From 8a04a06a88997c624a746eaf81c0b6e9e183884b Mon Sep 17 00:00:00 2001 From: Joao Paulo Magalhaes Date: Thu, 19 Nov 2020 22:55:48 +0000 Subject: [PATCH] leading_zeroes(): 0 is not a valid input --- include/fast_float/float_common.h | 30 ++++++++++++++---------------- tests/basictest.cpp | 1 - 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 2c0c18e..0f17329 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -3,6 +3,7 @@ #include #include +#include #if defined(_MSC_VER) && !defined(__clang__) #define FASTFLOAT_VISUAL_STUDIO 1 @@ -89,26 +90,23 @@ struct value128 { /* result might be undefined when input_num is zero */ fastfloat_really_inline int leading_zeroes(uint64_t input_num) { + assert(input_num > 0); #ifdef FASTFLOAT_VISUAL_STUDIO -#if defined(_M_X64) || defined(_M_ARM64) + #if defined(_M_X64) || defined(_M_ARM64) unsigned long leading_zero = 0; // Search the mask data from most significant bit (MSB) // to least significant bit (LSB) for a set bit (1). - if (_BitScanReverse64(&leading_zero, input_num)) - return (int)(63 - leading_zero); - else - return 64; -#else - if(!input_num) return 64; - int n = 0; - if(input_num & uint64_t(0xffffffff00000000)) input_num >>= 32, n |= 32; - if(input_num & uint64_t( 0xffff0000)) input_num >>= 16, n |= 16; - if(input_num & uint64_t( 0xff00)) input_num >>= 8, n |= 8; - if(input_num & uint64_t( 0xf0)) input_num >>= 4, n |= 4; - if(input_num & uint64_t( 0xc)) input_num >>= 2, n |= 2; - if(input_num & uint64_t( 0x2)) input_num >>= 1, n |= 1; - return 63 - n; -#endif + return (int)(_BitScanReverse64(&leading_zero, input_num) - leading_zero); + #else + int n = 0; + if(input_num & uint64_t(0xffffffff00000000)) input_num >>= 32, n |= 32; + if(input_num & uint64_t( 0xffff0000)) input_num >>= 16, n |= 16; + if(input_num & uint64_t( 0xff00)) input_num >>= 8, n |= 8; + if(input_num & uint64_t( 0xf0)) input_num >>= 4, n |= 4; + if(input_num & uint64_t( 0xc)) input_num >>= 2, n |= 2; + if(input_num & uint64_t( 0x2)) input_num >>= 1, n |= 1; + return 63 - n; + #endif #else return __builtin_clzll(input_num); #endif diff --git a/tests/basictest.cpp b/tests/basictest.cpp index fc42681..a2f3110 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -7,7 +7,6 @@ TEST_CASE("leading_zeroes") { constexpr const uint64_t bit = 1; - CHECK(fast_float::leading_zeroes(0) == 64); CHECK(fast_float::leading_zeroes(bit << 0) == 63); CHECK(fast_float::leading_zeroes(bit << 1) == 62); CHECK(fast_float::leading_zeroes(bit << 2) == 61);