Boost logo

Boost :

From: John Maddock (john_at_[hidden])
Date: 2008-05-27 04:44:49


Bruno Lalande wrote:
> As I said, what I'd like is to have a default behavior that returns 1.
> I thought I could use the already existing ignore_error policy but I
> realize its behavior is imposed by the framework. For domain_error,
> which is the policy that best fits the 0^0 case IMO, ignore_error
> returns quiet_NaN which is not what I want. I can't use a user_error
> either since it would force me to predefine the user_domain_error
> function, thus stealing this point of customization to the user. So
> I'm realizing I'll have to adapt the framework (that's probably what
> you meant the other day by "adding new policies", I didn't notice at
> that moment).
>
> I don't know Boost.Math policies very much but my understanding is
> that we don't need a new policy but just a new action type, that I
> could use to return 1. I see 2 possibilities: creating a brand new
> action type, or allowing the existing "ignore_error" action to take in
> its constructor the value that we want it to return in place of
> quiet_NaN.
>
> Or maybe you prefer to simply return quiet_NaN instead of 1? Note that
> it's not the behavior of the C pow function so it could be misleading
> for users.
>
> What do you think about that?

I don't like the idea of returning a NaN: returning 1 seems to be the right
thing to do, and should probably be the default behaviour? The other
problem with reusing a domain_error is that the default behaviour is to
throw an exception, which may not be what users expect for this corner case?

So I guess I'm leaning towards yet-another error-action, "zero_power_error"
maybe?

On the other hand.... Googling around, it's clear that 0^0 has an
indeterminant value, and C99 says of the pow function:

"A domain error occurs if x is finite and negative and y is finite and not
an integer value. A domain error may occur if x is zero and y is less than
or equal to zero."

However in the appendix under recomended practice it lists lots of special
cases:

F.9.4.4 The pow functions
-pow(±0, y) returns ±¥ and raises the ''divide-by-zero'' floating-point
exception
for y an odd integer < 0.
- pow(±0, y) returns +¥ and raises the ''divide-by-zero'' floating-point
exception for y < 0 and not an odd integer.
- pow(±0, y) returns ±0 for y an odd integer > 0.
- pow(±0, y) returns +0 for y > 0 and not an odd integer.
- pow(-1, ±¥) returns 1.
- pow(+1, y) returns 1 for any y, even a NaN.
- pow(x, ±0) returns 1 for any x, even a NaN.
- pow(x, y) returns a NaN and raises the ''invalid'' floating-point
exception for
finite x < 0 and finite non-integer y.
- pow(x, -¥) returns +¥ for | x | < 1.
- pow(x, -¥) returns +0 for | x | > 1.
- pow(x, +¥) returns +0 for | x | < 1.
- pow(x, +¥) returns +¥ for | x | > 1.
- pow(-¥, y) returns -0 for y an odd integer < 0.
- pow(-¥, y) returns +0 for y < 0 and not an odd integer.
- pow(-¥, y) returns -¥ for y an odd integer > 0.
- pow(-¥, y) returns +¥ for y > 0 and not an odd integer.
- pow(+¥, y) returns +0 for y < 0.
- pow(+¥, y) returns +¥ for y > 0.

Sorry about the mangled text: those funny symbols are infinities!

The key bit here is:

"- pow(x, ±0) returns 1 for any x, even a NaN."

So the result should be 1!

Personally I can't help wondering if they just overlooked the 0^0 case :-(

Grrr, still not sure what to do here, how about:

* If the domain_error action is "ignore_error" then return 1, otherwise,
* Raise a domain_error as normal.

?

Not sure if this helps, John.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk