@@ -10,6 +10,7 @@ const arch = builtin.cpu.arch;
10
10
const math = std .math ;
11
11
const mem = std .mem ;
12
12
const expect = std .testing .expect ;
13
+ const expectEqual = std .testing .expectEqual ;
13
14
const common = @import ("common.zig" );
14
15
15
16
pub const panic = common .panic ;
@@ -211,32 +212,100 @@ pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {
211
212
}
212
213
}
213
214
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
+ }
216
225
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 );
222
247
}
223
248
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
226
261
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 ));
232
262
}
233
263
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 ))));
237
274
}
238
275
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
242
311
}
0 commit comments