Conflict API definitions of Math.pow(x, 0.5) and Math.sqrt(x) for x={-0.0, Double.NEGATIVE_INFINITY}(Internet mail)

Raffaello Giulietti raffaello.giulietti at gmail.com
Sat May 15 22:55:40 UTC 2021


Hi Jie,

I don't think that changing the spec of Math.pow() to be misaligned with 
IEEE 754 would be a wise option. IEEE is much more pervasive than Java. 
There are many aspects in IEEE that might be seen as questionable, but 
at least it is a widely adopted standard.

AFAIU, the only reason you would like to "optimize" the special case of 
y = 0.5 in pow(x, y) to return sqrt(x) is for performance, more accuracy 
and some kind of consistency.

But then, why not a special case for y = 0.25 as sqrt(sqrt(x))?
And what about y = 0.75? Should this be translated to sqrt(sqrt(pow(x, 3)))?
What about y = 1.0 / 3.0? Should this become cbrt(x)?
And why not consider y = 2.0 / 3.0 in a special rule: cbrt(x * x)?

You see, the special cases can quickly become unmanageable. Also, 
special rules would produce results which are "discontinuous" with 
nearby exponents, like y = 0.5000000000000001.

That's probably why IEEE doesn't propose translation rules for finite 
numerical exponents that are not integers, except when x is a special value.


Greetings
Raffaello



On 2021-04-12 13:44, jiefu(傅杰) wrote:
> Hi Andrew H, Andrew D, and Raffaello,
> 
> Thank you all for your kind reply and helpful comments.
> 
> Now I got where the rules come from.
> But I don't think the IEEE standars are reasonable to specify conflits rules.
> Maybe, these computations should be open to be implementation dependent.
> 
> (If it's possible) I really hope the special cases of Math.pow(x, 0.5) can be aligned with Math.sqrt(x) in Java.
> We already allow some plausible behaviors to be different with the IEEE recommendations for some special cases, right?
> And in that case, we can replace pow(x, 0.5) with sqrt(x) safely.
> 
> Thanks.
> Best regards,
> Jie
> 
> 
> On 2021/4/12, 6:40 PM, "Raffaello Giulietti" <raffaello.giulietti at gmail.com> wrote:
> 
>      Hi Jie,
>      
>      the behavior you report is the one specified by the standard IEEE 754.
>      Java follows this standard as closely as it can.
>      
>      The standard says that
>      * squareRoot(-0) = -0
>      * squareRoot(-∞) = NaN
>      
>      Also, the standard has a long lists of special cases for pow(x, y),
>      among them:
>      * pow(±0, y) is +0 for finite y > 0 and not an odd integer
>      * pow(-∞, y) is +∞ for finite y > 0 and not an odd integer
>      
>      Thus, the conflicts you observe originate in following the standard, not
>      by special Java rules.
>      
>      Unfortunately, the IEEE standard does not explain the reasons for the
>      special rules. Some are obvious, some are not.
>      
>      
>      HTH
>      Raffaello
>      
>      
>      > Hi all,
>      >
>      > I found Math.pow(x, 0.5) and Math.sqrt(x) would compute different values as the following:
>      > ```
>      > Math.pow(-0.0, 0.5) = 0.0
>      > Math.sqrt(-0.0) = -0.0
>      >
>      > Math.pow(Double.NEGATIVE_INFINITY, 0.5) = Infinity
>      > Math.sqrt(Double.NEGATIVE_INFINITY) = NaN
>      > ```
>      >
>      > The reason is that both of pow and sqrt have special rules for these computations.
>      > For example, this rule [1] specifies Math.pow(-0.0, 0.5) must be 0.0.
>      > And this one [2] specifies Math.sqrt(-0.0) must be -0.0.
>      > And we do have rules for Math.pow(Double.NEGATIVE_INFINITY, 0.5) = Infinity and Math.sqrt(Double.NEGATIVE_INFINITY) = NaN too.
>      >
>      > I think most people will be confused by these rules because from the view of mathematics, Math.pow(x, 0.5) should be equal to Math.sqrt(x).
>      >
>      > So why Java creates conflict special rules for them?
>      > Is it possible to let Math.pow(-0.0, 0.5) = -0.0 and Math.pow(Double.NEGATIVE_INFINITY, 0.5) = NaN also be allowed?
>      >
>      > I came across this problem when I was trying to optimize pow(x, 0.5) with sqrt(x).
>      > If pow(x, 0.5)'s two special rules can be aligned with sqrt(x), then pow(x, 0.5)'s performance can be improved by 7x~14x [3].
>      >
>      > Thanks.
>      > Best regards,
>      > Jie
>      
>      
> 



More information about the compiler-dev mailing list