
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.