mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Tuning.
This commit is contained in:
parent
dc7349eb91
commit
38fbe0c8e6
@ -31,4 +31,4 @@ endif()
|
||||
if(FASTFLOAT_TEST)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif(FASTFLOAT_SANITIZE)
|
||||
endif(FASTFLOAT_TEST)
|
||||
@ -14,4 +14,4 @@ fast_float_add_cpp_test(long_exhaustive32_64)
|
||||
fast_float_add_cpp_test(long_random64)
|
||||
fast_float_add_cpp_test(random64)
|
||||
fast_float_add_cpp_test(basictest)
|
||||
fast_float_add_cpp_test(example_test)
|
||||
fast_float_add_cpp_test(example_test)
|
||||
@ -185,25 +185,25 @@ int main() {
|
||||
Assert(basic_test_32bit("50.811574935913086",50.811574935913086f));
|
||||
Assert(basic_test_32bit("17.486443519592285",17.486443519592285f));
|
||||
Assert(basic_test_32bit("13.91745138168335",13.91745138168335f));
|
||||
Assert(basic_test_32bit("7.5464513301849365",7.5464513301849365f));
|
||||
Assert(basic_test_32bit("7.5464513301849365",0x1.e2f90ep+2f));
|
||||
Assert(basic_test_32bit("2.687217116355896",2.687217116355896f));
|
||||
Assert(basic_test_32bit("1.1877630352973938",1.1877630352973938f));
|
||||
Assert(basic_test_32bit("1.1877630352973938",0x1.30113ep+0f));
|
||||
Assert(basic_test_32bit("0.7622503340244293",0.7622503340244293f));
|
||||
Assert(basic_test_32bit("0.30531780421733856",0.30531780421733856f));
|
||||
Assert(basic_test_32bit("0.21791061013936996",0.21791061013936996f));
|
||||
Assert(basic_test_32bit("0.09289376810193062",0.09289376810193062f));
|
||||
Assert(basic_test_32bit("0.30531780421733856",0x1.38a53ap-2f));
|
||||
Assert(basic_test_32bit("0.21791061013936996",0x1.be47eap-3f));
|
||||
Assert(basic_test_32bit("0.09289376810193062",0x1.7c7e2ep-4f));
|
||||
Assert(basic_test_32bit("0.03706067614257336",0.03706067614257336f));
|
||||
Assert(basic_test_32bit("0.028068351559340954",0.028068351559340954f));
|
||||
Assert(basic_test_32bit("0.012114629615098238",0.012114629615098238f));
|
||||
Assert(basic_test_32bit("0.004221370676532388",0.004221370676532388f));
|
||||
Assert(basic_test_32bit("0.012114629615098238",0x1.8cf8e2p-7f));
|
||||
Assert(basic_test_32bit("0.004221370676532388",0x1.14a6dap-8f));
|
||||
Assert(basic_test_32bit("0.002153817447833717",0.002153817447833717f));
|
||||
Assert(basic_test_32bit("0.0015924838953651488",0.0015924838953651488f));
|
||||
Assert(basic_test_32bit("0.0015924838953651488",0x1.a175cap-10f));
|
||||
Assert(basic_test_32bit("0.0008602388261351734",0.0008602388261351734f));
|
||||
Assert(basic_test_32bit("0.00036393293703440577",0.00036393293703440577f));
|
||||
Assert(basic_test_32bit("0.00036393293703440577",0x1.7d9c82p-12f));
|
||||
Assert(basic_test_32bit("0.00013746770127909258",0.00013746770127909258));
|
||||
Assert(basic_test_32bit("16407.9462890625", 16407.9462890625f));
|
||||
Assert(basic_test_32bit("1.1754947011469036e-38", 1.1754947011469036e-38f));
|
||||
Assert(basic_test_32bit("7.0064923216240854e-46", 7.0064923216240854e-46f));
|
||||
Assert(basic_test_32bit("1.1754947011469036e-38", 0x1.000006p-126f));
|
||||
Assert(basic_test_32bit("7.0064923216240854e-46", 0x1p-149f));
|
||||
Assert(basic_test_32bit("8388614.5", 8388614.5f));
|
||||
Assert(basic_test_32bit("0e9999999999999999999999999999", 0));
|
||||
Assert(basic_test_32bit("1234456789012345678901234567890e9999999999999999999999999999", std::numeric_limits<float>::infinity()));
|
||||
@ -218,9 +218,9 @@ int main() {
|
||||
Assert(basic_test_32bit(1.4012984643e-45f));
|
||||
Assert(basic_test_32bit(1.1754942107e-38f));
|
||||
Assert(basic_test_32bit(1.1754943508e-45f));
|
||||
Assert(basic_test_32bit(3.4028234664e38f));
|
||||
Assert(basic_test_32bit(3.4028234665e38f));
|
||||
Assert(basic_test_32bit(3.4028234666e38f));
|
||||
Assert(basic_test_32bit("3.4028234664e38", 0x1.fffffep+127f));
|
||||
Assert(basic_test_32bit("3.4028234665e38", 0x1.fffffep+127f));
|
||||
Assert(basic_test_32bit("3.4028234666e38", 0x1.fffffep+127f));
|
||||
Assert(basic_test_32bit("0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625", 0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625));
|
||||
Assert(basic_test_32bit("0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125", 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125));
|
||||
Assert(basic_test_32bit("0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875", 0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875));
|
||||
|
||||
@ -10,7 +10,7 @@ template <typename T> char *to_string(T d, char *buffer) {
|
||||
return buffer + written;
|
||||
}
|
||||
|
||||
static __uint128_t g_lehmer64_state;
|
||||
static fast_float::value128 g_lehmer64_state;
|
||||
|
||||
/**
|
||||
* D. H. Lehmer, Mathematical methods in large-scale computing units.
|
||||
@ -24,11 +24,16 @@ static __uint128_t g_lehmer64_state;
|
||||
* Society 68.225 (1999): 249-260.
|
||||
*/
|
||||
|
||||
static inline void lehmer64_seed(uint64_t seed) { g_lehmer64_state = seed; }
|
||||
static inline void lehmer64_seed(uint64_t seed) {
|
||||
g_lehmer64_state.high = 0;
|
||||
g_lehmer64_state.low = seed;
|
||||
}
|
||||
|
||||
static inline uint64_t lehmer64() {
|
||||
g_lehmer64_state *= UINT64_C(0xda942042e4dd58b5);
|
||||
return uint64_t(g_lehmer64_state >> 64);
|
||||
fast_float::value128 v = fast_float::full_multiplication(g_lehmer64_state.low,UINT64_C(0xda942042e4dd58b5));
|
||||
v.high += g_lehmer64_state.high * UINT64_C(0xda942042e4dd58b5);
|
||||
g_lehmer64_state = v;
|
||||
return v.high;
|
||||
}
|
||||
|
||||
size_t errors;
|
||||
|
||||
@ -10,7 +10,8 @@ template <typename T> char *to_string(T d, char *buffer) {
|
||||
return buffer + written;
|
||||
}
|
||||
|
||||
static __uint128_t g_lehmer64_state;
|
||||
|
||||
static fast_float::value128 g_lehmer64_state;
|
||||
|
||||
/**
|
||||
* D. H. Lehmer, Mathematical methods in large-scale computing units.
|
||||
@ -24,11 +25,16 @@ static __uint128_t g_lehmer64_state;
|
||||
* Society 68.225 (1999): 249-260.
|
||||
*/
|
||||
|
||||
static inline void lehmer64_seed(uint64_t seed) { g_lehmer64_state = seed; }
|
||||
static inline void lehmer64_seed(uint64_t seed) {
|
||||
g_lehmer64_state.high = 0;
|
||||
g_lehmer64_state.low = seed;
|
||||
}
|
||||
|
||||
static inline uint64_t lehmer64() {
|
||||
g_lehmer64_state *= UINT64_C(0xda942042e4dd58b5);
|
||||
return uint64_t(g_lehmer64_state >> 64);
|
||||
fast_float::value128 v = fast_float::full_multiplication(g_lehmer64_state.low,UINT64_C(0xda942042e4dd58b5));
|
||||
v.high += g_lehmer64_state.high * UINT64_C(0xda942042e4dd58b5);
|
||||
g_lehmer64_state = v;
|
||||
return v.high;
|
||||
}
|
||||
|
||||
size_t errors;
|
||||
|
||||
@ -11,11 +11,10 @@ public:
|
||||
// Inspired from
|
||||
// https://github.com/lemire/testingRNG/blob/master/source/wyhash.h
|
||||
wyhash64_x_ += UINT64_C(0x60bee2bee120fc15);
|
||||
__uint128_t tmp;
|
||||
tmp = (__uint128_t)wyhash64_x_ * UINT64_C(0xa3b195354a39b70d);
|
||||
uint64_t m1 = (tmp >> 64) ^ tmp;
|
||||
tmp = (__uint128_t)m1 * UINT64_C(0x1b03738712fad5c9);
|
||||
uint64_t m2 = (tmp >> 64) ^ tmp;
|
||||
fast_float::value128 tmp = fast_float::full_multiplication(wyhash64_x_, UINT64_C(0xa3b195354a39b70d));
|
||||
uint64_t m1 = (tmp.high) ^ tmp.low;
|
||||
tmp = fast_float::full_multiplication(m1, UINT64_C(0x1b03738712fad5c9));
|
||||
uint64_t m2 = (tmp.high) ^ tmp.low;
|
||||
return m2;
|
||||
}
|
||||
bool next_bool() { return (next() & 1) == 1; }
|
||||
@ -31,17 +30,17 @@ public:
|
||||
}*/
|
||||
int s = max - min + 1;
|
||||
uint64_t x = next();
|
||||
__uint128_t m = (__uint128_t)x * (__uint128_t)s;
|
||||
uint64_t l = (uint64_t)m;
|
||||
fast_float::value128 m = fast_float::full_multiplication(x, s);
|
||||
uint64_t l = m.low;
|
||||
if (l < s) {
|
||||
uint64_t t = -s % s;
|
||||
while (l < t) {
|
||||
x = next();
|
||||
m = (__uint128_t)x * (__uint128_t)s;
|
||||
l = (uint64_t)m;
|
||||
m = fast_float::full_multiplication(x, s);
|
||||
l = m.low;
|
||||
}
|
||||
}
|
||||
return (m >> 64) + min;
|
||||
return (m.high) + min;
|
||||
}
|
||||
int next_digit() { return next_ranged_int(0, 9); }
|
||||
|
||||
@ -113,7 +112,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
|
||||
#endif
|
||||
if (st == pr) {
|
||||
std::cerr << "strtof_l could not parse '" << st << std::endl;
|
||||
return std::make_pair(0, false);
|
||||
return std::make_pair(0.0f, false);
|
||||
}
|
||||
return std::make_pair(d, true);
|
||||
}
|
||||
|
||||
122
tests/test.cpp
122
tests/test.cpp
@ -1,122 +0,0 @@
|
||||
#include "fast_float/fast_float.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
inline void Assert(bool Assertion) {
|
||||
if (!Assertion)
|
||||
throw std::runtime_error("bug");
|
||||
}
|
||||
|
||||
template <typename T> std::string to_string(T d) {
|
||||
std::string s(64, '\0');
|
||||
auto written = std::snprintf(&s[0], s.size(), "%.*e",
|
||||
std::numeric_limits<T>::max_digits10 - 1, d);
|
||||
s.resize(written);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool demo32(std::string vals) {
|
||||
float result_value;
|
||||
auto result = fast_float::from_chars(vals.data(), vals.data() + vals.size(),
|
||||
result_value);
|
||||
if (result.ec != std::errc()) {
|
||||
std::cerr << " I could not parse " << vals << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << result_value << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool demo32(std::string vals, float val) {
|
||||
float result_value;
|
||||
auto result = fast_float::from_chars(vals.data(), vals.data() + vals.size(),
|
||||
result_value);
|
||||
if (result.ec != std::errc()) {
|
||||
std::cerr << " I could not parse " << vals << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (std::isnan(val)) {
|
||||
if (!std::isnan(result_value)) {
|
||||
std::cerr << "not nan" << result_value << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else if (result_value != val) {
|
||||
std::cerr << "I got " << std::setprecision(15) << result_value << " but I was expecting " << val
|
||||
<< std::endl;
|
||||
uint32_t word;
|
||||
memcpy(&word, &result_value, sizeof(word));
|
||||
std::cout << "got mantissa = " << (word & ((1<<23)-1)) << std::endl;
|
||||
memcpy(&word, &val, sizeof(word));
|
||||
std::cout << "wanted mantissa = " << (word & ((1<<23)-1)) << std::endl;
|
||||
std::cerr << "string: " << vals << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << result_value << " == " << val << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool demo32(float val) {
|
||||
std::string vals = to_string(val);
|
||||
return demo32(vals, val);
|
||||
}
|
||||
|
||||
bool demo64(std::string vals, double val) {
|
||||
double result_value;
|
||||
auto result = fast_float::from_chars(vals.data(), vals.data() + vals.size(),
|
||||
result_value);
|
||||
if (result.ec != std::errc()) {
|
||||
std::cerr << " I could not parse " << vals << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (std::isnan(val)) {
|
||||
if (!std::isnan(result_value)) {
|
||||
std::cerr << "not nan" << result_value << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else if (result_value != val) {
|
||||
std::cerr << "I got " << std::setprecision(15) << result_value << " but I was expecting " << val
|
||||
<< std::endl;
|
||||
std::cerr << "string: " << vals << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << result_value << " == " << val << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool demo64(double val) {
|
||||
std::string vals = to_string(val);
|
||||
return demo64(vals, val);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "32 bits " << std::endl;
|
||||
Assert(demo64("+1", 1));
|
||||
Assert(demo64("2e3000", std::numeric_limits<float>::infinity()));
|
||||
Assert(demo32("3.5028234666e38", std::numeric_limits<float>::infinity()));
|
||||
Assert(demo32("7.0060e-46", 0));
|
||||
Assert(demo32(1.00000006e+09f));
|
||||
Assert(demo32(1.4012984643e-45f));
|
||||
Assert(demo32(1.1754942107e-38f));
|
||||
Assert(demo32(1.1754943508e-45f));
|
||||
Assert(demo32(3.4028234664e38f));
|
||||
Assert(demo32(3.4028234665e38f));
|
||||
Assert(demo32(3.4028234666e38f));
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "64 bits " << std::endl;
|
||||
Assert(demo64("+1", 1));
|
||||
Assert(demo64("2e3000", std::numeric_limits<double>::infinity()));
|
||||
Assert(demo64("1.9e308", std::numeric_limits<double>::infinity()));
|
||||
Assert(demo64(3e-324));
|
||||
Assert(demo32(1.00000006e+09f));
|
||||
Assert(demo64(4.9406564584124653e-324));
|
||||
Assert(demo64(4.9406564584124654e-324));
|
||||
Assert(demo64(2.2250738585072009e-308));
|
||||
Assert(demo64(2.2250738585072014e-308));
|
||||
Assert(demo64(1.7976931348623157e308));
|
||||
Assert(demo64(1.7976931348623158e308));
|
||||
std::cout << std::endl;
|
||||
std::cout << "All ok" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user