@@ -127,32 +127,32 @@ TEST_CASE("system_info") {
127
127
std::cout << std::endl;
128
128
}
129
129
130
- TEST_CASE (" float .rounds_to_nearest" ) {
130
+ TEST_CASE (" double .rounds_to_nearest" ) {
131
131
//
132
132
// If this function fails, we may be left in a non-standard rounding state.
133
133
//
134
- static float volatile fmin = std::numeric_limits<float >::min ();
134
+ static double volatile fmin = std::numeric_limits<double >::min ();
135
135
fesetround (FE_UPWARD);
136
- std::cout << " FE_UPWARD: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
137
- << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
136
+ std::cout << " FE_UPWARD: fmin + 1.0 = " << fHexAndDec (fmin + 1.0 )
137
+ << " 1.0 - fmin = " << fHexAndDec (1.0 - fmin) << std::endl;
138
138
CHECK (fegetround () == FE_UPWARD);
139
139
CHECK (fast_float::detail::rounds_to_nearest () == false );
140
140
141
141
fesetround (FE_DOWNWARD);
142
- std::cout << " FE_DOWNWARD: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
143
- << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
142
+ std::cout << " FE_DOWNWARD: fmin + 1.0 = " << fHexAndDec (fmin + 1.0 )
143
+ << " 1.0 - fmin = " << fHexAndDec (1.0 - fmin) << std::endl;
144
144
CHECK (fegetround () == FE_DOWNWARD);
145
145
CHECK (fast_float::detail::rounds_to_nearest () == false );
146
146
147
147
fesetround (FE_TOWARDZERO);
148
- std::cout << " FE_TOWARDZERO: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
149
- << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
148
+ std::cout << " FE_TOWARDZERO: fmin + 1.0 = " << fHexAndDec (fmin + 1.0 )
149
+ << " 1.0 - fmin = " << fHexAndDec (1.0 - fmin) << std::endl;
150
150
CHECK (fegetround () == FE_TOWARDZERO);
151
151
CHECK (fast_float::detail::rounds_to_nearest () == false );
152
152
153
153
fesetround (FE_TONEAREST);
154
- std::cout << " FE_TONEAREST: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
155
- << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
154
+ std::cout << " FE_TONEAREST: fmin + 1.0 = " << fHexAndDec (fmin + 1.0 )
155
+ << " 1.0 - fmin = " << fHexAndDec (1.0 - fmin) << std::endl;
156
156
CHECK (fegetround () == FE_TONEAREST);
157
157
#if (FLT_EVAL_METHOD == 1) || (FLT_EVAL_METHOD == 0)
158
158
CHECK (fast_float::detail::rounds_to_nearest () == true );
@@ -265,6 +265,144 @@ TEST_CASE("double.parse_negative_zero") {
265
265
CHECK (float64_parsed == 0x8000'0000'0000'0000 );
266
266
}
267
267
268
+ TEST_CASE (" float.rounds_to_nearest" ) {
269
+ //
270
+ // If this function fails, we may be left in a non-standard rounding state.
271
+ //
272
+ static float volatile fmin = std::numeric_limits<float >::min ();
273
+ fesetround (FE_UPWARD);
274
+ std::cout << " FE_UPWARD: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
275
+ << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
276
+ CHECK (fegetround () == FE_UPWARD);
277
+ CHECK (fast_float::detail::rounds_to_nearest () == false );
278
+
279
+ fesetround (FE_DOWNWARD);
280
+ std::cout << " FE_DOWNWARD: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
281
+ << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
282
+ CHECK (fegetround () == FE_DOWNWARD);
283
+ CHECK (fast_float::detail::rounds_to_nearest () == false );
284
+
285
+ fesetround (FE_TOWARDZERO);
286
+ std::cout << " FE_TOWARDZERO: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
287
+ << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
288
+ CHECK (fegetround () == FE_TOWARDZERO);
289
+ CHECK (fast_float::detail::rounds_to_nearest () == false );
290
+
291
+ fesetround (FE_TONEAREST);
292
+ std::cout << " FE_TONEAREST: fmin + 1.0f = " << fHexAndDec (fmin + 1 .0f )
293
+ << " 1.0f - fmin = " << fHexAndDec (1 .0f - fmin) << std::endl;
294
+ CHECK (fegetround () == FE_TONEAREST);
295
+ #if (FLT_EVAL_METHOD == 1) || (FLT_EVAL_METHOD == 0)
296
+ CHECK (fast_float::detail::rounds_to_nearest () == true );
297
+ #endif
298
+ }
299
+
300
+ TEST_CASE (" float.parse_zero" ) {
301
+ //
302
+ // If this function fails, we may be left in a non-standard rounding state.
303
+ //
304
+ char const *zero = " 0" ;
305
+ uint32_t float32_parsed;
306
+ float f = 0 ;
307
+ ::memcpy (&float32_parsed, &f, sizeof (f));
308
+ CHECK (float32_parsed == 0 );
309
+
310
+ fesetround (FE_UPWARD);
311
+ auto r1 = fast_float::from_chars (zero, zero + 1 , f);
312
+ CHECK (r1.ec == std::errc ());
313
+ std::cout << " FE_UPWARD parsed zero as " << fHexAndDec (f) << std::endl;
314
+ CHECK (f == 0 );
315
+ ::memcpy (&float32_parsed, &f, sizeof (f));
316
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
317
+ << std::endl;
318
+ CHECK (float32_parsed == 0 );
319
+
320
+ fesetround (FE_TOWARDZERO);
321
+ auto r2 = fast_float::from_chars (zero, zero + 1 , f);
322
+ CHECK (r2.ec == std::errc ());
323
+ std::cout << " FE_TOWARDZERO parsed zero as " << fHexAndDec (f) << std::endl;
324
+ CHECK (f == 0 );
325
+ ::memcpy (&float32_parsed, &f, sizeof (f));
326
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
327
+ << std::endl;
328
+ CHECK (float32_parsed == 0 );
329
+
330
+ fesetround (FE_DOWNWARD);
331
+ auto r3 = fast_float::from_chars (zero, zero + 1 , f);
332
+ CHECK (r3.ec == std::errc ());
333
+ std::cout << " FE_DOWNWARD parsed zero as " << fHexAndDec (f) << std::endl;
334
+ CHECK (f == 0 );
335
+ ::memcpy (&float32_parsed, &f, sizeof (f));
336
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
337
+ << std::endl;
338
+ CHECK (float32_parsed == 0 );
339
+
340
+ fesetround (FE_TONEAREST);
341
+ auto r4 = fast_float::from_chars (zero, zero + 1 , f);
342
+ CHECK (r4.ec == std::errc ());
343
+ std::cout << " FE_TONEAREST parsed zero as " << fHexAndDec (f) << std::endl;
344
+ CHECK (f == 0 );
345
+ ::memcpy (&float32_parsed, &f, sizeof (f));
346
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
347
+ << std::endl;
348
+ CHECK (float32_parsed == 0 );
349
+ }
350
+
351
+ TEST_CASE (" float.parse_negative_zero" ) {
352
+ //
353
+ // If this function fails, we may be left in a non-standard rounding state.
354
+ //
355
+ char const *negative_zero = " -0" ;
356
+ uint32_t float32_parsed;
357
+ float f = -0 .;
358
+ ::memcpy (&float32_parsed, &f, sizeof (f));
359
+ CHECK (float32_parsed == 0x8000'0000 );
360
+
361
+ fesetround (FE_UPWARD);
362
+ auto r1 = fast_float::from_chars (negative_zero, negative_zero + 2 , f);
363
+ CHECK (r1.ec == std::errc ());
364
+ std::cout << " FE_UPWARD parsed negative zero as " << fHexAndDec (f)
365
+ << std::endl;
366
+ CHECK (f == 0 );
367
+ ::memcpy (&float32_parsed, &f, sizeof (f));
368
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
369
+ << std::endl;
370
+ CHECK (float32_parsed == 0x8000'0000 );
371
+
372
+ fesetround (FE_TOWARDZERO);
373
+ auto r2 = fast_float::from_chars (negative_zero, negative_zero + 2 , f);
374
+ CHECK (r2.ec == std::errc ());
375
+ std::cout << " FE_TOWARDZERO parsed negative zero as " << fHexAndDec (f)
376
+ << std::endl;
377
+ CHECK (f == 0 );
378
+ ::memcpy (&float32_parsed, &f, sizeof (f));
379
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
380
+ << std::endl;
381
+ CHECK (float32_parsed == 0x8000'0000 );
382
+
383
+ fesetround (FE_DOWNWARD);
384
+ auto r3 = fast_float::from_chars (negative_zero, negative_zero + 2 , f);
385
+ CHECK (r3.ec == std::errc ());
386
+ std::cout << " FE_DOWNWARD parsed negative zero as " << fHexAndDec (f)
387
+ << std::endl;
388
+ CHECK (f == 0 );
389
+ ::memcpy (&float32_parsed, &f, sizeof (f));
390
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
391
+ << std::endl;
392
+ CHECK (float32_parsed == 0x8000'0000 );
393
+
394
+ fesetround (FE_TONEAREST);
395
+ auto r4 = fast_float::from_chars (negative_zero, negative_zero + 2 , f);
396
+ CHECK (r4.ec == std::errc ());
397
+ std::cout << " FE_TONEAREST parsed negative zero as " << fHexAndDec (f)
398
+ << std::endl;
399
+ CHECK (f == 0 );
400
+ ::memcpy (&float32_parsed, &f, sizeof (f));
401
+ std::cout << " float as uint32_t is " << iHexAndDec (float32_parsed)
402
+ << std::endl;
403
+ CHECK (float32_parsed == 0x8000'0000 );
404
+ }
405
+
268
406
#if FASTFLOAT_SUPPLEMENTAL_TESTS
269
407
// C++ 17 because it is otherwise annoying to browse all files in a directory.
270
408
// We also only run these tests on little endian systems.
0 commit comments