mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Minor cleaning.
This commit is contained in:
parent
2e1d8ba899
commit
288efd35eb
@ -14,9 +14,6 @@
|
||||
|
||||
namespace fast_float {
|
||||
|
||||
|
||||
|
||||
|
||||
// This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
|
||||
// the result, with the "high" part corresponding to the most significant bits and the
|
||||
// low part corresponding to the least significant bits.
|
||||
|
||||
@ -3,10 +3,6 @@
|
||||
|
||||
#include <cfloat>
|
||||
#include <cstdint>
|
||||
#ifndef _WIN32
|
||||
// strcasecmp, strncasecmp
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define FASTFLOAT_VISUAL_STUDIO 1
|
||||
@ -21,7 +17,8 @@
|
||||
namespace fast_float {
|
||||
|
||||
// Compares two ASCII strings in a case insensitive manner.
|
||||
inline bool fastfloat_strncasecmp(const char * input1, const char * input2, size_t length) {
|
||||
inline bool fastfloat_strncasecmp(const char *input1, const char *input2,
|
||||
size_t length) {
|
||||
char running_diff{0};
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
running_diff |= (input1[i] ^ input2[i]);
|
||||
@ -33,13 +30,19 @@ inline bool fastfloat_strncasecmp(const char * input1, const char * input2, size
|
||||
#error "FLT_EVAL_METHOD should be defined, please include cfloat."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool is_space(uint8_t c) {
|
||||
static const bool table[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static const bool table[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
return table[c];
|
||||
}
|
||||
|
||||
@ -49,7 +52,6 @@ constexpr uint32_t max_digit_without_overflow = 19;
|
||||
constexpr int32_t decimal_point_range = 2047;
|
||||
} // namespace
|
||||
|
||||
|
||||
struct value128 {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
@ -57,10 +59,8 @@ struct value128 {
|
||||
value128() : low(0), high(0) {}
|
||||
};
|
||||
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
fastfloat_really_inline
|
||||
int leading_zeroes(uint64_t input_num) {
|
||||
fastfloat_really_inline int leading_zeroes(uint64_t input_num) {
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
unsigned long leading_zero = 0;
|
||||
// Search the mask data from most significant bit (MSB)
|
||||
@ -74,7 +74,6 @@ int leading_zeroes(uint64_t input_num) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN32) && !defined(__clang__)
|
||||
// Note MinGW falls here too
|
||||
#include <intrin.h>
|
||||
@ -85,7 +84,8 @@ int leading_zeroes(uint64_t input_num) {
|
||||
fastfloat_really_inline uint64_t __emulu(uint32_t x, uint32_t y) {
|
||||
return x * (uint64_t)y;
|
||||
}
|
||||
fastfloat_really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
|
||||
fastfloat_really_inline uint64_t _umul128(uint64_t ab, uint64_t cd,
|
||||
uint64_t *hi) {
|
||||
uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd);
|
||||
uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd);
|
||||
uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32));
|
||||
@ -97,14 +97,16 @@ fastfloat_really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi
|
||||
}
|
||||
#endif
|
||||
|
||||
fastfloat_really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
|
||||
fastfloat_really_inline value128 full_multiplication(uint64_t value1,
|
||||
uint64_t value2) {
|
||||
value128 answer;
|
||||
#ifdef _M_ARM64
|
||||
// ARM64 has native support for 64-bit multiplications, no need to emultate
|
||||
answer.high = __umulh(value1, value2);
|
||||
answer.low = value1 * value2;
|
||||
#else
|
||||
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
|
||||
answer.low =
|
||||
_umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
|
||||
#endif // _M_ARM64
|
||||
return answer;
|
||||
}
|
||||
@ -112,8 +114,8 @@ fastfloat_really_inline value128 full_multiplication(uint64_t value1, uint64_t v
|
||||
#else
|
||||
|
||||
// compute value1 * value2
|
||||
fastfloat_really_inline
|
||||
value128 full_multiplication(uint64_t value1, uint64_t value2) {
|
||||
fastfloat_really_inline value128 full_multiplication(uint64_t value1,
|
||||
uint64_t value2) {
|
||||
value128 answer;
|
||||
__uint128_t r = ((__uint128_t)value1) * value2;
|
||||
answer.low = uint64_t(r);
|
||||
@ -156,14 +158,17 @@ struct decimal {
|
||||
::memcpy(&val, digits, sizeof(uint64_t));
|
||||
val = val * 2561 >> 8;
|
||||
val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16;
|
||||
uint64_t mantissa = uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32);
|
||||
uint64_t mantissa =
|
||||
uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32);
|
||||
// 8 more digits for a total of 16
|
||||
::memcpy(&val, digits + sizeof(uint64_t), sizeof(uint64_t));
|
||||
val = val * 2561 >> 8;
|
||||
val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16;
|
||||
uint32_t eight_digits_value = uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32);
|
||||
uint32_t eight_digits_value =
|
||||
uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32);
|
||||
mantissa = 100000000 * mantissa + eight_digits_value;
|
||||
for(uint32_t i = 2*sizeof(uint64_t); i < max_digit_without_overflow; i++) {
|
||||
for (uint32_t i = 2 * sizeof(uint64_t); i < max_digit_without_overflow;
|
||||
i++) {
|
||||
mantissa = mantissa * 10 + digits[i]; // can be accelerated
|
||||
}
|
||||
return mantissa;
|
||||
@ -172,17 +177,15 @@ struct decimal {
|
||||
inline int32_t to_truncated_exponent() {
|
||||
return decimal_point - max_digit_without_overflow;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
constexpr static double powers_of_ten_double[] = {
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
|
||||
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
|
||||
constexpr static float powers_of_ten_float[] = {
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10};
|
||||
constexpr static float powers_of_ten_float[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5,
|
||||
1e6, 1e7, 1e8, 1e9, 1e10};
|
||||
|
||||
template <typename T>
|
||||
struct binary_format {
|
||||
template <typename T> struct binary_format {
|
||||
static constexpr int mantissa_explicit_bits();
|
||||
static constexpr int minimum_exponent();
|
||||
static constexpr int infinite_power();
|
||||
@ -195,73 +198,54 @@ struct binary_format {
|
||||
static constexpr T exact_power_of_ten(int64_t power);
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::mantissa_explicit_bits() {
|
||||
template <> constexpr int binary_format<double>::mantissa_explicit_bits() {
|
||||
return 52;
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::mantissa_explicit_bits() {
|
||||
template <> constexpr int binary_format<float>::mantissa_explicit_bits() {
|
||||
return 23;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::max_exponent_round_to_even() {
|
||||
template <> constexpr int binary_format<double>::max_exponent_round_to_even() {
|
||||
return 23;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<float>::max_exponent_round_to_even() {
|
||||
template <> constexpr int binary_format<float>::max_exponent_round_to_even() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::min_exponent_round_to_even() {
|
||||
template <> constexpr int binary_format<double>::min_exponent_round_to_even() {
|
||||
return -4;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<float>::min_exponent_round_to_even() {
|
||||
template <> constexpr int binary_format<float>::min_exponent_round_to_even() {
|
||||
return -17;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::minimum_exponent() {
|
||||
template <> constexpr int binary_format<double>::minimum_exponent() {
|
||||
return -1023;
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::minimum_exponent() {
|
||||
template <> constexpr int binary_format<float>::minimum_exponent() {
|
||||
return -127;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::infinite_power() {
|
||||
template <> constexpr int binary_format<double>::infinite_power() {
|
||||
return 0x7FF;
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::infinite_power() {
|
||||
template <> constexpr int binary_format<float>::infinite_power() {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::sign_index() {
|
||||
return 63;
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::sign_index() {
|
||||
return 31;
|
||||
}
|
||||
template <> constexpr int binary_format<double>::sign_index() { return 63; }
|
||||
template <> constexpr int binary_format<float>::sign_index() { return 31; }
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::min_exponent_fast_path() {
|
||||
template <> constexpr int binary_format<double>::min_exponent_fast_path() {
|
||||
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||
return 0;
|
||||
#else
|
||||
return -22;
|
||||
#endif
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::min_exponent_fast_path() {
|
||||
template <> constexpr int binary_format<float>::min_exponent_fast_path() {
|
||||
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||
return 0;
|
||||
#else
|
||||
@ -269,23 +253,17 @@ constexpr int binary_format<float>::min_exponent_fast_path() {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
constexpr int binary_format<double>::max_exponent_fast_path() {
|
||||
template <> constexpr int binary_format<double>::max_exponent_fast_path() {
|
||||
return 22;
|
||||
}
|
||||
template <>
|
||||
constexpr int binary_format<float>::max_exponent_fast_path() {
|
||||
template <> constexpr int binary_format<float>::max_exponent_fast_path() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
|
||||
template <> constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
|
||||
return uint64_t(2) << mantissa_explicit_bits();
|
||||
}
|
||||
template <>
|
||||
constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
|
||||
template <> constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
|
||||
return uint64_t(2) << mantissa_explicit_bits();
|
||||
}
|
||||
|
||||
@ -299,15 +277,15 @@ constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
|
||||
return powers_of_ten_float[power];
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace fast_float
|
||||
|
||||
// for convenience:
|
||||
#include <ostream>
|
||||
std::ostream &operator<<(std::ostream &out, const fast_float::decimal &d) {
|
||||
out << "0.";
|
||||
for(size_t i = 0; i < d.num_digits; i++) { out << int32_t(d.digits[i]); }
|
||||
for (size_t i = 0; i < d.num_digits; i++) {
|
||||
out << int32_t(d.digits[i]);
|
||||
}
|
||||
out << " * 10 ** " << d.decimal_point;
|
||||
return out;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user