|
9 | 9 | #include <fenv.h> |
10 | 10 | #include <assert.h> |
11 | 11 | #include <inttypes.h> |
| 12 | +#include <string.h> |
12 | 13 |
|
13 | 14 | #define FLOAT_MAXDIGITS_10 9 |
14 | 15 | #define DOUBLE_MAXDIGITS_10 17 |
15 | 16 |
|
16 | | -char *float_to_string_long(float f, char *buffer) { |
17 | | - int written = snprintf(buffer, 128, "%.*e", 64, f); |
18 | | - return buffer + written; |
19 | | -} |
20 | | - |
21 | | -char *float_to_string(float f, char *buffer) { |
22 | | - int written = snprintf(buffer, 64, "%.*e", FLOAT_MAXDIGITS_10 - 1, f); |
23 | | - return buffer + written; |
24 | | -} |
25 | | - |
26 | | -char *double_to_string_long(double d, char *buffer) { |
27 | | - int written = snprintf(buffer, 128, "%.*e", 64, d); |
28 | | - return buffer + written; |
29 | | -} |
30 | | - |
31 | | -char *double_to_string(double d, char *buffer) { |
32 | | - int written = snprintf(buffer, 64, "%.*e", FLOAT_MAXDIGITS_10 - 1, d); |
33 | | - return buffer + written; |
34 | | -} |
35 | | - |
36 | 17 | static inline ffc_outcome parse_outcome(uint64_t len, const char* outcome_text) { |
37 | 18 | static const struct { const char *name; ffc_outcome val; } map[] = { |
38 | 19 | {"ok", FFC_OUTCOME_OK}, |
@@ -366,88 +347,6 @@ void test_file(const char* filename, csv_row_callback_t cb, ffc_parse_options op |
366 | 347 | csv_parser_destroy(p); |
367 | 348 | } |
368 | 349 |
|
369 | | -ffc_result roundtrip_float(float f, float *result, bool do_long) { |
370 | | - char buffer[128]; |
371 | | - char const *string_end = do_long ? float_to_string_long(f, buffer) : float_to_string(f, buffer); |
372 | | - ffc_result parse_result = ffc_from_chars_float(buffer, string_end, result); |
373 | | - return parse_result; |
374 | | -} |
375 | | - |
376 | | -void test_exhaustive(char *buffer, bool do_long) { |
377 | | - for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) { |
378 | | - float f; |
379 | | - double d; |
380 | | - if ((w % 1048576) == 0) { |
381 | | - printf("%"PRIu64" / %"PRIu32"\n", w / 1048576, 0xFFFFFFFF / 1048576); |
382 | | - } |
383 | | - uint32_t word32 = (uint32_t)(w); |
384 | | - |
385 | | - memcpy(&f, &word32, sizeof(f)); |
386 | | - memcpy(&d, &w, sizeof(d)); |
387 | | - |
388 | | -#if 1 |
389 | | - { |
390 | | - char const *string_end = do_long ? float_to_string_long(f, buffer) : float_to_string(f, buffer); |
391 | | - float result_value; |
392 | | - ffc_result result = ffc_from_chars_float(buffer, string_end, &result_value); |
393 | | - // Starting with version 4.0 for fast_float, we return result_out_of_range |
394 | | - // if the value is either too small (too close to zero) or too large |
395 | | - // (effectively infinity). So std::errc::result_out_of_range is normal for |
396 | | - // well-formed input strings. |
397 | | - if (result.outcome != FFC_OUTCOME_OK && |
398 | | - result.outcome != FFC_OUTCOME_OUT_OF_RANGE) { |
399 | | - fprintf(stderr, "(32) parsing error ? %s\n", buffer); |
400 | | - abort(); |
401 | | - } |
402 | | - if (isnan(f)) { |
403 | | - if (!isnan(result_value)) { |
404 | | - fprintf(stderr, "(32) not nan %s\n", buffer); |
405 | | - abort(); |
406 | | - } |
407 | | - } else if (copysign(1, result_value) != copysign(1, f)) { |
408 | | - fprintf(stderr, "(32) %s\n", buffer); |
409 | | - fprintf(stderr, "(32) I got %a but I was expecting %a\n", result_value, f); |
410 | | - abort(); |
411 | | - } else if (result_value != f) { |
412 | | - fprintf(stderr, "(32) fail for w = %"PRIu64"\n%s got %f expected %f\n", w, buffer, result_value, f); |
413 | | - fprintf(stderr, "(32) started with %a\n", f); |
414 | | - fprintf(stderr, "(32) got back %a\n", result_value); |
415 | | - abort(); |
416 | | - } |
417 | | - } |
418 | | -#endif |
419 | | - { |
420 | | - char const *string_end = do_long ? double_to_string_long(d, buffer) : double_to_string(d, buffer); |
421 | | - double result_double; |
422 | | - ffc_result result = ffc_from_chars_double(buffer, string_end, &result_double); |
423 | | - // Starting with version 4.0 for fast_float, we return result_out_of_range |
424 | | - // if the value is either too small (too close to zero) or too large |
425 | | - // (effectively infinity). So std::errc::result_out_of_range is normal for |
426 | | - // well-formed input strings. |
427 | | - if (result.outcome != FFC_OUTCOME_OK && |
428 | | - result.outcome != FFC_OUTCOME_OUT_OF_RANGE) { |
429 | | - fprintf(stderr, "(64) parsing error ? %s\n", buffer); |
430 | | - abort(); |
431 | | - } |
432 | | - if (!double_eq(result_double, d)) { |
433 | | - fprintf(stderr, "(64) fail for w = %"PRIu64"\n%s got %f expected %f\n", w, buffer, result_double, d); |
434 | | - fprintf(stderr, "(64) started with %a\n", d); |
435 | | - fprintf(stderr, "(64) got back %a\n", result_double); |
436 | | - abort(); |
437 | | - } |
438 | | - } |
439 | | - } |
440 | | - puts(""); |
441 | | -} |
442 | | - |
443 | | -void exhaustive_32_run(void) { |
444 | | - char buffer_long[128]; |
445 | | - test_exhaustive(buffer_long, true); |
446 | | - puts("\nall ok"); |
447 | | - return; |
448 | | -} |
449 | | - |
450 | | - |
451 | 350 | void double_rounds_to_nearest(void) { |
452 | 351 | static volatile double fmin = DBL_MIN; |
453 | 352 | char *s1, *s2; |
@@ -594,7 +493,6 @@ void float_special(void) { |
594 | 493 | } |
595 | 494 |
|
596 | 495 | int main(void) { |
597 | | - |
598 | 496 | // verify_float("1.1754942807573642917e-38", 0x1.fffffcp-127f); |
599 | 497 | // exit(0); |
600 | 498 |
|
@@ -622,11 +520,6 @@ int main(void) { |
622 | 520 |
|
623 | 521 | float_special(); |
624 | 522 |
|
625 | | - #define FFC_TEST_EXHAUSTIVE 0 |
626 | | - #if FFC_TEST_EXHAUSTIVE |
627 | | - exhaustive_32_run(); |
628 | | - #endif |
629 | | - |
630 | 523 | if (FAILS != 0) { |
631 | 524 | fprintf(stderr, "Test failures from csvs: %d\n", FAILS); |
632 | 525 | return 1; |
|
0 commit comments