> Initial pass of porting FDLIBM sinh/cosh/tanh to Java. I do intend to 
> refactor the regression tests a bit to reduce duplication, but the actual 
> ports should be ready for review.
> 
> Diff'ing the ports as before, original vs transliteration port:
> 
> 
> $ diff -w Hyperbolic.c Hyperbolic.translit.java
> 1c1
> < /* __ieee754_sinh(x)
> ---
>>     /**
> 17a18,19
>>     static class Sinh {
>>         private static final double one = 1.0, shuge = 1.0e307;
> 19,33c21
> < #include "fdlibm.h"
> < 
> < #ifdef __STDC__
> < static const double one = 1.0, shuge = 1.0e307;
> < #else
> < static double one = 1.0, shuge = 1.0e307;
> < #endif
> < 
> < #ifdef __STDC__
> <         double __ieee754_sinh(double x)
> < #else
> <         double __ieee754_sinh(x)
> <         double x;
> < #endif
> < {
> ---
>>         private static double compute(double x) {
> 36c24
> <         unsigned lx;
> ---
>>             /* unsigned */ int lx;
> 51c39
> <             t = expm1(fabs(x));
> ---
>>                 t = FdlibmTranslit.expm1(Math.abs(x));
> 57c45
> <         if (ix < 0x40862E42)  return h*__ieee754_exp(fabs(x));
> ---
>>             if (ix < 0x40862E42)  return h*StrictMath.exp(Math.abs(x)); // 
>> TODO switch to translit
> 60,62c48,52
> <         lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
> <         if (ix<0x408633CE || 
> ((ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d))) {
> <             w = __ieee754_exp(0.5*fabs(x));
> ---
>>             // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
>>             // lx =  (((*(unsigned*)&one)>>29)) + (unsigned*)&x ;
>>             lx = __LO(x);
>>             if (ix<0x408633CE || 
>> ((ix==0x408633ce)&&(Long.compareUnsigned(lx, 0x8fb9f87d) <= 0 ))) {
>>                 w = StrictMath.exp(0.5*Math.abs(x)); // TODO switch to 
>> translit
> 70c60,62
> < /* __ieee754_cosh(x)
> ---
>>     }
>> 
>>     /**
> 90,105c82,84
> < 
> < #include "fdlibm.h"
> < 
> < #ifdef __STDC__
> < static const double one = 1.0, half=0.5, huge = 1.0e300;
> < #else
> < static double one = 1.0, half=0.5, huge = 1.0e300;
> < #endif
> < 
> < #ifdef __STDC__
> <         double __ieee754_cosh(double x)
> < #else
> <         double __ieee754_cosh(x)
> <         double x;
> < #endif
> < {
> ---
>>     static class Cosh {
>>         private static final double one = 1.0, half=0.5, huge = 1.0e300;
>>         private static double compute(double x) {
> 108c87
> <         unsigned lx;
> ---
>>             /*unsigned*/ int lx;
> 119c98
> <             t = expm1(fabs(x));
> ---
>>                 t = expm1(Math.abs(x));
> 127c106
> <                 t = __ieee754_exp(fabs(x));
> ---
>>                 t = StrictMath.exp(Math.abs(x)); // TODO switch to translit
> 132c111
> <         if (ix < 0x40862E42)  return half*__ieee754_exp(fabs(x));
> ---
>>             if (ix < 0x40862E42)  return half*StrictMath.exp(Math.abs(x)); 
>> // TODO switch to translit
> 135c114
> <         lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
> ---
>>             lx = __LO(x);
> 137,138c116,117
> <               ((ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d))) {
> <             w = __ieee754_exp(half*fabs(x));
> ---
>>                 ((ix==0x408633ce)&&(Integer.compareUnsigned(lx, 0x8fb9f87d) 
>> <= 0))) {
>>                 w = StrictMath.exp(half*Math.abs(x)); // TODO switch to 
>> translit
> 146c125,127
> < /* Tanh(x)
> ---
>>     }
>> 
>>     /**
> 169,184c150,152
> < 
> < #include "fdlibm.h"
> < 
> < #ifdef __STDC__
> < static const double one=1.0, two=2.0, tiny = 1.0e-300;
> < #else
> < static double one=1.0, two=2.0, tiny = 1.0e-300;
> < #endif
> < 
> < #ifdef __STDC__
> <         double tanh(double x)
> < #else
> <         double tanh(x)
> <         double x;
> < #endif
> < {
> ---
>>     static class Tanh {
>>         private static final double one=1.0, two=2.0, tiny = 1.0e-300;
>>         static double compute(double x) {
> 203c171
> <                 t = expm1(two*fabs(x));
> ---
>>                     t = expm1(two*Math.abs(x));
> 206c174
> <                 t = expm1(-two*fabs(x));
> ---
>>                     t = expm1(-two*Math.abs(x));
> 214a183
>>     }
> 
> 
> Note that the original has a in-line version of the "__LO" macro rather than 
> using the macro.
> 
> 
> And transliteration vs more idiomatic:
> 
> 
> $ diff -w Hyperbolic.translit.java Hyperbolic.fdlibm.java 
> 21c21
> <         private static double compute(double x) {
> ---
>>          static double compute(double x) {
> 26c26
> <             /* High word of |x|. */
> ---
>>             // High word of |x|
> 28c28
> <             ix = jx&0x7fffffff;
> ---
>>             ix = jx & 0x7fff_ffff;
> 30,31c30,33
> <             /* x is INF or NaN */
> <             if(ix>=0x7ff00000) return x+x;
> ---
>>             // x is INF or NaN
>>             if ( ix >= 0x7ff0_0000) {
>>                 return x + x;
>>             }
> 34,40c36,48
> <             if (jx<0) h = -h;
> <             /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
> <             if (ix < 0x40360000) {          /* |x|<22 */
> <                 if (ix<0x3e300000)          /* |x|<2**-28 */
> <                     if(shuge+x>one) return x;/* sinh(tiny) = tiny with 
> inexact */
> <                 t = FdlibmTranslit.expm1(Math.abs(x));
> <                 if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
> ---
>>             if ( jx < 0) {
>>                 h = -h;
>>             }
>>             // |x| in [0,22], return sign(x)*0.5*(E+E/(E+1)))
>>             if (ix < 0x4036_0000) {          // |x| < 22
>>                 if (ix < 0x3e30_0000)        // |x| < 2**-28
>>                     if (shuge + x > one) {   // sinh(tiny) = tiny with 
>> inexact
>>                         return x;
>>                     }
>>                 t = StrictMath.expm1(Math.abs(x));
>>                 if (ix < 0x3ff0_0000) {
>>                     return h*(2.0 * t - t*t/(t + one));
>>                 }
> 44,45c52,55
> <             /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
> <             if (ix < 0x40862E42)  return h*StrictMath.exp(Math.abs(x)); // 
> TODO switch to translit
> ---
>>             // |x| in [22, log(maxdouble)] return 0.5*exp(|x|)
>>             if (ix < 0x4086_2E42) {
>>                 return h*StrictMath.exp(Math.abs(x));
>>             }
> 47,49c57
> <             /* |x| in [log(maxdouble), overflowthresold] */
> <             // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
> <             // lx =  (((*(unsigned*)&one)>>29)) + (unsigned*)&x ;
> ---
>>             // |x| in [log(maxdouble), overflowthresold]
> 51,52c59,62
> <             if (ix<0x408633CE || 
> ((ix==0x408633ce)&&(Long.compareUnsigned(lx, 0x8fb9f87d) <= 0 ))) {
> <                 w = StrictMath.exp(0.5*Math.abs(x)); // TODO switch to 
> translit
> ---
>>             if (ix < 0x4086_33CE ||
>>                 ((ix == 0x4086_33ce) &&
>>                  (Long.compareUnsigned(lx, 0x8fb9_f87d) <= 0 ))) {
>>                 w = StrictMath.exp(0.5 * Math.abs(x));
> 57c67
> <             /* |x| > overflowthresold, sinh(x) overflow */
> ---
>>             // |x| > overflowthresold, sinh(x) overflow
> 84c94
> <         private static double compute(double x) {
> ---
>>         static double compute(double x) {
> 89c99
> <             /* High word of |x|. */
> ---
>>             // High word of |x|
> 91c101
> <             ix &= 0x7fffffff;
> ---
>>             ix &= 0x7fff_ffff;
> 93,94c103,106
> <             /* x is INF or NaN */
> <             if(ix>=0x7ff00000) return x*x;
> ---
>>             // x is INF or NaN
>>             if (ix >= 0x7ff_00000) {
>>                 return x*x;
>>             }
> 96,98c108,110
> <             /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
> <             if(ix<0x3fd62e43) {
> <                 t = expm1(Math.abs(x));
> ---
>>             // |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|))
>>             if (ix < 0x3fd6_2e43) {
>>                 t = StrictMath.expm1(Math.abs(x));
> 100c112,114
> <                 if (ix<0x3c800000) return w;        /* cosh(tiny) = 1 */
> ---
>>                 if (ix < 0x3c80_0000) { // cosh(tiny) = 1
>>                     return w;
>>                 }
> 104,106c118,120
> <             /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
> <             if (ix < 0x40360000) {
> <                 t = StrictMath.exp(Math.abs(x)); // TODO switch to translit
> ---
>>             // |x| in [0.5*ln2, 22], return (exp(|x|) + 1/exp(|x|)/2
>>             if (ix < 0x4036_0000) {
>>                 t = StrictMath.exp(Math.abs(x));
> 110,111c124,127
> <             /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
> <             if (ix < 0x40862E42)  return half*StrictMath.exp(Math.abs(x)); 
> // TODO switch to translit
> ---
>>             // |x| in [22, log(maxdouble)] return half*exp(|x|)
>>             if (ix < 0x4086_2E42) {
>>                 return half*StrictMath.exp(Math.abs(x));
>>             }
> 113c129
> <             /* |x| in [log(maxdouble), overflowthresold] */
> ---
>>             // |x| in [log(maxdouble), overflowthresold]
> 115,117c131,134
> <             if (ix<0x408633CE ||
> <                 ((ix==0x408633ce)&&(Integer.compareUnsigned(lx, 0x8fb9f87d) 
> <= 0))) {
> <                 w = StrictMath.exp(half*Math.abs(x)); // TODO switch to 
> translit
> ---
>>             if (ix<0x4086_33CE ||
>>                 ((ix == 0x4086_33ce) &&
>>                  (Integer.compareUnsigned(lx, 0x8fb9_f87d) <= 0))) {
>>                 w = StrictMath.exp(half*Math.abs(x));
> 122c139
> <             /* |x| > overflowthresold, cosh(x) overflow */
> ---
>>             // |x| > overflowthresold, cosh(x) overflow
> 126d142
> < 
> 156c172
> <             /* High word of |x|. */
> ---
>>             // High word of |x|.
> 158c174
> <             ix = jx&0x7fffffff;
> ---
>>             ix = jx & 0x7fff_ffff;
> 160,163c176,182
> <             /* x is INF or NaN */
> <             if(ix>=0x7ff00000) {
> <                 if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
> <                 else       return one/x-one;    /* tanh(NaN) = NaN */
> ---
>>             // x is INF or NaN
>>             if (ix >= 0x7ff0_0000) {
>>                 if (jx >= 0) {  // tanh(+-inf)=+-1
>>                     return one/x + one;
>>                 } else {        // tanh(NaN) = NaN
>>                     return one/x - one;
>>                 }
> 166,171c185,190
> <             /* |x| < 22 */
> <             if (ix < 0x40360000) {          /* |x|<22 */
> <                 if (ix<0x3c800000)          /* |x|<2**-55 */
> <                     return x*(one+x);       /* tanh(small) = small */
> <                 if (ix>=0x3ff00000) {       /* |x|>=1  */
> <                     t = expm1(two*Math.abs(x));
> ---
>>             // |x| < 22
>>             if (ix < 0x4036_0000) {          // |x| < 22
>>                 if (ix<0x3c80_0000)          // |x| < 2**-55
>>                     return x*(one + x);      // tanh(small) = small
>>                 if (ix>=0x3ff0_0000) {       // |x| >= 1
>>                     t = StrictMath.expm1(two*Math.abs(x));
> 174c193
> <                     t = expm1(-two*Math.abs(x));
> ---
>>                     t = StrictMath.expm1(-two*Math.abs(x));
> 177,179c196,197
> <                 /* |x| > 22, return +-1 */
> <             } else {
> <                 z = one - tiny;             /* raised inexact flag */
> ---
>>             } else { // |x| > 22, return +-1
>>                 z = one - tiny;             // raised inexact flag

Joe Darcy has updated the pull request incrementally with one additional commit 
since the last revision:

  Improve exp usage.

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

Changes:
  - all: https://git.openjdk.org/jdk/pull/12429/files
  - new: https://git.openjdk.org/jdk/pull/12429/files/45d4247f..19fe9857

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=12429&range=05
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12429&range=04-05

  Stats: 23 lines in 3 files changed: 6 ins; 4 del; 13 mod
  Patch: https://git.openjdk.org/jdk/pull/12429.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/12429/head:pull/12429

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

Reply via email to