Phil Steitz wrote:

--- Brent Worden <[EMAIL PROTECTED]> wrote:


I am also a little confused by J's analysis. Do we know
definitively that using
J2SE, there is precision loss in Math.pow(x,n) vs x*x*...*x (n
terms) for small
integer n?  If the answer is yes, we should establish the
guideline that for
integer n < 4, we use explicit products instead of Math.pow(-,n).

Phil


According to the J2SE javadoc, the math methods use fdlibm
(http://www.netlib.org/fdlibm/) for their implementations.  Here's the pow
implementation http://www.netlib.org/fdlibm/e_pow.c.  According to its
comments, its only perfectly accurate for the two integer argument case.
Otherwise it's "nearly rounded."




Thanks for doing the research, Brent. Based on this, I propose that we establish the guideline above -- i.e., avoid Math.pow(x,n) for (constant) integer n < 4 and floating point x. I will submit a patch to developer.xml including this.

Phil

Just to elaborate slightly,

its only perfectly accurate for the two integer argument case.
Otherwise it's "nearly rounded."

This does not mean that Math.pow is using Integer Arithmetic in accomplishing x^n. Java still does implicit casting to doubles prior to Math.pow, it has to as the only method signature for Math.pow is

public static native double pow(double a, double b);

this means it is doing double precision floating point arithmetic when calculating Math.pow( x, n). Because of this, for x values where x^n > Integer.MAX_VALUE, Math.pow does not overflow during the calculation. It is also the case that ((double)x) * x carries the same precision as Math.pow(x,n) upto 2^52 bits if significant digits (the mantissa of a double).

So in terms of computational efficiency, ((double)x)*x is perfectly accurate for results upto 2^52 or 4.5036E+15 significant digits. With this in mind,

(1) It is very important to also use ((double)x)*x instead of (double)(x*x), as the loss of precision starts to occur at far greater values than overflow occurs if one were doing integer arithmetic

(2) Its appropriate to also use ((double)x)*x in place of Math.pow(x,2) when x = values.length (0 <= x < Integer.MAX_VALUE), because both will begin loosing precision at about the same time and ((double)x)*x is a more efficient approach than Math.pow.

-Mark



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to