authorgravatar for 57540512+rdimas-ut@users.noreply.github.comRuben Dimas <57540512+rdimas-ut@users.noreply.github.com> 2023-09-12 02:19:21-04:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2023-09-12 22:22:07+12:00
loga8a4f1755e440bc6ff8c27fad0da91ed83f20841
tree5a8d07ab1b5a3038b7707860b374430f15455a12
parent7827265ea81c72e44da9b7d9b91e68d557e4db6d

std.math.asinh: fixed -0.0 evaluating to 0.0


1 files changed, 10 insertions(+), 19 deletions(-)

lib/std/math/asinh.zig+10-19
......@@ -28,30 +28,25 @@ pub fn asinh(x: anytype) @TypeOf(x) {
2828fn asinh32(x: f32) f32 {
2929 const u = @as(u32, @bitCast(x));
3030 const i = u & 0x7FFFFFFF;
31 const s = i >> 31;
31 const s = u >> 31;
3232
3333 var rx = @as(f32, @bitCast(i)); // |x|
3434
35 // TODO: Shouldn't need this explicit check.
36 if (math.isNegativeInf(x)) {
37 return x;
38 }
39
4035 // |x| >= 0x1p12 or inf or nan
4136 if (i >= 0x3F800000 + (12 << 23)) {
4237 rx = @log(rx) + 0.69314718055994530941723212145817656;
4338 }
4439 // |x| >= 2
4540 else if (i >= 0x3F800000 + (1 << 23)) {
46 rx = @log(2 * x + 1 / (@sqrt(x * x + 1) + x));
41 rx = @log(2 * rx + 1 / (@sqrt(rx * rx + 1) + rx));
4742 }
4843 // |x| >= 0x1p-12, up to 1.6ulp error
4944 else if (i >= 0x3F800000 - (12 << 23)) {
50 rx = math.log1p(x + x * x / (@sqrt(x * x + 1) + 1));
45 rx = math.log1p(rx + rx * rx / (@sqrt(rx * rx + 1) + 1));
5146 }
5247 // |x| < 0x1p-12, inexact if x != 0
5348 else {
54 math.doNotOptimizeAway(x + 0x1.0p120);
49 math.doNotOptimizeAway(rx + 0x1.0p120);
5550 }
5651
5752 return if (s != 0) -rx else rx;
......@@ -60,29 +55,25 @@ fn asinh32(x: f32) f32 {
6055fn asinh64(x: f64) f64 {
6156 const u = @as(u64, @bitCast(x));
6257 const e = (u >> 52) & 0x7FF;
63 const s = e >> 63;
58 const s = u >> 63;
6459
6560 var rx = @as(f64, @bitCast(u & (maxInt(u64) >> 1))); // |x|
6661
67 if (math.isNegativeInf(x)) {
68 return x;
69 }
70
7162 // |x| >= 0x1p26 or inf or nan
7263 if (e >= 0x3FF + 26) {
7364 rx = @log(rx) + 0.693147180559945309417232121458176568;
7465 }
7566 // |x| >= 2
7667 else if (e >= 0x3FF + 1) {
77 rx = @log(2 * x + 1 / (@sqrt(x * x + 1) + x));
68 rx = @log(2 * rx + 1 / (@sqrt(rx * rx + 1) + rx));
7869 }
7970 // |x| >= 0x1p-12, up to 1.6ulp error
8071 else if (e >= 0x3FF - 26) {
81 rx = math.log1p(x + x * x / (@sqrt(x * x + 1) + 1));
72 rx = math.log1p(rx + rx * rx / (@sqrt(rx * rx + 1) + 1));
8273 }
8374 // |x| < 0x1p-12, inexact if x != 0
8475 else {
85 math.doNotOptimizeAway(x + 0x1.0p120);
76 math.doNotOptimizeAway(rx + 0x1.0p120);
8677 }
8778
8879 return if (s != 0) -rx else rx;
......@@ -121,7 +112,7 @@ test "math.asinh64" {
121112
122113test "math.asinh32.special" {
123114 try expect(asinh32(0.0) == 0.0);
124 try expect(asinh32(-0.0) == -0.0);
115 try expect(@as(u32, @bitCast(asinh32(-0.0))) == @as(u32, 2147483648));
125116 try expect(math.isPositiveInf(asinh32(math.inf(f32))));
126117 try expect(math.isNegativeInf(asinh32(-math.inf(f32))));
127118 try expect(math.isNan(asinh32(math.nan(f32))));
......@@ -129,7 +120,7 @@ test "math.asinh32.special" {
129120
130121test "math.asinh64.special" {
131122 try expect(asinh64(0.0) == 0.0);
132 try expect(asinh64(-0.0) == -0.0);
123 try expect(@as(u64, @bitCast(asinh64(-0.0))) == @as(u64, 9223372036854775808));
133124 try expect(math.isPositiveInf(asinh64(math.inf(f64))));
134125 try expect(math.isNegativeInf(asinh64(-math.inf(f64))));
135126 try expect(math.isNan(asinh64(math.nan(f64))));