JDK-4358794 : Math package: implement pow10 (power of 10) with optimization for integer powers
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2000-08-02
  • Updated: 2003-09-30
  • Resolved: 2003-09-30
Related Reports
Relates :  

Name: stC104175			Date: 08/02/2000

java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

RFE #4074599 is about "Math.log10(double)" (base 10 logarithm). Evaluation
said "While trivial to compute, the log10 function is sufficiently common and
useful that we should eventually provide it". I think that a "Math.pow10
(double)" method may be a useful complement, especially if it is optimized for
integers power. Currently, one can compute

Math.pow(10, x);

But this method has rounding error for some integers values of 'x'. The test
case below illustrate it:

class Test
	public static void main(String[] args)
		int count=0;
		for (int e=-308; e<=308; e++)
			final double n1=StrictMath.pow(10, e);
			final double n2=Double.parseDouble("1E"+e);
			System.out.println(e+"\t "+n2+"\t "+n1);
			if (n1!=n2) count++;
		System.out.println(count+" differences found");

In 64 cases, the number computed by "pow(10, e)" is not the closest IEEE
floating point representation. Actually, "parseDouble("1E"+e)" give as close or
closer values than "Math.pow(10, e)" for all 'e'. The difference is very small.
Such a small difference may be insignificant in most case, but power of 10 may
be a special case since it is used for scaling human-readable axis, scaling SI
units (centimeters, millimeters, picometers, yoctometers (1E-24 m), etc...) and
others works related to human-readable numbers.

In summary, I'm proposing a "Math.pow10(double)" method with special
optimization (if necessary) for integer power.

(Review ID: 107862) 

WORK AROUND Name: stC104175 Date: 08/02/2000 Math.pow(10, e) If 'e' is an integer value and if precision is more important than performance, then parseDouble("1E"+e) give better results. ======================================================================

EVALUATION A pow10 method should be unnecessary. The specification for pow calls for it to have 1 ulp accuracy, which the FDLIBM code used by StrictMath.pow does. This does not guarantee that conversion from string and the results of pow should be the same since conversion from string must meet the tighter accuracy bound of 1/2 ulp (i.e. string -> double must be correctly rounded). The observed differences are between adjacent floating-point numbers, which would be allowed by the specifications for pow and string -> double conversion. However, after some further checking, the results of calls to StrictMath.pow seem to differ from a presumed C implementation of FDLIBM (from the Sun C compiler) in almost exactly the same cases as StrictMath.pow differs from string -> double conversion. Therefore, there appears to be some bugs in the current implementation of StrictMath.pow vis a vis the requirement to use FDLIBM. See comments sections for list of "failing" exponents. ###@###.### 2002-02-04 After further investigation, the C implemenation referred to above is *not* using fdlibm's version of pow. Will try try to build C version of fdlibm to clarify if the observed behavior is accurate vis a vis the StrictMath.pow spec. ###@###.### 2002-02-08 Current behavior seems correct according to the spec; i.e. not a bug. Will consider the request for pow10 in Tiger as part of 4633024. ###@###.### 2002-04-10 Pow10 was not included as part of the Tiger math library work. I do not believe pow10 has sufficient marginal utility to exist as a separate method. I believe making a more robust/accurate pow method would be a more fruitful effort. ###@###.### 2003-09-30