On Wed, 15 Feb 2023 22:44:40 GMT, Joe Darcy <da...@openjdk.org> wrote:
>> 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 with a new target base due to a merge > or a rebase. The pull request now contains 14 commits: > > - Merge branch 'master' into JDK-8301444 > - Refactor regression test. > - Small refactorings in Fdlibm.java > - Remove unnecessary semicolons. > - Add exhausting test coverage. > - Merge branch 'master' into JDK-8301444 > - Merge branch 'master' into JDK-8301444 > - Improve exp usage. > - Add additional note. > - Respond to review feedback. > - ... and 4 more: https://git.openjdk.org/jdk/compare/3ba15608...3c4e1812 Approved. ------------- Marked as reviewed by bpb (Reviewer). PR: https://git.openjdk.org/jdk/pull/12429