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

Andrew Dinn adinn at redhat.com
Mon Apr 12 09:23:24 UTC 2021


On 12/04/2021 07:51, jiefu(傅杰) wrote:

> 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).

This is already a confused situation from the point of view of 
mathematics. Consider these two expressions:

Math.sqrt(-0.0) * Math.sqrt(-0.0)

Math.pow(-0.0, 0.5) * Math.pow(-0.0, 0.5)

It doesn't matter whether the functions sqrt and pow compute -0.0 or 0.0 
as the value here. Either result will fail to satisfy the equality

   f(x) * f(x) == x

The problem is that computation has already diverged from mathematical 
expectation by introducing the value -0.0. So, Java (and other 
languages) have to make up a rule here.

> 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?

It might well match expectations better if both functions were to 
generate the same value here. However, expectations have already been 
set by libc:

$ cat > sqrt.c << END
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv) {
     printf("sqrt(-0.F) = %f\n", sqrt(-0.F));
     printf("pow(-0.F, 0.5) = %f\n", pow(-0.F, 0.5));
}
END
$ make sqrt
cc     sqrt.c   -o sqrt
$ ./sqrt
sqrt(-0.F) = -0.000000
pow(-0.F, 0.5) = 0.000000

I have no idea why these specific results were made up for C but Java 
really ought to follow them.

regards,


Andrew Dinn
-----------
Red Hat Distinguished Engineer
Red Hat UK Ltd
Registered in England and Wales under Company Registration No. 03798903
Directors: Michael Cunningham, Michael ("Mike") O'Neill



More information about the hotspot-compiler-dev mailing list