RFR: JDK-8301392: Port fdlibm log1p to Java [v3]

Joe Darcy darcy at openjdk.org
Wed Feb 1 19:01:04 UTC 2023


On Wed, 1 Feb 2023 07:16:25 GMT, Joe Darcy <darcy at openjdk.org> wrote:

>> Another day, another PR to port FDLBIM to Java, this time for the log1p method.
>> 
>> Other than using the two-argument form of the __HI method in Java transliteration version rather than C macro, there are no appreciable differences between the original C source in 
>> 
>> src/java.base/share/native/libfdlibm/s_log1p.c
>> 
>> and the transliteration for testing purposes in
>> 
>> test/jdk/java/lang/StrictMath/FdlibmTranslit.java
>> 
>> The more idiomatic port in
>> 
>> src/java.base/share/classes/java/lang/FdLibm.java
>> 
>> has had a series of transformation applied layering on the transliteration. The intermediate commits show the progress.
>> 
>> The regression tests include probing around input values the implementation uses to decided which branch to take.
>
> Joe Darcy has updated the pull request incrementally with two additional commits since the last revision:
> 
>  - Appease jcheck.
>  - Fix typo; improve tests.

PS To provide more context for the review, below are the "diff -w" output for the original C fdlibm with the transliteration port and the transliteration port with the more idiomatic port.


$ diff -w Log1p.c Log1p.translit.java 
1c1,2
< /* double log1p(double x)
---
>     /**
>      * Returns the natural logarithm of the sum of the argument and 1.
64a66,77
>     static class Log1p {
>         private static double ln2_hi  =  6.93147180369123816490e-01;  /* 3fe62e42 fee00000 */
>         private static double ln2_lo  =  1.90821492927058770002e-10;  /* 3dea39ef 35793c76 */
>         private static double two54   =  1.80143985094819840000e+16;  /* 43500000 00000000 */
>         private static double Lp1 = 6.666666666666735130e-01;  /* 3FE55555 55555593 */
>         private static double Lp2 = 3.999999999940941908e-01;  /* 3FD99999 9997FA04 */
>         private static double Lp3 = 2.857142874366239149e-01;  /* 3FD24924 94229359 */
>         private static double Lp4 = 2.222219843214978396e-01;  /* 3FCC71C5 1D8E78AF */
>         private static double Lp5 = 1.818357216161805012e-01;  /* 3FC74664 96CB03DE */
>         private static double Lp6 = 1.531383769920937332e-01;  /* 3FC39A09 D078C69F */
>         private static double Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
>         private static double zero = 0.0;
66,92c79
< #include "fdlibm.h"
< 
< #ifdef __STDC__
< static const double
< #else
< static double
< #endif
< ln2_hi  =  6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
< ln2_lo  =  1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
< two54   =  1.80143985094819840000e+16,  /* 43500000 00000000 */
< Lp1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
< Lp2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
< Lp3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
< Lp4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
< Lp5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
< Lp6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
< Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
< 
< static double zero = 0.0;
< 
< #ifdef __STDC__
<         double log1p(double x)
< #else
<         double log1p(x)
<         double x;
< #endif
< {
---
>         public static double compute(double x) {
137c124
<                 __HI(u) = hu|0x3ff00000;        /* normalize u */
---
>                     u = __HI(u, hu|0x3ff00000);        /* normalize u */
140c127
<                 __HI(u) = hu|0x3fe00000;        /* normalize u/2 */
---
>                     u = __HI(u, hu|0x3fe00000);        /* normalize u/2 */
158a146
>     }


The constants are reformatted as expected and the __HI() C macro used on the left-hand side of an assignment is replaced by a Java method call.

And port-vs-port:


$ diff -w Log1p.translit.java Log1p.fdlibm.java 
67,77c67,75
<         private static double ln2_hi  =  6.93147180369123816490e-01;  /* 3fe62e42 fee00000 */
<         private static double ln2_lo  =  1.90821492927058770002e-10;  /* 3dea39ef 35793c76 */
<         private static double two54   =  1.80143985094819840000e+16;  /* 43500000 00000000 */
<         private static double Lp1 = 6.666666666666735130e-01;  /* 3FE55555 55555593 */
<         private static double Lp2 = 3.999999999940941908e-01;  /* 3FD99999 9997FA04 */
<         private static double Lp3 = 2.857142874366239149e-01;  /* 3FD24924 94229359 */
<         private static double Lp4 = 2.222219843214978396e-01;  /* 3FCC71C5 1D8E78AF */
<         private static double Lp5 = 1.818357216161805012e-01;  /* 3FC74664 96CB03DE */
<         private static double Lp6 = 1.531383769920937332e-01;  /* 3FC39A09 D078C69F */
<         private static double Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
<         private static double zero = 0.0;
---
>         private static final double ln2_hi = 0x1.62e42feep-1;       // 6.93147180369123816490e-01
>         private static final double ln2_lo = 0x1.a39ef35793c76p-33; // 1.90821492927058770002e-10
>         private static final double Lp1    = 0x1.5555555555593p-1;  // 6.666666666666735130e-01
>         private static final double Lp2    = 0x1.999999997fa04p-2;  // 3.999999999940941908e-01
>         private static final double Lp3    = 0x1.2492494229359p-2;  // 2.857142874366239149e-01
>         private static final double Lp4    = 0x1.c71c51d8e78afp-3;  // 2.222219843214978396e-01
>         private static final double Lp5    = 0x1.7466496cb03dep-3;  // 1.818357216161805012e-01
>         private static final double Lp6    = 0x1.39a09d078c69fp-3;  // 1.531383769920937332e-01
>         private static final double Lp7    = 0x1.2f112df3e5244p-3;  // 1.479819860511658591e-01
84c82
<             ax = hx&0x7fffffff;
---
>             ax = hx & 0x7fff_ffff;
87,94c85,88
<             if (hx < 0x3FDA827A) {                  /* x < 0.41422  */
<                 if(ax>=0x3ff00000) {                /* x <= -1.0 */
<                     /*
<                      * Added redundant test against hx to work around VC++
<                      * code generation problem.
<                      */
<                     if(x==-1.0 && (hx==0xbff00000)) /* log1p(-1)=-inf */
<                         return -two54/zero;
---
>             if (hx < 0x3FDA_827A) {                  /* x < 0.41422  */
>                 if (ax >= 0x3ff0_0000) {             /* x <= -1.0 */
>                     if (x == -1.0) /* log1p(-1)=-inf */
>                         return -INFINITY;
96c90
<                         return (x-x)/(x-x);           /* log1p(x<-1)=NaN */
---
>                         return Double.NaN;           /* log1p(x < -1) = NaN */
98,100c92,95
<                 if(ax<0x3e200000) {                 /* |x| < 2**-29 */
<                     if(two54+x>zero                 /* raise inexact */
<                        &&ax<0x3c900000)            /* |x| < 2**-54 */
---
> 
>                 if (ax < 0x3e20_0000) {                /* |x| < 2**-29 */
>                     if (TWO54 + x > 0.0                /* raise inexact */
>                        && ax < 0x3c90_0000)            /* |x| < 2**-54 */
105,106c100,105
<                 if(hx>0||hx<=((int)0xbfd2bec3)) {
<                     k=0;f=x;hu=1;}  /* -0.2929<x<0.41422 */
---
> 
>                 if (hx > 0 || hx <= 0xbfd2_bec3) { /* -0.2929 < x < 0.41422 */
>                     k=0;
>                     f=x;
>                     hu=1;
>                 }
108c107,111
<             if (hx >= 0x7ff00000) return x+x;
---
> 
>             if (hx >= 0x7ff0_0000) {
>                 return x+x;
>             }
> 
110c113
<                 if(hx<0x43400000) {
---
>                 if (hx < 0x4340_0000) {
122,124c125,127
<                 hu &= 0x000fffff;
<                 if(hu<0x6a09e) {
<                     u = __HI(u, hu|0x3ff00000);        /* normalize u */
---
>                 hu &= 0x000f_ffff;
>                 if (hu < 0x6_a09e) {
>                     u = __HI(u, hu | 0x3ff0_0000);       /* normalize u */
127,128c130,131
<                     u = __HI(u, hu|0x3fe00000);        /* normalize u/2 */
<                     hu = (0x00100000-hu)>>2;
---
>                     u = __HI(u, hu | 0x3fe0_0000);       /* normalize u/2 */
>                     hu = (0x0010_0000 - hu) >> 2;
131a135
> 
134,135c138,145
<                 if(f==zero) { if(k==0) return zero;
<                     else {c += k*ln2_lo; return k*ln2_hi+c;}}
---
>                 if (f == 0.0) {
>                     if (k == 0) {
>                         return 0.0;
>                     } else {
>                         c += k * ln2_lo;
>                         return k * ln2_hi + c;
>                     }
>                 }
137c147,149
<                 if(k==0) return f-R; else
---
>                 if (k == 0) {
>                     return f - R;
>                 } else {
139a152
>             }
143c156,158
<             if(k==0) return f-(hfsq-s*(hfsq+R)); else
---
>             if (k == 0) {
>                 return f-(hfsq-s*(hfsq+R));
>             } else {
144a160
>             }

-------------

PR: https://git.openjdk.org/jdk/pull/12301


More information about the core-libs-dev mailing list