RFR: 8375285: Port fdlibm asinh to Java
Anton Artemov
aartemov at openjdk.org
Mon Jan 26 11:54:33 UTC 2026
On Fri, 23 Jan 2026 02:36:15 GMT, Joe Darcy <darcy 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...
>
> src/java.base/share/classes/java/lang/FdLibm.java line 3543:
>
>> 3541: int hx,ix;
>> 3542: hx = __HI(x);
>> 3543: ix = hx&0x7fffffff;
>
> As part of making the code more idiomatic, I would include adding space characters around `&` and switching one-line `/* ... */` over to `//` comments where possible.
Addressed.
> src/java.base/share/classes/java/lang/Math.java line 2762:
>
>> 2760:
>> 2761: /**
>> 2762: * Returns the inverse hyperbolic sine of a {@code double} value.
>
> The method specification should provide some general statements in term of the accuracy of the method in terms of ulps.
>
> Explicitly specifying asinh(NaN) is NaN is probably worthwhile too.
Addressed in the latest commit.
> src/java.base/share/classes/java/lang/StrictMath.java line 2173:
>
>> 2171: }
>> 2172:
>> 2173: /**
>
> The list of "these methods must use FDLIBM algorithms..." up at the class-level specs of StrictMath should be updated to include asinh.
Addressed.
> test/jdk/java/lang/StrictMath/HyperbolicTests.java line 497:
>
>> 495: private static int testAsinh() {
>> 496: int failures = 0;
>> 497: double [][] testCases = {
>
> How were these values generated?
These results were generated by running a small C++ program linked to a IEEE-standard built fdlibm.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2727300965
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2727300757
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2727301096
PR Review Comment: https://git.openjdk.org/jdk/pull/29273#discussion_r2727301340
More information about the core-libs-dev
mailing list