Skip to content

Commit a35688b

Browse files
authored
Merge pull request #20069 from LewisGaul/math-tests-simplified
Math tests simplified (exp and log functions) with bugfixes
2 parents e62e42f + 03dfd2e commit a35688b

File tree

7 files changed

+473
-186
lines changed

7 files changed

+473
-186
lines changed

lib/compiler_rt/exp.zig

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const arch = builtin.cpu.arch;
1010
const math = std.math;
1111
const mem = std.mem;
1212
const expect = std.testing.expect;
13+
const expectEqual = std.testing.expectEqual;
1314
const common = @import("common.zig");
1415

1516
pub const panic = common.panic;
@@ -211,32 +212,100 @@ pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {
211212
}
212213
}
213214

214-
test "exp32" {
215-
const epsilon = 0.000001;
215+
test "expf() special" {
216+
try expectEqual(expf(0.0), 1.0);
217+
try expectEqual(expf(-0.0), 1.0);
218+
try expectEqual(expf(1.0), math.e);
219+
try expectEqual(expf(math.ln2), 2.0);
220+
try expectEqual(expf(math.inf(f32)), math.inf(f32));
221+
try expect(math.isPositiveZero(expf(-math.inf(f32))));
222+
try expect(math.isNan(expf(math.nan(f32))));
223+
try expect(math.isNan(expf(math.snan(f32))));
224+
}
216225

217-
try expect(expf(0.0) == 1.0);
218-
try expect(math.approxEqAbs(f32, expf(0.0), 1.0, epsilon));
219-
try expect(math.approxEqAbs(f32, expf(0.2), 1.221403, epsilon));
220-
try expect(math.approxEqAbs(f32, expf(0.8923), 2.440737, epsilon));
221-
try expect(math.approxEqAbs(f32, expf(1.5), 4.481689, epsilon));
226+
test "expf() sanity" {
227+
try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12);
228+
try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6);
229+
try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13);
230+
try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10);
231+
try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13);
232+
try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0);
233+
try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1);
234+
try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0);
235+
try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1);
236+
try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1);
237+
try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8);
238+
try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20);
239+
try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25);
240+
try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20);
241+
try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8);
242+
try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2);
243+
try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16);
244+
try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24);
245+
try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5);
246+
try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28);
222247
}
223248

224-
test "exp64" {
225-
const epsilon = 0.000001;
249+
test "expf() boundary" {
250+
try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite
251+
try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf
252+
try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value
253+
try expectEqual(expf(0x1p-149), 1.0); // Min positive input value
254+
try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value
255+
try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input
256+
try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input
257+
try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero
258+
try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero
259+
try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal
260+
try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal
226261

227-
try expect(exp(0.0) == 1.0);
228-
try expect(math.approxEqAbs(f64, exp(0.0), 1.0, epsilon));
229-
try expect(math.approxEqAbs(f64, exp(0.2), 1.221403, epsilon));
230-
try expect(math.approxEqAbs(f64, exp(0.8923), 2.440737, epsilon));
231-
try expect(math.approxEqAbs(f64, exp(1.5), 4.481689, epsilon));
232262
}
233263

234-
test "exp32.special" {
235-
try expect(math.isPositiveInf(expf(math.inf(f32))));
236-
try expect(math.isNan(expf(math.nan(f32))));
264+
test "exp() special" {
265+
try expectEqual(exp(0.0), 1.0);
266+
try expectEqual(exp(-0.0), 1.0);
267+
// TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC
268+
// try expectEqual(exp(1.0), math.e);
269+
try expectEqual(exp(math.ln2), 2.0);
270+
try expectEqual(exp(math.inf(f64)), math.inf(f64));
271+
try expect(math.isPositiveZero(exp(-math.inf(f64))));
272+
try expect(math.isNan(exp(math.nan(f64))));
273+
try expect(math.isNan(exp(math.snan(f64))));
237274
}
238275

239-
test "exp64.special" {
240-
try expect(math.isPositiveInf(exp(math.inf(f64))));
241-
try expect(math.isNan(exp(math.nan(f64))));
276+
test "exp() sanity" {
277+
try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);
278+
try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);
279+
try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);
280+
try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);
281+
try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);
282+
try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);
283+
try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);
284+
try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);
285+
try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);
286+
try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);
287+
try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);
288+
try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);
289+
try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);
290+
try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);
291+
try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);
292+
try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);
293+
try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);
294+
try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);
295+
try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);
296+
try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);
297+
}
298+
299+
test "exp() boundary" {
300+
try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite
301+
try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf
302+
try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
303+
try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value
304+
try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value
305+
try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input
306+
try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input
307+
try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero
308+
try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero
309+
try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal
310+
try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal
242311
}

lib/compiler_rt/exp2.zig

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const arch = builtin.cpu.arch;
1010
const math = std.math;
1111
const mem = std.mem;
1212
const expect = std.testing.expect;
13+
const expectEqual = std.testing.expectEqual;
1314
const common = @import("common.zig");
1415

1516
pub const panic = common.panic;
@@ -58,7 +59,7 @@ pub fn exp2f(x: f32) callconv(.c) f32 {
5859
if (common.want_float_exceptions) mem.doNotOptimizeAway(-0x1.0p-149 / x);
5960
}
6061
// x <= -150
61-
if (u >= 0x3160000) {
62+
if (u >= 0xC3160000) {
6263
return 0;
6364
}
6465
}
@@ -457,34 +458,78 @@ const exp2dt = [_]f64{
457458
0x1.690f4b19e9471p+0, -0x1.9780p-45,
458459
};
459460

460-
test "exp2_32" {
461-
const epsilon = 0.000001;
461+
test "exp2f() special" {
462+
try expectEqual(exp2f(0.0), 1.0);
463+
try expectEqual(exp2f(-0.0), 1.0);
464+
try expectEqual(exp2f(1.0), 2.0);
465+
try expectEqual(exp2f(-1.0), 0.5);
466+
try expectEqual(exp2f(math.inf(f32)), math.inf(f32));
467+
try expect(math.isPositiveZero(exp2f(-math.inf(f32))));
468+
try expect(math.isNan(exp2f(math.nan(f32))));
469+
try expect(math.isNan(exp2f(math.snan(f32))));
470+
}
462471

463-
try expect(exp2f(0.0) == 1.0);
464-
try expect(math.approxEqAbs(f32, exp2f(0.2), 1.148698, epsilon));
465-
try expect(math.approxEqAbs(f32, exp2f(0.8923), 1.856133, epsilon));
466-
try expect(math.approxEqAbs(f32, exp2f(1.5), 2.828427, epsilon));
467-
try expect(math.approxEqAbs(f32, exp2f(37.45), 187747237888, epsilon));
468-
try expect(math.approxEqAbs(f32, exp2f(-1), 0.5, epsilon));
472+
test "exp2f() sanity" {
473+
try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9);
474+
try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4);
475+
try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9);
476+
try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7);
477+
try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9);
478+
try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0);
479+
try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1);
480+
try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0);
481+
try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0);
482+
try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1);
469483
}
470484

471-
test "exp2_64" {
472-
const epsilon = 0.000001;
485+
test "exp2f() boundary" {
486+
try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite
487+
try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result
488+
try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero
489+
try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero
490+
try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal
491+
try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal
492+
try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value
493+
try expectEqual(exp2f(0x1p-149), 1); // Min positive input value
494+
try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value
495+
try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input
496+
try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input
497+
}
473498

474-
try expect(exp2(0.0) == 1.0);
475-
try expect(math.approxEqAbs(f64, exp2(0.2), 1.148698, epsilon));
476-
try expect(math.approxEqAbs(f64, exp2(0.8923), 1.856133, epsilon));
477-
try expect(math.approxEqAbs(f64, exp2(1.5), 2.828427, epsilon));
478-
try expect(math.approxEqAbs(f64, exp2(-1), 0.5, epsilon));
479-
try expect(math.approxEqAbs(f64, exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1, epsilon));
499+
test "exp2() special" {
500+
try expectEqual(exp2(0.0), 1.0);
501+
try expectEqual(exp2(-0.0), 1.0);
502+
try expectEqual(exp2(1.0), 2.0);
503+
try expectEqual(exp2(-1.0), 0.5);
504+
try expectEqual(exp2(math.inf(f64)), math.inf(f64));
505+
try expect(math.isPositiveZero(exp2(-math.inf(f64))));
506+
try expect(math.isNan(exp2(math.nan(f64))));
507+
try expect(math.isNan(exp2(math.snan(f64))));
480508
}
481509

482-
test "exp2_32.special" {
483-
try expect(math.isPositiveInf(exp2f(math.inf(f32))));
484-
try expect(math.isNan(exp2f(math.nan(f32))));
510+
test "exp2() sanity" {
511+
try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);
512+
try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);
513+
try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);
514+
try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);
515+
try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);
516+
try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);
517+
try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);
518+
try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);
519+
try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);
520+
try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);
485521
}
486522

487-
test "exp2_64.special" {
488-
try expect(math.isPositiveInf(exp2(math.inf(f64))));
489-
try expect(math.isNan(exp2(math.nan(f64))));
523+
test "exp2() boundary" {
524+
try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite
525+
try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result
526+
try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero
527+
try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero
528+
try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal
529+
try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal
530+
try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
531+
try expectEqual(exp2(0x1p-1074), 1); // Min positive input value
532+
try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value
533+
try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input
534+
try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input
490535
}

lib/compiler_rt/log.zig

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
const std = @import("std");
88
const builtin = @import("builtin");
99
const math = std.math;
10-
const testing = std.testing;
10+
const expect = std.testing.expect;
11+
const expectEqual = std.testing.expectEqual;
1112
const arch = builtin.cpu.arch;
1213
const common = @import("common.zig");
1314

@@ -110,8 +111,8 @@ pub fn log(x_: f64) callconv(.c) f64 {
110111

111112
// subnormal, scale x
112113
k -= 54;
113-
x *= 0x1.0p54;
114-
hx = @intCast(@as(u64, @bitCast(ix)) >> 32);
114+
x *= 0x1p54;
115+
hx = @intCast(@as(u64, @bitCast(x)) >> 32);
115116
} else if (hx >= 0x7FF00000) {
116117
return x;
117118
} else if (hx == 0x3FF00000 and ix << 32 == 0) {
@@ -159,38 +160,72 @@ pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {
159160
}
160161
}
161162

162-
test "ln32" {
163-
const epsilon = 0.000001;
163+
test "logf() special" {
164+
try expectEqual(logf(0.0), -math.inf(f32));
165+
try expectEqual(logf(-0.0), -math.inf(f32));
166+
try expect(math.isPositiveZero(logf(1.0)));
167+
try expectEqual(logf(math.e), 1.0);
168+
try expectEqual(logf(math.inf(f32)), math.inf(f32));
169+
try expect(math.isNan(logf(-1.0)));
170+
try expect(math.isNan(logf(-math.inf(f32))));
171+
try expect(math.isNan(logf(math.nan(f32))));
172+
try expect(math.isNan(logf(math.snan(f32))));
173+
}
164174

165-
try testing.expect(math.approxEqAbs(f32, logf(0.2), -1.609438, epsilon));
166-
try testing.expect(math.approxEqAbs(f32, logf(0.8923), -0.113953, epsilon));
167-
try testing.expect(math.approxEqAbs(f32, logf(1.5), 0.405465, epsilon));
168-
try testing.expect(math.approxEqAbs(f32, logf(37.45), 3.623007, epsilon));
169-
try testing.expect(math.approxEqAbs(f32, logf(89.123), 4.490017, epsilon));
170-
try testing.expect(math.approxEqAbs(f32, logf(123123.234375), 11.720941, epsilon));
175+
test "logf() sanity" {
176+
try expect(math.isNan(logf(-0x1.0223a0p+3)));
177+
try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0);
178+
try expect(math.isNan(logf(-0x1.0c34b4p+3)));
179+
try expect(math.isNan(logf(-0x1.a206f0p+2)));
180+
try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1);
181+
try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2);
182+
try expect(math.isNan(logf(-0x1.a05cc8p-2)));
183+
try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1);
184+
try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2);
185+
try expect(math.isNan(logf(-0x1.5b86eap-1)));
171186
}
172187

173-
test "ln64" {
174-
const epsilon = 0.000001;
188+
test "logf() boundary" {
189+
try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value
190+
try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value
191+
try expect(math.isNan(logf(-0x1p-149))); // Min negative input value
192+
try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0
193+
try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0
194+
try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal
195+
try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal
196+
}
175197

176-
try testing.expect(math.approxEqAbs(f64, log(0.2), -1.609438, epsilon));
177-
try testing.expect(math.approxEqAbs(f64, log(0.8923), -0.113953, epsilon));
178-
try testing.expect(math.approxEqAbs(f64, log(1.5), 0.405465, epsilon));
179-
try testing.expect(math.approxEqAbs(f64, log(37.45), 3.623007, epsilon));
180-
try testing.expect(math.approxEqAbs(f64, log(89.123), 4.490017, epsilon));
181-
try testing.expect(math.approxEqAbs(f64, log(123123.234375), 11.720941, epsilon));
198+
test "log() special" {
199+
try expectEqual(log(0.0), -math.inf(f64));
200+
try expectEqual(log(-0.0), -math.inf(f64));
201+
try expect(math.isPositiveZero(log(1.0)));
202+
try expectEqual(log(math.e), 1.0);
203+
try expectEqual(log(math.inf(f64)), math.inf(f64));
204+
try expect(math.isNan(log(-1.0)));
205+
try expect(math.isNan(log(-math.inf(f64))));
206+
try expect(math.isNan(log(math.nan(f64))));
207+
try expect(math.isNan(log(math.snan(f64))));
182208
}
183209

184-
test "ln32.special" {
185-
try testing.expect(math.isPositiveInf(logf(math.inf(f32))));
186-
try testing.expect(math.isNegativeInf(logf(0.0)));
187-
try testing.expect(math.isNan(logf(-1.0)));
188-
try testing.expect(math.isNan(logf(math.nan(f32))));
210+
test "log() sanity" {
211+
try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3)));
212+
try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);
213+
try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3)));
214+
try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2)));
215+
try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);
216+
try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);
217+
try expect(math.isNan(log(-0x1.a05cc754481d1p-2)));
218+
try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);
219+
try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);
220+
try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1)));
189221
}
190222

191-
test "ln64.special" {
192-
try testing.expect(math.isPositiveInf(log(math.inf(f64))));
193-
try testing.expect(math.isNegativeInf(log(0.0)));
194-
try testing.expect(math.isNan(log(-1.0)));
195-
try testing.expect(math.isNan(log(math.nan(f64))));
223+
test "log() boundary" {
224+
try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value
225+
try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value
226+
try expect(math.isNan(log(-0x1p-1074))); // Min negative input value
227+
try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0
228+
try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0
229+
try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal
230+
try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal
196231
}

0 commit comments

Comments
 (0)