Skip to content

Commit 73f694e

Browse files
committed
Separate and parallelize the exhaustive tests
Also add the ability to run with a stride (or step) (Codex 5.3)
1 parent 9631bfd commit 73f694e

File tree

3 files changed

+306
-109
lines changed

3 files changed

+306
-109
lines changed

Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: test example
1+
.PHONY: test example exhaustive
22

33
# Detect linux and define _DEFAULT_SOURCE if so
44
UNAME_S := $(shell uname -s)
@@ -7,6 +7,7 @@ ifeq ($(UNAME_S),Linux)
77
endif
88

99
CLANG_FLAGS := -xc -Wall -Wextra -Wpedantic -O3 -g -std=c99 $(EXTRA_CFLAGS)
10+
CLANG_PTHREAD_FLAGS := $(CLANG_FLAGS) -pthread
1011

1112
out/test_runner: ffc.h test_src/test.c | out
1213
gcc -xc -Wall -Wextra -Wpedantic ffc.h -fsyntax-only
@@ -16,9 +17,15 @@ test: out/test_runner out/test_int_runner
1617
./out/test_runner
1718
./out/test_int_runner
1819

20+
exhaustive: out/test_exhaustive_runner
21+
./out/test_exhaustive_runner
22+
1923
out/test_int_runner: ffc.h test_src/test_int.c | out
2024
clang $(CLANG_FLAGS) -I. -Itest_src test_src/test_int.c -o out/test_int_runner -lm
2125

26+
out/test_exhaustive_runner: ffc.h test_src/test_exhaustive.c | out
27+
clang $(CLANG_PTHREAD_FLAGS) -I. -Itest_src test_src/test_exhaustive.c -o out/test_exhaustive_runner -lm
28+
2229
ffc.h: src/ffc.h src/common.h src/parse.h src/digit_comparison.h src/api.h src/bigint.h amalgamate.py
2330
python3 amalgamate.py > ffc.h
2431

test_src/test.c

Lines changed: 1 addition & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,11 @@
99
#include <fenv.h>
1010
#include <assert.h>
1111
#include <inttypes.h>
12+
#include <string.h>
1213

1314
#define FLOAT_MAXDIGITS_10 9
1415
#define DOUBLE_MAXDIGITS_10 17
1516

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-
3617
static inline ffc_outcome parse_outcome(uint64_t len, const char* outcome_text) {
3718
static const struct { const char *name; ffc_outcome val; } map[] = {
3819
{"ok", FFC_OUTCOME_OK},
@@ -366,88 +347,6 @@ void test_file(const char* filename, csv_row_callback_t cb, ffc_parse_options op
366347
csv_parser_destroy(p);
367348
}
368349

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-
451350
void double_rounds_to_nearest(void) {
452351
static volatile double fmin = DBL_MIN;
453352
char *s1, *s2;
@@ -594,7 +493,6 @@ void float_special(void) {
594493
}
595494

596495
int main(void) {
597-
598496
// verify_float("1.1754942807573642917e-38", 0x1.fffffcp-127f);
599497
// exit(0);
600498

@@ -622,11 +520,6 @@ int main(void) {
622520

623521
float_special();
624522

625-
#define FFC_TEST_EXHAUSTIVE 0
626-
#if FFC_TEST_EXHAUSTIVE
627-
exhaustive_32_run();
628-
#endif
629-
630523
if (FAILS != 0) {
631524
fprintf(stderr, "Test failures from csvs: %d\n", FAILS);
632525
return 1;

0 commit comments

Comments
 (0)