RFR: JDK-8302026: Port fdlibm inverse trig functions (asin, acos, atan) to Java
Joe Darcy
darcy at openjdk.org
Mon Feb 13 22:18:11 UTC 2023
On Mon, 13 Feb 2023 22:03:14 GMT, Joe Darcy <darcy at openjdk.org> wrote:
> Proceeding down the line of FDLIBM functions to be ported, next up are asin, acos, and atan.
>
> Diffs of the various versions will follow in a separate message.
>
> There were no unusual coding idioms encountered in porting these methods.
Original C vs transliteration port:
$ diff -w InverseTrig.c InverseTrig.translit.java
1c1,2
< /* __ieee754_asin(x)
---
> /** Returns the arcsine of x.
> *
30,38c31,32
<
<
< #include "fdlibm.h"
<
< #ifdef __STDC__
< static const double
< #else
< static double
< #endif
---
> static class Asin {
> private static final double
56,62c50
< #ifdef __STDC__
< double __ieee754_asin(double x)
< #else
< double __ieee754_asin(x)
< double x;
< #endif
< {
---
> static double compute(double x) {
83c71
< w = one-fabs(x);
---
> w = one-Math.abs(x);
87c75
< s = sqrt(t);
---
> s = Math.sqrt(t);
93c81,82
< __LO(w) = 0;
---
> // __LO(w) = 0;
> w = __LO(w, 0);
102c91,93
< /* __ieee754_acos(x)
---
> }
>
> /** Returns the arccosine of x.
125,132c116,117
<
< #include "fdlibm.h"
<
< #ifdef __STDC__
< static const double
< #else
< static double
< #endif
---
> static class Acos {
> private static final double
148,154c133
< #ifdef __STDC__
< double __ieee754_acos(double x)
< #else
< double __ieee754_acos(x)
< double x;
< #endif
< {
---
> static double compute(double x) {
177c156
< s = sqrt(z);
---
> s = Math.sqrt(z);
183c162
< s = sqrt(z);
---
> s = Math.sqrt(z);
185c164,165
< __LO(df) = 0;
---
> // __LO(df) = 0;
> df = __LO(df, 0);
194c174,176
< /* atan(x)
---
> }
>
> /* Returns the arctangent of x.
213,220c195,196
<
< #include "fdlibm.h"
<
< #ifdef __STDC__
< static const double atanhi[] = {
< #else
< static double atanhi[] = {
< #endif
---
> static class Atan {
> private static final double atanhi[] = {
227,231c203
< #ifdef __STDC__
< static const double atanlo[] = {
< #else
< static double atanlo[] = {
< #endif
---
> private static final double atanlo[] = {
238,242c210
< #ifdef __STDC__
< static const double aT[] = {
< #else
< static double aT[] = {
< #endif
---
> private static final double aT[] = {
256,260c224
< #ifdef __STDC__
< static const double
< #else
< static double
< #endif
---
> private static final double
264,270c228
< #ifdef __STDC__
< double atan(double x)
< #else
< double atan(x)
< double x;
< #endif
< {
---
> static double compute(double x) {
288c246
< x = fabs(x);
---
> x = Math.abs(x);
313a272
> }
Transliteration port vs more idiomatic port:
$ diff -w InverseTrig.translit.java InverseTrig.fdlibm.java
31a32,33
> private Asin() {throw new UnsupportedOperationException();}
>
33,48c35,48
< one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
< huge = 1.000e+300,
< pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
< pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
< pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
< /* coefficient for R(x^2) */
< pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
< pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
< pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
< pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
< pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
< pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
< qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
< qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
< qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
< qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
---
> pio2_hi = 0x1.921fb54442d18p0, // 1.57079632679489655800e+00
> pio2_lo = 0x1.1a62633145c07p-54, // 6.12323399573676603587e-17
> pio4_hi = 0x1.921fb54442d18p-1, // 7.85398163397448278999e-01
> // coefficient for R(x^2)
> pS0 = 0x1.5555555555555p-3, // 1.66666666666666657415e-01
> pS1 = -0x1.4d61203eb6f7dp-2, // -3.25565818622400915405e-01
> pS2 = 0x1.9c1550e884455p-3, // 2.01212532134862925881e-01
> pS3 = -0x1.48228b5688f3bp-5, // -4.00555345006794114027e-02
> pS4 = 0x1.9efe07501b288p-11, // 7.91534994289814532176e-04
> pS5 = 0x1.23de10dfdf709p-15, // 3.47933107596021167570e-05
> qS1 = -0x1.33a271c8a2d4bp1, // -2.40339491173441421878e+00
> qS2 = 0x1.02ae59c598ac8p1, // 2.02094576023350569471e+00
> qS3 = -0x1.6066c1b8d0159p-1, // -6.88283971605453293030e-01
> qS4 = 0x1.3b8c5b12e9282p-4; // 7.70381505559019352791e-02
54,57c54,57
< ix = hx&0x7fffffff;
< if(ix>= 0x3ff00000) { /* |x|>= 1 */
< if(((ix-0x3ff00000)|__LO(x))==0)
< /* asin(1)=+-pi/2 with inexact */
---
> ix = hx & 0x7fff_ffff;
> if (ix >= 0x3ff0_0000) { // |x| >= 1
> if(((ix - 0x3ff0_0000) | __LO(x)) == 0) {
> // asin(1) = +-pi/2 with inexact
59,63c59,66
< return (x-x)/(x-x); /* asin(|x|>1) is NaN */
< } else if (ix<0x3fe00000) { /* |x|<0.5 */
< if(ix<0x3e400000) { /* if |x| < 2**-27 */
< if(huge+x>one) return x;/* return x with inexact if x!=0*/
< } else
---
> }
> return (x - x)/(x - x); // asin(|x| > 1) is NaN
> } else if (ix < 0x3fe0_0000) { // |x| < 0.5
> if (ix < 0x3e40_0000) { // if |x| < 2**-27
> if (HUGE + x > 1.0) {// return x with inexact if x != 0
> return x;
> }
> } else {
64a68
> }
66c70
< q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
---
> q = 1.0 + t*(qS1 + t*(qS2 + t*(qS3 + t*qS4)));
70,71c74,75
< /* 1> |x|>= 0.5 */
< w = one-Math.abs(x);
---
> // 1 > |x| >= 0.5
> w = 1.0 - Math.abs(x);
74c78
< q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
---
> q = 1.0 + t*(qS1 + t*(qS2 + t*(qS3 + t*qS4)));
76c80
< if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
---
> if (ix >= 0x3FEF_3333) { // if |x| > 0.975
81d84
< // __LO(w) = 0;
89c92
< if(hx>0) return t; else return -t;
---
> return (hx > 0) ? t : -t;
116a120,121
> private Acos() {throw new UnsupportedOperationException();}
>
118,131c123,134
< one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
< pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
< pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
< pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
< pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
< pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
< pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
< pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
< pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
< pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
< qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
< qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
< qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
< qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
---
> pio2_hi = 0x1.921fb54442d18p0, // 1.57079632679489655800e+00
> pio2_lo = 0x1.1a62633145c07p-54, // 6.12323399573676603587e-17
> pS0 = 0x1.5555555555555p-3, // 1.66666666666666657415e-01
> pS1 = -0x1.4d61203eb6f7dp-2, // -3.25565818622400915405e-01
> pS2 = 0x1.9c1550e884455p-3, // 2.01212532134862925881e-01
> pS3 = -0x1.48228b5688f3bp-5, // -4.00555345006794114027e-02
> pS4 = 0x1.9efe07501b288p-11, // 7.91534994289814532176e-04
> pS5 = 0x1.23de10dfdf709p-15, // 3.47933107596021167570e-05
> qS1 = -0x1.33a271c8a2d4bp1, // -2.40339491173441421878e+00
> qS2 = 0x1.02ae59c598ac8p1, // 2.02094576023350569471e+00
> qS3 = -0x1.6066c1b8d0159p-1, // -6.88283971605453293030e-01
> qS4 = 0x1.3b8c5b12e9282p-4; // 7.70381505559019352791e-02
137,141c140,147
< ix = hx&0x7fffffff;
< if(ix>=0x3ff00000) { /* |x| >= 1 */
< if(((ix-0x3ff00000)|__LO(x))==0) { /* |x|==1 */
< if(hx>0) return 0.0; /* acos(1) = 0 */
< else return pi+2.0*pio2_lo; /* acos(-1)= pi */
---
> ix = hx & 0x7fff_ffff;
> if (ix >= 0x3ff0_0000) { // |x| >= 1
> if (((ix - 0x3ff0_0000) | __LO(x)) == 0) { // |x| == 1
> if (hx > 0) {// acos(1) = 0
> return 0.0;
> }else { // acos(-1)= pi
> return Math.PI + 2.0*pio2_lo;
> }
143c149,153
< return (x-x)/(x-x); /* acos(|x|>1) is NaN */
---
> return (x-x)/(x-x); // acos(|x| > 1) is NaN
> }
> if (ix < 0x3fe0_0000) { // |x| < 0.5
> if (ix <= 0x3c60_0000) { // if |x| < 2**-57
> return pio2_hi + pio2_lo;
145,146d154
< if(ix<0x3fe00000) { /* |x| < 0.5 */
< if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
149c157
< q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
---
> q = 1.0 + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4)));
152,153c160,161
< } else if (hx<0) { /* x < -0.5 */
< z = (one+x)*0.5;
---
> } else if (hx < 0) { // x < -0.5
> z = (1.0 + x)*0.5;
155c163
< q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
---
> q = 1.0 + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4)));
159,161c167,169
< return pi - 2.0*(s+w);
< } else { /* x > 0.5 */
< z = (one-x)*0.5;
---
> return Math.PI - 2.0*(s+w);
> } else { // x > 0.5
> z = (1.0 - x)*0.5;
164d171
< // __LO(df) = 0;
168c175
< q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
---
> q = 1.0 + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4)));
195a203,204
> private Atan() {throw new UnsupportedOperationException();}
>
197,200c206,209
< 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
< 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
< 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
< 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
---
> 0x1.dac670561bb4fp-2, // atan(0.5)hi 4.63647609000806093515e-01
> 0x1.921fb54442d18p-1, // atan(1.0)hi 7.85398163397448278999e-01
> 0x1.f730bd281f69bp-1, // atan(1.5)hi 9.82793723247329054082e-01
> 0x1.921fb54442d18p0, // atan(inf)hi 1.57079632679489655800e+00
204,207c213,216
< 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
< 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
< 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
< 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
---
> 0x1.a2b7f222f65e2p-56, // atan(0.5)lo 2.26987774529616870924e-17
> 0x1.1a62633145c07p-55, // atan(1.0)lo 3.06161699786838301793e-17
> 0x1.007887af0cbbdp-56, // atan(1.5)lo 1.39033110312309984516e-17
> 0x1.1a62633145c07p-54, // atan(inf)lo 6.12323399573676603587e-17
211,221c220,230
< 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
< -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
< 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
< -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
< 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
< -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
< 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
< -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
< 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
< -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
< 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
---
> 0x1.555555555550dp-2, // 3.33333333333329318027e-01
> -0x1.999999998ebc4p-3, // -1.99999999998764832476e-01
> 0x1.24924920083ffp-3, // 1.42857142725034663711e-01
> -0x1.c71c6fe231671p-4, // -1.11111104054623557880e-01
> 0x1.745cdc54c206ep-4, // 9.09088713343650656196e-02
> -0x1.3b0f2af749a6dp-4, // -7.69187620504482999495e-02
> 0x1.10d66a0d03d51p-4, // 6.66107313738753120669e-02
> -0x1.dde2d52defd9ap-5, // -5.83357013379057348645e-02
> 0x1.97b4b24760debp-5, // 4.97687799461593236017e-02
> -0x1.2b4442c6a6c2fp-5, // -3.65315727442169155270e-02
> 0x1.0ad3ae322da11p-6, // 1.62858201153657823623e-02
224,227d232
< private static final double
< one = 1.0,
< huge = 1.0e300;
<
233,242c238,253
< ix = hx&0x7fffffff;
< if(ix>=0x44100000) { /* if |x| >= 2^66 */
< if(ix>0x7ff00000||
< (ix==0x7ff00000&&(__LO(x)!=0)))
< return x+x; /* NaN */
< if(hx>0) return atanhi[3]+atanlo[3];
< else return -atanhi[3]-atanlo[3];
< } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
< if (ix < 0x3e200000) { /* |x| < 2^-29 */
< if(huge+x>one) return x; /* raise inexact */
---
> ix = hx & 0x7fff_ffff;
> if (ix >= 0x4410_0000) { // if |x| >= 2^66
> if (ix > 0x7ff0_0000 ||
> (ix == 0x7ff0_0000 && (__LO(x) != 0))) {
> return x+x; // NaN
> }
> if (hx > 0) {
> return atanhi[3] + atanlo[3];
> } else {
> return -atanhi[3] - atanlo[3];
> }
> } if (ix < 0x3fdc_0000) { // |x| < 0.4375
> if (ix < 0x3e20_0000) { // |x| < 2^-29
> if (HUGE + x > 1.0) { // raise inexact
> return x;
> }
247,251c258,264
< if (ix < 0x3ff30000) { /* |x| < 1.1875 */
< if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
< id = 0; x = (2.0*x-one)/(2.0+x);
< } else { /* 11/16<=|x|< 19/16 */
< id = 1; x = (x-one)/(x+one);
---
> if (ix < 0x3ff3_0000) { // |x| < 1.1875
> if (ix < 0x3fe60000) { // 7/16 <= |x| < 11/16
> id = 0;
> x = (2.0*x - 1.0)/(2.0 + x);
> } else { // 11/16 <= |x| < 19/16
> id = 1;
> x = (x - 1.0)/(x + 1.0);
254,257c267,273
< if (ix < 0x40038000) { /* |x| < 2.4375 */
< id = 2; x = (x-1.5)/(one+1.5*x);
< } else { /* 2.4375 <= |x| < 2^66 */
< id = 3; x = -1.0/x;
---
> if (ix < 0x4003_8000) { // |x| < 2.4375
> id = 2;
> x = (x - 1.5)/(1.0 + 1.5*x);
> } else { // 2.4375 <= |x| < 2^66
> id = 3;
> x = -1.0/x;
> }
259,260c275,276
< }}
< /* end of argument reduction */
---
> }
> // end of argument reduction
263c279
< /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
---
> // break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly
266,267c282,284
< if (id<0) return x - x*(s1+s2);
< else {
---
> if (id < 0) {
> return x - x*(s1 + s2);
> } else {
-------------
PR: https://git.openjdk.org/jdk/pull/12545
More information about the core-libs-dev
mailing list