Conflict API definitions of Math.pow(x, 0.5) and Math.sqrt(x) for x={-0.0, Double.NEGATIVE_INFINITY}
Raffaello Giulietti
raffaello.giulietti at gmail.com
Mon Apr 12 10:40:02 UTC 2021
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 core-libs-dev
mailing list