Skip to content

Commit abd315c

Browse files
committed
use libm functions for acosh and asinh
1 parent 562dee4 commit abd315c

7 files changed

Lines changed: 37 additions & 24 deletions

File tree

library/coretests/tests/num/floats.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,8 @@ float_test! {
16991699
assert!(nan.asinh().is_nan());
17001700
assert!(flt(-0.0).asinh().is_sign_negative());
17011701

1702+
assert_ne!(Float::MAX.asinh(), inf);
1703+
17021704
// issue 63271
17031705
assert_approx_eq!(flt(2.0).asinh(), 1.443635475178810342493276740273105, Float::ASINH_APPROX);
17041706
assert_approx_eq!(flt(-2.0).asinh(), -1.443635475178810342493276740273105, Float::ASINH_APPROX);
@@ -1732,6 +1734,7 @@ float_test! {
17321734
assert!(nan.acosh().is_nan());
17331735
assert_approx_eq!(flt(2.0).acosh(), 1.31695789692481670862504634730796844, Float::ACOSH_APPROX);
17341736
assert_approx_eq!(flt(3.0).acosh(), 1.76274717403908605046521864995958461, Float::ACOSH_APPROX);
1737+
assert_ne!(Float::MAX.acosh(), inf);
17351738

17361739
#[allow(overflowing_literals)]
17371740
if Float::MAX > flt(66000.0) {

library/std/src/num/f128.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,10 @@ impl f128 {
868868
#[must_use = "method returns a new number and does not mutate the original value"]
869869
pub fn asinh(self) -> f128 {
870870
let ax = self.abs();
871+
if ax >= (1u128 << f128::MANTISSA_DIGITS / 2) as f128 {
872+
return (ax.ln() + consts::LN_2).copysign(self);
873+
}
874+
871875
let ix = 1.0 / ax;
872876
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
873877
}
@@ -902,6 +906,8 @@ impl f128 {
902906
pub fn acosh(self) -> f128 {
903907
if self < 1.0 {
904908
Self::NAN
909+
} else if self >= (1u128 << f128::MANTISSA_DIGITS / 2) as f128 {
910+
self.ln() + consts::LN_2
905911
} else {
906912
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
907913
}

library/std/src/num/f16.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -832,9 +832,7 @@ impl f16 {
832832
#[unstable(feature = "f16", issue = "116909")]
833833
#[must_use = "method returns a new number and does not mutate the original value"]
834834
pub fn asinh(self) -> f16 {
835-
let ax = self.abs();
836-
let ix = 1.0 / ax;
837-
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
835+
cmath::asinhf(self as f32) as f16
838836
}
839837

840838
/// Inverse hyperbolic cosine function.
@@ -865,11 +863,7 @@ impl f16 {
865863
#[unstable(feature = "f16", issue = "116909")]
866864
#[must_use = "method returns a new number and does not mutate the original value"]
867865
pub fn acosh(self) -> f16 {
868-
if self < 1.0 {
869-
Self::NAN
870-
} else {
871-
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
872-
}
866+
cmath::acoshf(self as f32) as f16
873867
}
874868

875869
/// Inverse hyperbolic tangent function.

library/std/src/num/f32.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,9 +1091,7 @@ impl f32 {
10911091
#[stable(feature = "rust1", since = "1.0.0")]
10921092
#[inline]
10931093
pub fn asinh(self) -> f32 {
1094-
let ax = self.abs();
1095-
let ix = 1.0 / ax;
1096-
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1094+
cmath::asinhf(self)
10971095
}
10981096

10991097
/// Inverse hyperbolic cosine function.
@@ -1119,11 +1117,7 @@ impl f32 {
11191117
#[stable(feature = "rust1", since = "1.0.0")]
11201118
#[inline]
11211119
pub fn acosh(self) -> f32 {
1122-
if self < 1.0 {
1123-
Self::NAN
1124-
} else {
1125-
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1126-
}
1120+
cmath::acoshf(self)
11271121
}
11281122

11291123
/// Inverse hyperbolic tangent function.

library/std/src/num/f64.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,9 +1091,7 @@ impl f64 {
10911091
#[stable(feature = "rust1", since = "1.0.0")]
10921092
#[inline]
10931093
pub fn asinh(self) -> f64 {
1094-
let ax = self.abs();
1095-
let ix = 1.0 / ax;
1096-
(ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1094+
cmath::asinh(self)
10971095
}
10981096

10991097
/// Inverse hyperbolic cosine function.
@@ -1119,11 +1117,7 @@ impl f64 {
11191117
#[stable(feature = "rust1", since = "1.0.0")]
11201118
#[inline]
11211119
pub fn acosh(self) -> f64 {
1122-
if self < 1.0 {
1123-
Self::NAN
1124-
} else {
1125-
(self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1126-
}
1120+
cmath::acosh(self)
11271121
}
11281122

11291123
/// Inverse hyperbolic tangent function.

library/std/src/sys/cmath.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
// or by `compiler-builtins` on unsupported platforms.
55
unsafe extern "C" {
66
pub safe fn acos(n: f64) -> f64;
7+
pub safe fn acosh(n: f64) -> f64;
78
pub safe fn asin(n: f64) -> f64;
9+
pub safe fn asinh(n: f64) -> f64;
810
pub safe fn atan(n: f64) -> f64;
911
pub safe fn atan2(a: f64, b: f64) -> f64;
1012
pub safe fn cosh(n: f64) -> f64;
@@ -57,6 +59,16 @@ cfg_select! {
5759
f64::acos(n as f64) as f32
5860
}
5961

62+
#[inline]
63+
pub fn acoshf(n: f32) -> f32 {
64+
f64::acosh(n as f64) as f32
65+
}
66+
67+
#[inline]
68+
pub fn asinhf(n: f32) -> f32 {
69+
f64::asinh(n as f64) as f32
70+
}
71+
6072
#[inline]
6173
pub fn asinf(n: f32) -> f32 {
6274
f64::asin(n as f64) as f32
@@ -95,7 +107,9 @@ cfg_select! {
95107
_ => {
96108
unsafe extern "C" {
97109
pub safe fn acosf(n: f32) -> f32;
110+
pub safe fn acoshf(n: f32) -> f32;
98111
pub safe fn asinf(n: f32) -> f32;
112+
pub safe fn asinhf(n: f32) -> f32;
99113
pub safe fn atan2f(a: f32, b: f32) -> f32;
100114
pub safe fn atanf(n: f32) -> f32;
101115
pub safe fn coshf(n: f32) -> f32;

src/tools/miri/src/shims/math.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3030
| "acosf"
3131
| "asinf"
3232
| "atanf"
33+
| "acoshf"
34+
| "asinhf"
3335
| "log1pf"
3436
| "expm1f"
3537
| "tgammaf"
@@ -52,6 +54,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
5254
"acosf" => f_host.acos(),
5355
"asinf" => f_host.asin(),
5456
"atanf" => f_host.atan(),
57+
"acoshf" => f_host.acosh(),
58+
"asinhf" => f_host.asinh(),
5559
"log1pf" => f_host.ln_1p(),
5660
"expm1f" => f_host.exp_m1(),
5761
"tgammaf" => f_host.gamma(),
@@ -113,6 +117,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
113117
| "acos"
114118
| "asin"
115119
| "atan"
120+
| "acosh"
121+
| "asinh"
116122
| "log1p"
117123
| "expm1"
118124
| "tgamma"
@@ -135,6 +141,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
135141
"acos" => f_host.acos(),
136142
"asin" => f_host.asin(),
137143
"atan" => f_host.atan(),
144+
"acosh" => f_host.acosh(),
145+
"asinh" => f_host.asinh(),
138146
"log1p" => f_host.ln_1p(),
139147
"expm1" => f_host.exp_m1(),
140148
"tgamma" => f_host.gamma(),

0 commit comments

Comments
 (0)