
Boost : 
From: John Maddock (john_at_[hidden])
Date: 20080527 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 yetanother erroraction, "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 ''dividebyzero'' floatingpoint
exception
for y an odd integer < 0.
 pow(±0, y) returns +¥ and raises the ''dividebyzero'' floatingpoint
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'' floatingpoint
exception for
finite x < 0 and finite noninteger 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