diff --git a/MultiSource/Benchmarks/TSVC/CMakeLists.txt b/MultiSource/Benchmarks/TSVC/CMakeLists.txt --- a/MultiSource/Benchmarks/TSVC/CMakeLists.txt +++ b/MultiSource/Benchmarks/TSVC/CMakeLists.txt @@ -1,3 +1,8 @@ + +# Expect exact numeric results. However, the libc printf implementation emits +# 'E' in scientific notation, while the reference output contains 'e'. +set(FP_ABSTOLERANCE 0.0) + add_subdirectory(ControlFlow-dbl) add_subdirectory(ControlFlow-flt) add_subdirectory(ControlLoops-dbl) diff --git a/tools/fpcmp.c b/tools/fpcmp.c --- a/tools/fpcmp.c +++ b/tools/fpcmp.c @@ -247,10 +247,9 @@ return data; } -int diff_files_with_tolerance(const char *path_a, const char *path_b, - double absolute_tolerance, - double relative_tolerance, - bool ignore_whitespace) { +int diff_file(const char *path_a, const char *path_b, bool parse_fp, + double absolute_tolerance, double relative_tolerance, + bool ignore_whitespace) { /* First, load the file buffers completely into memory. */ long A_size, B_size; char *data_a = load_file(path_a, &A_size); @@ -285,7 +284,7 @@ } // Scan for the end of file or next difference. - if (*F1P == *F2P && !isPossibleStartOfNumber(*F1P)) { + if (*F1P == *F2P && (!parse_fp || !isPossibleStartOfNumber(*F1P))) { ++F1P, ++F2P; continue; } @@ -297,11 +296,21 @@ if (ignore_whitespace) { if (skip_whitespace(&F1P, File1End) | skip_whitespace(&F2P, File2End)) continue; - } else { + } else if (parse_fp) { skip_whitespace(&F1NumStart, File1End); skip_whitespace(&F2NumStart, File2End); } + if (!parse_fp) { + // In non-floating point mode, recheck for character difference after + // skipping whitespace. + if (F1P < File1End && F2P < File2End && *F1P == *F2P) { + ++F1P, ++F2P; + continue; + } + break; + } + const char *F1NumEnd = AdvanceNumber(F1NumStart, File1End); const char *F2NumEnd = AdvanceNumber(F2NumStart, File2End); @@ -345,8 +354,7 @@ bool F2AtEnd = F2P >= File2End; if (!F1AtEnd && !F2AtEnd) { fprintf(stderr, - "%s: FP Comparison failed, not a numeric difference between '%c' " - "and '%c'\n", + "%s: Comparison failed, textual difference between '%c' and '%c'\n", g_program, F1P[0], F2P[0]); free(data_a); free(data_b); @@ -354,7 +362,7 @@ } if (!F1AtEnd || !F2AtEnd) { fprintf(stderr, - "%s: FP Comparison failed, unexpected end of one of the files\n", + "%s: Comparison failed, unexpected end of one of the files\n", g_program); free(data_a); free(data_b); @@ -370,16 +378,19 @@ void usage() { fprintf(stderr, "usage: %s [-a VALUE] [-r VALUE] [-i] \n\n", g_program); - fprintf(stderr, "Compare two files using absolute and relative tolerances\n"); - fprintf(stderr, "when comparing differences between two character\n"); - fprintf(stderr, "which could be real numbers\n"); - fprintf(stderr, "The -i switch ignores whitespace differences\n"); + fprintf( + stderr, + "Search two text files for differences. If either -a or -r is specified " + "(even if zero), floating numbers are parsed and considered equal if " + "neither the absolute nor relative tolerance is exceeded."); + fprintf(stderr, "The -i switch also ignores whitespace differences\n"); exit(2); } int main(int argc, char * const argv[]) { double relative_tolerance = 0.0; double absolute_tolerance = 0.0; + bool parse_fp = false; bool ignore_whitespace = false; int i; @@ -412,6 +423,7 @@ absolute_tolerance = value; else relative_tolerance = value; + parse_fp = true; } break; @@ -430,6 +442,6 @@ usage(); } - return diff_files_with_tolerance(argv[i], argv[i + 1], absolute_tolerance, - relative_tolerance, ignore_whitespace); + return diff_file(argv[i], argv[i + 1], parse_fp, absolute_tolerance, + relative_tolerance, ignore_whitespace); }