From fd9d9effda91bdba9b9135ef8b66f14bb576dc25 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 16 Nov 2022 15:25:03 -0500 Subject: [PATCH] More tweaking around clangcl --- include/fast_float/parse_number.h | 13 +++-- tests/basictest.cpp | 91 +++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 29 deletions(-) diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index b5f92ce..2b3b935 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -135,13 +135,14 @@ from_chars_result from_chars_advanced(const char *first, const char *last, // We do not have that fegetround() == FE_TONEAREST. // Next is a modified Clinger's fast path, inspired by Jakub JelĂ­nek's proposal if (pns.exponent >= 0 && pns.exponent <= binary_format::max_exponent_fast_path() && pns.mantissa <=binary_format::max_mantissa_fast_path(pns.exponent) && !pns.too_many_digits) { -#if (defined(_WIN32) && defined(__clang__)) - // 32-bit ClangCL maps 0 to -0.0 when fegetround() == FE_DOWNWARD - value = pns.mantissa ? T(pns.mantissa) : 0.0; -#else - value = T(pns.mantissa); +#if (defined(_MSC_VER) && defined(__clang__)) + // ClangCL may map 0 to -0.0 when fegetround() == FE_DOWNWARD + if(pns.mantissa == 0) { + value = 0; + return answer; + } #endif - value = value * binary_format::exact_power_of_ten(pns.exponent); + value = T(pns.mantissa) * binary_format::exact_power_of_ten(pns.exponent); if (pns.negative) { value = -value; } return answer; } diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 1c07256..fec51de 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -48,13 +48,66 @@ #define fHexAndDec(v) std::hexfloat << (v) << " (" << std::defaultfloat << (v) << ")" -// C++ 17 because it is otherwise annoying to browse all files in a directory. -// We also only run these tests on little endian systems. -#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) +const char * round_name(int d) { + switch(d) { + case FE_UPWARD: + return "FE_UPWARD"; + case FE_DOWNWARD: + return "FE_DOWNWARD"; + case FE_TOWARDZERO: + return "FE_TOWARDZERO"; + case FE_TONEAREST: + return "FE_TONEAREST"; + default: + return "UNKNOWN"; + } +} + + +#define FASTFLOAT_STR(x) #x +#define SHOW_DEFINE(x) printf("%s='%s'\n", #x, FASTFLOAT_STR(x)) + +TEST_CASE("system_info") { + std::cout << "system info:" << std::endl; +#ifdef _MSC_VER + SHOW_DEFINE(_MSC_VER); +#endif +#ifdef FASTFLOAT_64BIT_LIMB + SHOW_DEFINE(FASTFLOAT_64BIT_LIMB); +#endif +#ifdef __clang__ + SHOW_DEFINE(__clang__); +#endif +#ifdef FASTFLOAT_VISUAL_STUDIO + SHOW_DEFINE(FASTFLOAT_VISUAL_STUDIO); +#endif +#ifdef FASTFLOAT_IS_BIG_ENDIAN + #if FASTFLOAT_IS_BIG_ENDIAN + printf("big endian\n"); + #else + printf("little endian\n"); + #endif +#endif +#ifdef FASTFLOAT_32BIT + SHOW_DEFINE(FASTFLOAT_32BIT); +#endif +#ifdef FASTFLOAT_64BIT + SHOW_DEFINE(FASTFLOAT_64BIT); +#endif +#ifdef FLT_EVAL_METHOD + SHOW_DEFINE(FLT_EVAL_METHOD); +#endif +#ifdef _WIN32 + SHOW_DEFINE(_WIN32); +#endif +#ifdef _WIN64 + SHOW_DEFINE(_WIN64); +#endif + std::cout << "fegetround() = " << round_name(fegetround()) << std::endl; + std::cout << std::endl; + +} -#include -#include -#include TEST_CASE("rounds_to_nearest") { // @@ -82,23 +135,6 @@ TEST_CASE("rounds_to_nearest") { CHECK(fast_float::detail::rounds_to_nearest() == true); } -const char * round_name(int d) { - switch(d) { - case FE_UPWARD: - return "FE_UPWARD"; - case FE_DOWNWARD: - return "FE_DOWNWARD"; - case FE_TOWARDZERO: - return "FE_TOWARDZERO"; - case FE_TONEAREST: - return "FE_TONEAREST"; - default: - return "UNKNOWN"; - } - -} - - TEST_CASE("parse_zero") { // // If this function fails, we may be left in a non-standard rounding state. @@ -146,6 +182,15 @@ TEST_CASE("parse_zero") { CHECK(float64_parsed == 0); } +// C++ 17 because it is otherwise annoying to browse all files in a directory. +// We also only run these tests on little endian systems. +#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) + +#include +#include +#include + + // return true on success bool check_file(std::string file_name) {