@@ -8,6 +8,7 @@ const std = @import("../std.zig");
8
8
const math = std .math ;
9
9
const mem = std .mem ;
10
10
const expect = std .testing .expect ;
11
+ const expectEqual = std .testing .expectEqual ;
11
12
12
13
/// Returns the natural logarithm of 1 + x with greater accuracy when x is near zero.
13
14
///
@@ -182,49 +183,72 @@ fn log1p_64(x: f64) f64 {
182
183
return s * (hfsq + R ) + (dk * ln2_lo + c ) - hfsq + f + dk * ln2_hi ;
183
184
}
184
185
185
- test log1p {
186
- try expect (log1p (@as (f32 , 0.0 )) == log1p_32 (0.0 ));
187
- try expect (log1p (@as (f64 , 0.0 )) == log1p_64 (0.0 ));
186
+ test "log1p_32() special" {
187
+ try expectEqual (log1p_32 (0.0 ), 0.0 );
188
+ try expectEqual (log1p_32 (-0.0 ), 0.0 );
189
+ try expectEqual (log1p_32 (-1.0 ), - math .inf (f32 ));
190
+ try expectEqual (log1p_32 (1.0 ), math .ln2 );
191
+ try expectEqual (log1p_32 (math .inf (f32 )), math .inf (f32 ));
192
+ try expect (math .isNan (log1p_32 (-2.0 )));
193
+ try expect (math .isNan (log1p_32 (- math .inf (f32 ))));
194
+ try expect (math .isNan (log1p_32 (math .nan (f32 ))));
195
+ try expect (math .isNan (log1p_32 (math .snan (f32 ))));
188
196
}
189
197
190
- test log1p_32 {
191
- const epsilon = 0.000001 ;
192
-
193
- try expect (math .approxEqAbs (f32 , log1p_32 (0.0 ), 0.0 , epsilon ));
194
- try expect (math .approxEqAbs (f32 , log1p_32 (0.2 ), 0.182322 , epsilon ));
195
- try expect (math .approxEqAbs (f32 , log1p_32 (0.8923 ), 0.637793 , epsilon ));
196
- try expect (math .approxEqAbs (f32 , log1p_32 (1.5 ), 0.916291 , epsilon ));
197
- try expect (math .approxEqAbs (f32 , log1p_32 (37.45 ), 3.649359 , epsilon ));
198
- try expect (math .approxEqAbs (f32 , log1p_32 (89.123 ), 4.501175 , epsilon ));
199
- try expect (math .approxEqAbs (f32 , log1p_32 (123123.234375 ), 11.720949 , epsilon ));
198
+ test "log1p_32() sanity" {
199
+ try expect (math .isNan (log1p_32 (-0x1.0223a0p+3 )));
200
+ try expectEqual (log1p_32 (0x1.161868p+2 ), 0x1.ad1bdcp+0 );
201
+ try expect (math .isNan (log1p_32 (-0x1.0c34b4p+3 )));
202
+ try expect (math .isNan (log1p_32 (-0x1.a206f0p+2 )));
203
+ try expectEqual (log1p_32 (0x1.288bbcp+3 ), 0x1.2a1ab8p+1 );
204
+ try expectEqual (log1p_32 (0x1.52efd0p-1 ), 0x1.041a4ep-1 );
205
+ try expectEqual (log1p_32 (-0x1.a05cc8p-2 ), -0x1.0b3596p-1 );
206
+ try expectEqual (log1p_32 (0x1.1f9efap-1 ), 0x1.c88344p-2 );
207
+ try expectEqual (log1p_32 (0x1.8c5db0p-1 ), 0x1.258a8ep-1 );
208
+ try expectEqual (log1p_32 (-0x1.5b86eap-1 ), -0x1.22b542p+0 );
200
209
}
201
210
202
- test log1p_64 {
203
- const epsilon = 0.000001 ;
211
+ test "log1p_32() boundary" {
212
+ try expectEqual (log1p_32 (0x1.fffffep+127 ), 0x1.62e430p+6 ); // Max input value
213
+ try expectEqual (log1p_32 (0x1p-149 ), 0x1p-149 ); // Min positive input value
214
+ try expectEqual (log1p_32 (-0x1p-149 ), -0x1p-149 ); // Min negative input value
215
+ try expectEqual (log1p_32 (0x1p-126 ), 0x1p-126 ); // First subnormal
216
+ try expectEqual (log1p_32 (-0x1p-126 ), -0x1p-126 ); // First negative subnormal
217
+ try expectEqual (log1p_32 (-0x1.fffffep-1 ), -0x1.0a2b24p+4 ); // Last value before result is -inf
218
+ try expect (math .isNan (log1p_32 (-0x1.000002p+0 ))); // First value where result is nan
219
+ }
204
220
205
- try expect (math .approxEqAbs (f64 , log1p_64 (0.0 ), 0.0 , epsilon ));
206
- try expect (math .approxEqAbs (f64 , log1p_64 (0.2 ), 0.182322 , epsilon ));
207
- try expect (math .approxEqAbs (f64 , log1p_64 (0.8923 ), 0.637793 , epsilon ));
208
- try expect (math .approxEqAbs (f64 , log1p_64 (1.5 ), 0.916291 , epsilon ));
209
- try expect (math .approxEqAbs (f64 , log1p_64 (37.45 ), 3.649359 , epsilon ));
210
- try expect (math .approxEqAbs (f64 , log1p_64 (89.123 ), 4.501175 , epsilon ));
211
- try expect (math .approxEqAbs (f64 , log1p_64 (123123.234375 ), 11.720949 , epsilon ));
221
+ test "log1p_64() special" {
222
+ try expectEqual (log1p_64 (0.0 ), 0.0 );
223
+ try expectEqual (log1p_64 (-0.0 ), 0.0 );
224
+ try expectEqual (log1p_64 (-1.0 ), - math .inf (f64 ));
225
+ try expectEqual (log1p_64 (1.0 ), math .ln2 );
226
+ try expectEqual (log1p_64 (math .inf (f64 )), math .inf (f64 ));
227
+ try expect (math .isNan (log1p_64 (-2.0 )));
228
+ try expect (math .isNan (log1p_64 (- math .inf (f64 ))));
229
+ try expect (math .isNan (log1p_64 (math .nan (f64 ))));
230
+ try expect (math .isNan (log1p_64 (math .snan (f64 ))));
212
231
}
213
232
214
- test "log1p_32.special" {
215
- try expect (math .isPositiveInf (log1p_32 (math .inf (f32 ))));
216
- try expect (math .isPositiveZero (log1p_32 (0.0 )));
217
- try expect (math .isNegativeZero (log1p_32 (-0.0 )));
218
- try expect (math .isNegativeInf (log1p_32 (-1.0 )));
219
- try expect (math .isNan (log1p_32 (-2.0 )));
220
- try expect (math .isNan (log1p_32 (math .nan (f32 ))));
233
+ test "log1p_64() sanity" {
234
+ try expect (math .isNan (log1p_64 (-0x1.02239f3c6a8f1p+3 )));
235
+ try expectEqual (log1p_64 (0x1.161868e18bc67p+2 ), 0x1.ad1bdd1e9e686p+0 ); // Disagrees with GCC in last bit
236
+ try expect (math .isNan (log1p_64 (-0x1.0c34b3e01e6e7p+3 )));
237
+ try expect (math .isNan (log1p_64 (-0x1.a206f0a19dcc4p+2 )));
238
+ try expectEqual (log1p_64 (0x1.288bbb0d6a1e6p+3 ), 0x1.2a1ab8365b56fp+1 );
239
+ try expectEqual (log1p_64 (0x1.52efd0cd80497p-1 ), 0x1.041a4ec2a680ap-1 );
240
+ try expectEqual (log1p_64 (-0x1.a05cc754481d1p-2 ), -0x1.0b3595423aec1p-1 );
241
+ try expectEqual (log1p_64 (0x1.1f9ef934745cbp-1 ), 0x1.c8834348a846ep-2 );
242
+ try expectEqual (log1p_64 (0x1.8c5db097f7442p-1 ), 0x1.258a8e8a35bbfp-1 );
243
+ try expectEqual (log1p_64 (-0x1.5b86ea8118a0ep-1 ), -0x1.22b5426327502p+0 );
221
244
}
222
245
223
- test "log1p_64.special" {
224
- try expect (math .isPositiveInf (log1p_64 (math .inf (f64 ))));
225
- try expect (math .isPositiveZero (log1p_64 (0.0 )));
226
- try expect (math .isNegativeZero (log1p_64 (-0.0 )));
227
- try expect (math .isNegativeInf (log1p_64 (-1.0 )));
228
- try expect (math .isNan (log1p_64 (-2.0 )));
229
- try expect (math .isNan (log1p_64 (math .nan (f64 ))));
246
+ test "log1p_64() boundary" {
247
+ try expectEqual (log1p_64 (0x1.fffffffffffffp+1023 ), 0x1.62e42fefa39efp+9 ); // Max input value
248
+ try expectEqual (log1p_64 (0x1p-1074 ), 0x1p-1074 ); // Min positive input value
249
+ try expectEqual (log1p_64 (-0x1p-1074 ), -0x1p-1074 ); // Min negative input value
250
+ try expectEqual (log1p_64 (0x1p-1022 ), 0x1p-1022 ); // First subnormal
251
+ try expectEqual (log1p_64 (-0x1p-1022 ), -0x1p-1022 ); // First negative subnormal
252
+ try expectEqual (log1p_64 (-0x1.fffffffffffffp-1 ), -0x1.25e4f7b2737fap+5 ); // Last value before result is -inf
253
+ try expect (math .isNan (log1p_64 (-0x1.0000000000001p+0 ))); // First value where result is nan
230
254
}
0 commit comments