Skip to content

Commit 52b85a0

Browse files
chore: refactor atanh implementation
1 parent 04f0f1e commit 52b85a0

File tree

2 files changed

+39
-23
lines changed
  • lib/node_modules/@stdlib/math/base/special/atanh

2 files changed

+39
-23
lines changed

lib/node_modules/@stdlib/math/base/special/atanh/lib/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*
1919
* ## Notice
2020
*
21-
* The following copyright, license, and long comment were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/e_atanh.c?view=markup}. The implementation follows the original, but has been modified for JavaScript.
21+
* The following copyright, license, and long comment were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/12.2.0/lib/msun/src/e_atanh.c?view=markup}. The implementation follows the original, but has been modified for JavaScript.
2222
*
2323
* ```text
2424
* Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.

lib/node_modules/@stdlib/math/base/special/atanh/src/main.c

+38-22
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,27 @@
3333
#include "stdlib/math/base/special/atanh.h"
3434
#include "stdlib/math/base/assert/is_nan.h"
3535
#include "stdlib/math/base/special/log1p.h"
36+
#include "stdlib/constants/float64/high_word_abs_mask.h"
37+
#include "stdlib/number/float64/base/set_high_word.h"
38+
#include "stdlib/number/float64/base/to_words.h"
3639
#include "stdlib/constants/float64/pinf.h"
3740
#include "stdlib/constants/float64/ninf.h"
3841
#include <stdint.h>
3942

40-
static const double NEAR_ZERO = 1.0 / (1 << 28); // 2**-28
43+
static const double one = 1.0;
44+
45+
static const double zero = 0.0;
46+
47+
static const double huge = 1e300;
48+
49+
// 0x3ff00000 = 1072693248 => 0 01111111111 00000000000000000000 => biased exponent: 1023 = 0+1023 => 2^0 = 1
50+
static const int32_t HIGH_BIASED_EXP_0 = 0x3ff00000;
51+
52+
// 0x3e300000 = 1040187392 => 0 01111100011 00000000000000000000 => biased exponent: 100 = -23+127
53+
static const int32_t HIGH_BIASED_EXP_NEG_7 = 0x3e300000;
54+
55+
// 0x3fe00000 = 1071644672 => 0 01111111110 00000000000000000000 => biased exponent: 1022 = -1+1023 => 2^-1
56+
static const int32_t HIGH_BIASED_EXP_NEG_1 = 0x3fe00000;
4157

4258
/**
4359
* Computes the hyperbolic arctangent of a double-precision floating-point number.
@@ -79,34 +95,34 @@ static const double NEAR_ZERO = 1.0 / (1 << 28); // 2**-28
7995
* // returns ~1.472
8096
*/
8197
double stdlib_base_atanh( const double x ) {
82-
int32_t sgn;
83-
double ax;
98+
u_int32_t lx;
99+
double hx;
100+
double ahx;
84101
double t;
85102
if ( stdlib_base_is_nan( x ) || x < -1.0 || x > 1.0 ) {
86103
return 0.0 / 0.0; // NaN
87104
}
88-
if ( x == 1.0 ) {
89-
return STDLIB_CONSTANT_FLOAT64_PINF;
105+
// Split `x` into high and low words:
106+
stdlib_base_float64_to_words( x, &hx, &lx );
107+
108+
ahx = hx & STDLIB_CONSTANT_FLOAT64_HIGH_WORD_ABS_MASK;
109+
110+
if( ( ahx | ( ( lx | (-lx) )>>31 ))> HIGH_BIASED_EXP_0 ) {
111+
return ( x - x ) / ( x - x ); // |x|>1
90112
}
91-
if ( x == -1.0 ) {
92-
return STDLIB_CONSTANT_FLOAT64_NINF;
113+
if( ahx == HIGH_BIASED_EXP_0 ) {
114+
return x / zero;
93115
}
94-
if ( x < 0.0 ) {
95-
sgn = 1;
96-
ax = -x;
97-
} else {
98-
sgn = 0;
99-
ax = x;
116+
if( ahx < HIGH_BIASED_EXP_NEG_7 && ( huge+x ) > zero) {
117+
return x; // x<2**-28
100118
}
101-
// Case: |x| < 2**-28
102-
if ( ax < NEAR_ZERO ) {
103-
return ( sgn == 1 ) ? -ax : ax;
104-
}
105-
if ( ax < 0.5 ) {
106-
t = ax + ax;
107-
t = 0.5 * stdlib_base_log1p( t + ( t * ax / ( 1 - ax ) ) );
119+
stdlib_base_float64_set_high_word( x, &ahx );
120+
if( ahx < HIGH_BIASED_EXP_NEG_1 ) {
121+
t = x + x;
122+
t = 0.5 * stdlib_base_log1p( t + ( t * x / ( one - x ) ) );
123+
108124
} else {
109-
t = 0.5 * stdlib_base_log1p( ( ax + ax ) / ( 1 - ax ) );
125+
t = 0.5 * stdlib_base_log1p( ( x + x ) / ( one - x ) );
110126
}
111-
return ( sgn == 1 ) ? -t : t;
127+
return ( hx >= 0 ) ? -t : t;
112128
}

0 commit comments

Comments
 (0)