RFR: 8375285: Port fdlibm asinh to Java

Andrey Turbanov aturbanov at openjdk.org
Mon Jan 26 20:39:22 UTC 2026


On Fri, 16 Jan 2026 09:22:52 GMT, Anton Artemov <aartemov at openjdk.org> wrote:

> Hi, please consider the following changes:
> 
> This is a port of FDLIBM asinh method.
> 
> Original C vs transliteration port:
> 
> 
> $ diff -w fdlib_asinh.c Asinh.translit.java
> 1c1,3
> < /* asinh(x)
> ---
>> /**
>> * Return the Inverse Hyperbolic Sine of x
>> *
> 2a5
>> *
> 10a14,17
>> private static final class Asinh {
>>       private static final double one = 1.0;
>>       private static final double ln2 = 6.93147180559945286227e-01;
>>       private static final double huge = 1.0e300;
> 12,29c19
> < #include "fdlibm.h"
> <
> < #ifdef __STDC__
> < static const double
> < #else
> < static double
> < #endif
> < one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
> < ln2 =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
> < huge=  1.00000000000000000000e+300;
> <
> < #ifdef __STDC__
> <       double asinh(double x)
> < #else
> <       double asinh(x)
> <       double x;
> < #endif
> < {
> ---
>>       static double compute(double x) {
> 39c29
> <           w = __ieee754_log(fabs(x))+ln2;
> ---
>>                       w = log(Math.abs(x))+ln2;
> 41,42c31,32
> <           t = fabs(x);
> <           w = __ieee754_log(2.0*t+one/(sqrt(x*x+one)+t));
> ---
>>                       t = Math.abs(x);
>>                       w = log(2.0*t+one/(sqrt(x*x+one)+t));
> 45c35
> <           w =log1p(fabs(x)+t/(one+sqrt(one+t)));
> ---
>>                       w =log1p(Math.abs(x)+t/(one+sqrt(one+t)));
> 47a38
>>       }
> 
> Transliteration port vs more idiomatic port:
> 
> 
> $ diff -w Asinh.translit.java Asinh.fdlibm.java
> 6,9c6,12
> < *  Based on
> < *    asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
> < *   we have
> < *   asinh(x) := x  if  1+x*x=1,
> ---
>>  *
>>  *      asinh(x) is defined so that asinh(sinh(alpha)) = alpha -INF < alpha < < INF
>>  *      and sinh(asinh(x)) = x, -INF < x  < INF.
>>  *      It can be written as asinh(x) = ln(x + sqrt(x^2 + 1)), -INF < x  < INF.
>>  *      1. Replace x by |x| as the function is odd.
>>  *      2.
>>  *          asinh(x) := x, if 1+x^2 = 1,
> 12a16,22
>>  *
>>  *
>>  *
>>  * Special cases:
>>  *      only asinh(0)=0 is exact for finite x.
>>  *      asinh(NaN) is NaN
>>  *      asinh(INF) is INF
> 14,15c24
> < private static final class Asinh {
> <       private static final double one = 1.0;
> ---
>> static final class Asinh {
> 24c33,35
> <               if(ix>=0x7ff00000) return x+x;  /* x is inf or NaN */
> ---
>>               if(ix >= 0x7ff00000) {
>>                       return x + x;                       /* x is inf or NaN */
>>               }
> 26c37,39
> <                       if(huge+x>one) return x;    /* return x inexact except 0...

src/java.base/share/classes/java/lang/FdLibm.java line 3544:

> 3542:             hx = __HI(x);
> 3543:             ix = hx & 0x7fffffff;
> 3544:             if(ix >= 0x7ff00000) {

Suggestion:

            if (ix >= 0x7ff00000) {

src/java.base/share/classes/java/lang/FdLibm.java line 3548:

> 3546:             }
> 3547:             if(ix < 0x3e300000) {                   // |x| < 2**-28
> 3548:                 if(huge + x > 1.0) {

Suggestion:

            if (ix < 0x3e300000) {                   // |x| < 2**-28
                if (huge + x > 1.0) {

src/java.base/share/classes/java/lang/FdLibm.java line 3552:

> 3550:                 }
> 3551:             }
> 3552:             if(ix > 0x41b00000) {                   // |x| > 2**28

Suggestion:

            if (ix > 0x41b00000) {                   // |x| > 2**28

test/jdk/java/lang/Math/HyperbolicTests.java line 1535:

> 1533: 
> 1534: 
> 1535:         for(int i = 0; i < testCases.length; i++) {

Suggestion:

        for (int i = 0; i < testCases.length; i++) {

test/jdk/java/lang/Math/HyperbolicTests.java line 1544:

> 1542: 
> 1543: 
> 1544:         for(double nan : Tests.NaNs) {

Suggestion:

        for (double nan : Tests.NaNs) {

test/jdk/java/lang/Math/HyperbolicTests.java line 1559:

> 1557: 
> 1558: 
> 1559:         for(int i = 0; i < specialTestCases.length; i++) {

Suggestion:

        for (int i = 0; i < specialTestCases.length; i++) {

test/jdk/java/lang/Math/HyperbolicTests.java line 1572:

> 1570:         // double significand.
> 1571: 
> 1572:         for(int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) {

Suggestion:

        for (int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) {

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

PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729161991
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729162357
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729162705
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729154923
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729155502
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729156624
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2729157284


More information about the core-libs-dev mailing list