United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4347132 : Want Math.cbrt() function for cube root

Details
Type:
Enhancement
Submit Date:
2000-06-21
Status:
Resolved
Updated Date:
2003-05-16
Project Name:
JDK
Resolved Date:
2003-05-16
Component:
core-libs
OS:
linux,generic
Sub-Component:
java.lang
CPU:
x86,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.3.0,1.4.0
Fixed Versions:
5.0 (tiger)

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

Description

Name: sl110371			Date: 06/21/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)


It would be nice to have a Math.cbrt() function (cube root of a real number),
for those of us involved in numerical/graphics programming.

Looking at the JDK source code (publically available), there is a cbrt() native
method defined in the library but it is unused.  The Math class would need to
be altered to call this method, similar to the way it invokes sqrt().

Math.pow(x, 1/3.0) can be used to compute a cube root, but is much less
efficient than a true cube root function.  Also, special care must be taken for
negative values of x.  (See work-around).
(Review ID: 105412) 
======================================================================

Name: rmT116609			Date: 02/19/2002


DESCRIPTION OF THE PROBLEM :

It would be nice to have a cubic root method in java.lang.Math, for example :

public static double cbrt (double x)

This mathematical function is defined for all real values regardless of their sign, but computing it with Math.pow cannot be done directly for non positive values. We have to end up with this kind of code :

if (x >= 0)
  c = Math.pow (x, 1.0 / 3.0);
else
  c = -Math.pow (-x, 1.0 / 3.0);

(Review ID: 139858)
======================================================================

                                    

Comments
EVALUATION

This is a useful method that should be included in Java's math library.  A true cube root method will return somewhat different answers than pow(x, 1.0/3.0) since 1/3 is not exactly representable as a floating-point value.

joe.darcy@eng 2001-06-25
                                     
2001-06-25
SUGGESTED FIX

Directory make/java/java

sccs sccsdiff -r1.51 -r1.52 mapfile-vers 

------- mapfile-vers -------
141a142
>               Java_java_lang_StrictMath_log10;
145a147
>               Java_java_lang_StrictMath_cbrt;

Directory src/share/native/java/lang/fdlibm/include

sccs sccsdiff -r1.8 -r1.9 jfdlibm.h          

------- jfdlibm.h -------
26a27
> #define log10   jlog10
29a31
> #define cbrt    jcbrt


Directory src/share/native/java/lang

sccs sccsdiff -r1.51 -r1.52 StrictMath.c 

------- StrictMath.c -------
61a62,67
> Java_java_lang_StrictMath_log10(JNIEnv *env, jclass unused, jdouble d)
> {
>     return (jdouble) jlog10((double)d);
> }
> 
> JNIEXPORT jdouble JNICALL
66a73,78
> JNIEXPORT jdouble JNICALL
> Java_java_lang_StrictMath_cbrt(JNIEnv *env, jclass unused, jdouble d)
> {
>     return (jdouble) jcbrt((double)d);
> }
> 

Directory src/share/classes/java/lang
------- Math.java -------
4c4
<  * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
---
>  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
16,17c16,17
<  * <p>
<  * Unlike some of the numeric methods of class
---
>  * 
>  * <p>Unlike some of the numeric methods of class
23,24c23,24
<  * <p>
<  * By default many of the <code>Math</code> methods simply call
---
>  * 
>  * <p>By default many of the <code>Math</code> methods simply call
32,33c32,33
<  * <p>
<  * The quality of implementation specifications concern two
---
>  * 
>  * <p>The quality of implementation specifications concern two
93,95c93,95
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
108,110c108,110
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
125,127c125,127
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
143,145c143,145
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
159,161c159,161
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results 
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
176,178c176,178
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
225,227c225,227
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
246,248c246,248
<      * <p>
<      * A result must be within 1 ulp of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
250c250
<      * @param   a   a number greater than <code>0.0</code>.
---
>      * @param   a   a value
258a259,283
>      * Returns the base 10 logarithm of a <code>double</code> value.
>      * Special cases:
>      *
>      * <ul><li>If the argument is NaN or less than zero, then the result 
>      * is NaN.
>      * <li>If the argument is positive infinity, then the result is 
>      * positive infinity.
>      * <li>If the argument is positive zero or negative zero, then the 
>      * result is negative infinity.
>      * <li> If the argument is equal to 10<sup><i>n</i></sup> for
>      * integer <i>n</i>, then the result is <i>n</i>.
>      * </ul>
>      * 
>      * <p>A result must be within 1 ulp of the correctly rounded
>      * result.  Results must be semi-monotonic.
>      *
>      * @param   a   a value
>      * @return  the base 10 logarithm of  <code>a</code>.
>      * @since 1.5
>      */
>     public static double log10(double a) {
>       return StrictMath.log10(a); // default impl. delegates to StrictMath
>     }
> 
>     /**
283a309
> 
284a311,340
>      * Returns the cube root of a <code>double</code> value.  For
>      * positive finite <code>x</code>, <code>cbrt(-x) ==
>      * -cbrt(x)</code>; that is, the cube root of a negative value is
>      * the negative of the cube root of that value's magnitude.
>      * 
>      * Special cases: 
>      *
>      * <ul>
>      * 
>      * <li>If the argument is NaN, then the result is NaN.
>      *
>      * <li>If the argument is infinite, then the result is an infinity
>      * with the same sign as the argument.
>      *
>      * <li>If the argument is zero, then the result is a zero with the
>      * same sign as the argument.
>      * 
>      * </ul>
>      *
>      * A result must be within 1 ulp of the correctly rounded result.
>      * 
>      * @param   a   a value.
>      * @return  the cube root of <code>a</code>.
>      * @since 1.5
>      */
>     public static double cbrt(double a) {
>       return StrictMath.cbrt(a);
>     }
> 
>     /**
411,413c467,469
<      * <p>
<      * A result must be within 2 ulps of the correctly rounded result.  Results
<      * must be semi-monotonic.
---
>      * 
>      * <p>A result must be within 2 ulps of the correctly rounded
>      * result.  Results must be semi-monotonic.
618,628c674,684
<      * <p>
<      * When this method is first called, it creates a single new 
<      * pseudorandom-number generator, exactly as if by the expression 
<      * <blockquote><pre>new java.util.Random</pre></blockquote>
<      * This new pseudorandom-number generator is used thereafter for all 
<      * calls to this method and is used nowhere else. 
<      * <p>
<      * This method is properly synchronized to allow correct use by more 
<      * than one thread. However, if many threads need to generate 
<      * pseudorandom numbers at a great rate, it may reduce contention for 
<      * each thread to have its own pseudorandom-number generator.
---
>      * 
>      * <p>When this method is first called, it creates a single new
>      * pseudorandom-number generator, exactly as if by the expression
>      * <blockquote><pre>new java.util.Random</pre></blockquote> This
>      * new pseudorandom-number generator is used thereafter for all
>      * calls to this method and is used nowhere else.
>      * 
>      * <p>This method is properly synchronized to allow correct use by
>      * more than one thread. However, if many threads need to generate
>      * pseudorandom numbers at a great rate, it may reduce contention
>      * for each thread to have its own pseudorandom-number generator.
643,647c699,703
<      * <p>
<      * Note that if the argument is equal to the value of 
<      * <code>Integer.MIN_VALUE</code>, the most negative representable 
<      * <code>int</code> value, the result is that same value, which is 
<      * negative. 
---
>      * 
>      * <p>Note that if the argument is equal to the value of
>      * <code>Integer.MIN_VALUE</code>, the most negative representable
>      * <code>int</code> value, the result is that same value, which is
>      * negative.
661,665c717,721
<      * <p>
<      * Note that if the argument is equal to the value of 
<      * <code>Long.MIN_VALUE</code>, the most negative representable 
<      * <code>long</code> value, the result is that same value, which is 
<      * negative. 
---
>      * 
>      * <p>Note that if the argument is equal to the value of
>      * <code>Long.MIN_VALUE</code>, the most negative representable
>      * <code>long</code> value, the result is that same value, which
>      * is negative.
867a924,1018
>     /**
>      * Returns the size of an ulp of the argument.  An ulp of a
>      * <code>double</code> value is the positive distance between this
>      * floating-point value and the <code>double</code> value next
>      * larger in magnitude.  Note that for non-NaN <i>x</i>,
>      * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
>      * 
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive or negative infinity, then the
>      * result is positive infinity.
>      * <li> If the argument is positive or negative zero, then the result is
>      * <code>Double.MIN_VALUE</code>.
>      * <li> If the argument is &plusmn;<code>Double.MAX_VALUE</code>, then
>      * the result is equal to 2<sup>971</sup>.
>      * </ul>
>      *
>      * @param d the floating-point value whose ulp is to be returned
>      * @return the size of an ulp of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static double ulp(double d) {
>       return sun.misc.FpUtils.ulp(d);
>     }
> 
>     /**
>      * Returns the size of an ulp of the argument.  An ulp of a
>      * <code>float</code> value is the positive distance between this
>      * floating-point value and the <code>float</code> value next
>      * larger in magnitude.  Note that for non-NaN <i>x</i>,
>      * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
>      * 
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive or negative infinity, then the
>      * result is positive infinity.
>      * <li> If the argument is positive or negative zero, then the result is
>      * <code>Float.MIN_VALUE</code>.
>      * <li> If the argument is &plusmn;<code>Float.MAX_VALUE</code>, then
>      * the result is equal to 2<sup>104</sup>.
>      * </ul>
>      *
>      * @param f the floating-point value whose ulp is to be returned
>      * @return the size of an ulp of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static float ulp(float f) {
>       return sun.misc.FpUtils.ulp(f);
>     }
> 
>     /**
>      * Returns the signum function of the argument; zero if the argument
>      * is zero, 1.0 if the argument is greater than zero, -1.0 if the
>      * argument is less than zero.
>      *
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive zero or negative zero, then the
>      *      result is the same as the argument.
>      * </ul>
>      *
>      * @param d the floating-point value whose signum is to be returned
>      * @return the signum function of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static double signum(double d) {
>       return sun.misc.FpUtils.signum(d);
>     }
> 
>     /**
>      * Returns the signum function of the argument; zero if the argument
>      * is zero, 1.0f if the argument is greater than zero, -1.0f if the
>      * argument is less than zero.
>      *
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive zero or negative zero, then the
>      *      result is the same as the argument.
>      * </ul>
>      *
>      * @param f the floating-point value whose signum is to be returned
>      * @return the signum function of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static float signum(float f) {
>       return sun.misc.FpUtils.signum(f);
>     }

------- StrictMath.java -------
4c4
<  * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
---
>  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
16,18c16,18
<  * <p>
<  * To help ensure portability of Java programs, the definitions of 
<  * many of the numeric functions in this package require that they 
---
>  * 
>  * <p>To help ensure portability of Java programs, the definitions of 
>  * some of the numeric functions in this package require that they 
26,27c26,27
<  * <p>
<  * The network library may be found on the World Wide Web at:
---
>  * 
>  * <p>The network library may be found on the World Wide Web at:
31,37c31,42
<  * <p>
<  * The Java math library is defined with respect to the version of 
<  * <code>fdlibm</code> dated January 4, 1995. Where 
<  * <code>fdlibm</code> provides more than one definition for a 
<  * function (such as <code>acos</code>), use the "IEEE 754 core 
<  * function" version (residing in a file whose name begins with 
<  * the letter <code>e</code>). 
---
>  * 
>  * <p>The Java math library is defined with respect to the version of
>  * <code>fdlibm</code> dated January 4, 1995. Where
>  * <code>fdlibm</code> provides more than one definition for a
>  * function (such as <code>acos</code>), use the "IEEE 754 core
>  * function" version (residing in a file whose name begins with the
>  * letter <code>e</code>).  The methods which require
>  * <code>fdlibm</code> semantics are <code>sin</code>,
>  * <code>cos</code>, <code>tan</code>, <code>asin</code>,
>  * <code>acos</code>, <code>atan</code>, <code>exp</code>,
>  * <code>log</code>, <code>log10</code>, <code>cbrt</code>,
>  * <code>atan2</code>, and <code>pow</code>.
44c49
< public final strictfp class StrictMath {
---
> public final class StrictMath {
187c192
<      * @param   a   a number greater than <code>0.0</code>.
---
>      * @param   a   a value
192a198
> 
193a200,219
>      * Returns the base 10 logarithm of a <code>double</code> value.
>      * Special cases:
>      *
>      * <ul><li>If the argument is NaN or less than zero, then the result 
>      * is NaN.
>      * <li>If the argument is positive infinity, then the result is 
>      * positive infinity.
>      * <li>If the argument is positive zero or negative zero, then the 
>      * result is negative infinity.
>      * <li> If the argument is equal to 10<sup><i>n</i></sup> for
>      * integer <i>n</i>, then the result is <i>n</i>.
>      * </ul>
>      *
>      * @param   a   a value
>      * @return  the base 10 logarithm of  <code>a</code>.
>      * @since 1.5
>      */
>     public static native double log10(double a);
> 
>     /**
207d232
<      * <!--@return  the value of &radic;&nbsp;<code>a</code>.-->
212a238,262
>      * Returns the cube root of a <code>double</code> value.  For
>      * positive finite <code>x</code>, <code>cbrt(-x) ==
>      * -cbrt(x)</code>; that is, the cube root of a negative value is
>      * the ne
                                     
2004-06-11
SUGGESTED FIX

gative of the cube root of that value's magnitude.
>      * Special cases: 
>      *
>      * <ul>
>      *
>      * <li>If the argument is NaN, then the result is NaN.
>      *
>      * <li>If the argument is infinite, then the result is an infinity
>      * with the same sign as the argument.
>      *
>      * <li>If the argument is zero, then the result is a zero with the
>      * same sign as the argument.
>      * 
>      * </ul>
>      *
>      * @param   a   a value.
>      * @return  the cube root of <code>a</code>.
>      * @since 1.5
>      */
>     public static native double cbrt(double a);
> 
>     /**
529,539c579,589
<      * <p>
<      * When this method is first called, it creates a single new 
<      * pseudorandom-number generator, exactly as if by the expression 
<      * <blockquote><pre>new java.util.Random</pre></blockquote>
<      * This new pseudorandom-number generator is used thereafter for all 
<      * calls to this method and is used nowhere else. 
<      * <p>
<      * This method is properly synchronized to allow correct use by more 
<      * than one thread. However, if many threads need to generate 
<      * pseudorandom numbers at a great rate, it may reduce contention for 
<      * each thread to have its own pseudorandom number generator.
---
>      * 
>      * <p>When this method is first called, it creates a single new
>      * pseudorandom-number generator, exactly as if by the expression
>      * <blockquote><pre>new java.util.Random</pre></blockquote> This
>      * new pseudorandom-number generator is used thereafter for all
>      * calls to this method and is used nowhere else.
>      * 
>      * <p>This method is properly synchronized to allow correct use by
>      * more than one thread. However, if many threads need to generate
>      * pseudorandom numbers at a great rate, it may reduce contention
>      * for each thread to have its own pseudorandom number generator.
554,558c604,608
<      * <p>
<      * Note that if the argument is equal to the value of 
<      * <code>Integer.MIN_VALUE</code>, the most negative representable 
<      * <code>int</code> value, the result is that same value, which is 
<      * negative. 
---
>      * 
>      * <p>Note that if the argument is equal to the value of
>      * <code>Integer.MIN_VALUE</code>, the most negative representable
>      * <code>int</code> value, the result is that same value, which is
>      * negative.
572,576c622,626
<      * <p>
<      * Note that if the argument is equal to the value of 
<      * <code>Long.MIN_VALUE</code>, the most negative representable 
<      * <code>long</code> value, the result is that same value, which is 
<      * negative. 
---
>      * 
>      * <p>Note that if the argument is equal to the value of
>      * <code>Long.MIN_VALUE</code>, the most negative representable
>      * <code>long</code> value, the result is that same value, which
>      * is negative.
778a829,923
>     /**
>      * Returns the size of an ulp of the argument.  An ulp of a
>      * <code>double</code> value is the positive distance between this
>      * floating-point value and the <code>double</code> value next
>      * larger in magnitude.  Note that for non-NaN <i>x</i>,
>      * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
>      * 
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive or negative infinity, then the
>      * result is positive infinity.
>      * <li> If the argument is positive or negative zero, then the result is
>      * <code>Double.MIN_VALUE</code>.
>      * <li> If the argument is &plusmn;<code>Double.MAX_VALUE</code>, then
>      * the result is equal to 2<sup>971</sup>.
>      * </ul>
>      *
>      * @param d the floating-point value whose ulp is to be returned
>      * @return the size of an ulp of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static double ulp(double d) {
>       return sun.misc.FpUtils.ulp(d);
>     }
> 
>     /**
>      * Returns the size of an ulp of the argument.  An ulp of a
>      * <code>float</code> value is the positive distance between this
>      * floating-point value and the <code>float</code> value next
>      * larger in magnitude.  Note that for non-NaN <i>x</i>,
>      * <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
>      * 
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive or negative infinity, then the
>      * result is positive infinity.
>      * <li> If the argument is positive or negative zero, then the result is
>      * <code>Float.MIN_VALUE</code>.
>      * <li> If the argument is &plusmn;<code>Float.MAX_VALUE</code>, then
>      * the result is equal to 2<sup>104</sup>.
>      * </ul>
>      *
>      * @param f the floating-point value whose ulp is to be returned
>      * @return the size of an ulp of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static float ulp(float f) {
>       return sun.misc.FpUtils.ulp(f);
>     }
> 
>     /**
>      * Returns the signum function of the argument; zero if the argument
>      * is zero, 1.0 if the argument is greater than zero, -1.0 if the
>      * argument is less than zero.
>      *
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive zero or negative zero, then the
>      *      result is the same as the argument.
>      * </ul>
>      *
>      * @param d the floating-point value whose signum is to be returned
>      * @return the signum function of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static double signum(double d) {
>       return sun.misc.FpUtils.signum(d);
>     }
> 
>     /**
>      * Returns the signum function of the argument; zero if the argument
>      * is zero, 1.0f if the argument is greater than zero, -1.0f if the
>      * argument is less than zero.
>      *
>      * <p>Special Cases:
>      * <ul>
>      * <li> If the argument is NaN, then the result is NaN.
>      * <li> If the argument is positive zero or negative zero, then the
>      *      result is the same as the argument.
>      * </ul>
>      *
>      * @param f the floating-point value whose signum is to be returned
>      * @return the signum function of the argument
>      * @author Joseph D. Darcy
>      * @since 1.5
>      */
>     public static float signum(float f) {
>       return sun.misc.FpUtils.signum(f);
>     }
                                     
2004-06-11
WORK AROUND



Name: sl110371			Date: 06/21/2000


public double cbrt(double x) {

// cube root function

// Cube root of negative number is negative
// Take cbrt of magnitude then negate result
// Need to do this as pow returns complex (NaN) for negative x, which
//	is a technically correct answer, but not the one we want

     if(x < 0)
	return -Math.pow(-x, ONETHIRD);

     return Math.pow(x, ONETHIRD);
}
======================================================================
                                     
2004-06-11
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger

FIXED IN:
tiger

INTEGRATED IN:
tiger
tiger-b07


                                     
2004-06-14



Hardware and Software, Engineered to Work Together