More tweaking around clangcl

This commit is contained in:
Daniel Lemire 2022-11-16 15:25:03 -05:00
parent 559b89d34d
commit fd9d9effda
2 changed files with 75 additions and 29 deletions

View File

@ -135,13 +135,14 @@ from_chars_result from_chars_advanced(const char *first, const char *last,
// We do not have that fegetround() == FE_TONEAREST. // We do not have that fegetround() == FE_TONEAREST.
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal // Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal
if (pns.exponent >= 0 && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent) && !pns.too_many_digits) { if (pns.exponent >= 0 && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent) && !pns.too_many_digits) {
#if (defined(_WIN32) && defined(__clang__)) #if (defined(_MSC_VER) && defined(__clang__))
// 32-bit ClangCL maps 0 to -0.0 when fegetround() == FE_DOWNWARD // ClangCL may map 0 to -0.0 when fegetround() == FE_DOWNWARD
value = pns.mantissa ? T(pns.mantissa) : 0.0; if(pns.mantissa == 0) {
#else value = 0;
value = T(pns.mantissa); return answer;
}
#endif #endif
value = value * binary_format<T>::exact_power_of_ten(pns.exponent); value = T(pns.mantissa) * binary_format<T>::exact_power_of_ten(pns.exponent);
if (pns.negative) { value = -value; } if (pns.negative) { value = -value; }
return answer; return answer;
} }

View File

@ -48,13 +48,66 @@
#define fHexAndDec(v) std::hexfloat << (v) << " (" << std::defaultfloat << (v) << ")" #define fHexAndDec(v) std::hexfloat << (v) << " (" << std::defaultfloat << (v) << ")"
// C++ 17 because it is otherwise annoying to browse all files in a directory. const char * round_name(int d) {
// We also only run these tests on little endian systems. switch(d) {
#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) 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 <iostream>
#include <filesystem>
#include <charconv>
TEST_CASE("rounds_to_nearest") { TEST_CASE("rounds_to_nearest") {
// //
@ -82,23 +135,6 @@ TEST_CASE("rounds_to_nearest") {
CHECK(fast_float::detail::rounds_to_nearest() == true); 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") { TEST_CASE("parse_zero") {
// //
// If this function fails, we may be left in a non-standard rounding state. // 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); 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 <iostream>
#include <filesystem>
#include <charconv>
// return true on success // return true on success
bool check_file(std::string file_name) { bool check_file(std::string file_name) {