Merge pull request #1 from lemire/dlemire/adding_actions

Actions added.
This commit is contained in:
Daniel Lemire 2020-10-19 14:42:39 -04:00 committed by GitHub
commit 25cfdf5552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 111 additions and 158 deletions

20
.github/workflows/ubuntu18.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Ubuntu 18.04 CI (GCC 7)
on: [push, pull_request]
jobs:
ubuntu-build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.0
with:
cmake-version: '3.9.x'
- name: Use cmake
run: |
mkdir build &&
cd build &&
cmake -DFASTFLOAT_TEST=ON .. &&
cmake --build . &&
ctest --output-on-failure -R basictest

20
.github/workflows/ubuntu20.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Ubuntu 20.04 CI (GCC 9)
on: [push, pull_request]
jobs:
ubuntu-build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.0
with:
cmake-version: '3.9.x'
- name: Use cmake
run: |
mkdir build &&
cd build &&
cmake -DFASTFLOAT_TEST=ON .. &&
cmake --build . &&
ctest --output-on-failure -R basictest

25
.github/workflows/vs16-ci.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: VS16-CI
on: [push, pull_request]
jobs:
ci:
name: windows-vs16
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: 'Run CMake with VS16'
uses: lukka/run-cmake@v2
with:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
buildDirectory: "${{ github.workspace }}/../../_temp/windows"
cmakeBuildType: Release
buildWithCMake: true
cmakeGenerator: VS16Win64
cmakeAppendedArgs: -DFASTFLOAT_TEST=ON
buildWithCMakeArgs: --config Release
- name: 'Run CTest'
run: ctest -C Release --output-on-failure -R basictest
working-directory: "${{ github.workspace }}/../../_temp/windows"

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.9)
project(fast_float VERSION 0.1.0 LANGUAGES CXX) project(fast_float VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@ -31,4 +31,4 @@ endif()
if(FASTFLOAT_TEST) if(FASTFLOAT_TEST)
enable_testing() enable_testing()
add_subdirectory(tests) add_subdirectory(tests)
endif(FASTFLOAT_SANITIZE) endif(FASTFLOAT_TEST)

View File

@ -14,4 +14,4 @@ fast_float_add_cpp_test(long_exhaustive32_64)
fast_float_add_cpp_test(long_random64) fast_float_add_cpp_test(long_random64)
fast_float_add_cpp_test(random64) fast_float_add_cpp_test(random64)
fast_float_add_cpp_test(basictest) fast_float_add_cpp_test(basictest)
fast_float_add_cpp_test(example_test) fast_float_add_cpp_test(example_test)

View File

@ -185,25 +185,25 @@ int main() {
Assert(basic_test_32bit("50.811574935913086",50.811574935913086f)); Assert(basic_test_32bit("50.811574935913086",50.811574935913086f));
Assert(basic_test_32bit("17.486443519592285",17.486443519592285f)); Assert(basic_test_32bit("17.486443519592285",17.486443519592285f));
Assert(basic_test_32bit("13.91745138168335",13.91745138168335f)); 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("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.7622503340244293",0.7622503340244293f));
Assert(basic_test_32bit("0.30531780421733856",0.30531780421733856f)); Assert(basic_test_32bit("0.30531780421733856",0x1.38a53ap-2f));
Assert(basic_test_32bit("0.21791061013936996",0.21791061013936996f)); Assert(basic_test_32bit("0.21791061013936996",0x1.be47eap-3f));
Assert(basic_test_32bit("0.09289376810193062",0.09289376810193062f)); Assert(basic_test_32bit("0.09289376810193062",0x1.7c7e2ep-4f));
Assert(basic_test_32bit("0.03706067614257336",0.03706067614257336f)); Assert(basic_test_32bit("0.03706067614257336",0.03706067614257336f));
Assert(basic_test_32bit("0.028068351559340954",0.028068351559340954f)); Assert(basic_test_32bit("0.028068351559340954",0.028068351559340954f));
Assert(basic_test_32bit("0.012114629615098238",0.012114629615098238f)); Assert(basic_test_32bit("0.012114629615098238",0x1.8cf8e2p-7f));
Assert(basic_test_32bit("0.004221370676532388",0.004221370676532388f)); Assert(basic_test_32bit("0.004221370676532388",0x1.14a6dap-8f));
Assert(basic_test_32bit("0.002153817447833717",0.002153817447833717f)); 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.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("0.00013746770127909258",0.00013746770127909258));
Assert(basic_test_32bit("16407.9462890625", 16407.9462890625f)); Assert(basic_test_32bit("16407.9462890625", 16407.9462890625f));
Assert(basic_test_32bit("1.1754947011469036e-38", 1.1754947011469036e-38f)); Assert(basic_test_32bit("1.1754947011469036e-38", 0x1.000006p-126f));
Assert(basic_test_32bit("7.0064923216240854e-46", 7.0064923216240854e-46f)); Assert(basic_test_32bit("7.0064923216240854e-46", 0x1p-149f));
Assert(basic_test_32bit("8388614.5", 8388614.5f)); Assert(basic_test_32bit("8388614.5", 8388614.5f));
Assert(basic_test_32bit("0e9999999999999999999999999999", 0)); Assert(basic_test_32bit("0e9999999999999999999999999999", 0));
Assert(basic_test_32bit("1234456789012345678901234567890e9999999999999999999999999999", std::numeric_limits<float>::infinity())); 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.4012984643e-45f));
Assert(basic_test_32bit(1.1754942107e-38f)); Assert(basic_test_32bit(1.1754942107e-38f));
Assert(basic_test_32bit(1.1754943508e-45f)); Assert(basic_test_32bit(1.1754943508e-45f));
Assert(basic_test_32bit(3.4028234664e38f)); Assert(basic_test_32bit("3.4028234664e38", 0x1.fffffep+127f));
Assert(basic_test_32bit(3.4028234665e38f)); Assert(basic_test_32bit("3.4028234665e38", 0x1.fffffep+127f));
Assert(basic_test_32bit(3.4028234666e38f)); Assert(basic_test_32bit("3.4028234666e38", 0x1.fffffep+127f));
Assert(basic_test_32bit("0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625", 0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625)); Assert(basic_test_32bit("0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625", 0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625));
Assert(basic_test_32bit("0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125", 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125)); Assert(basic_test_32bit("0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125", 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125));
Assert(basic_test_32bit("0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875", 0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875)); Assert(basic_test_32bit("0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875", 0.00000000000000000000000000000000000002350988561514728583455765982071533026645717985517980855365926236850006129930346077117064851336181163787841796875));

View File

@ -10,7 +10,7 @@ template <typename T> char *to_string(T d, char *buffer) {
return buffer + written; 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. * 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. * 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() { static inline uint64_t lehmer64() {
g_lehmer64_state *= UINT64_C(0xda942042e4dd58b5); fast_float::value128 v = fast_float::full_multiplication(g_lehmer64_state.low,UINT64_C(0xda942042e4dd58b5));
return uint64_t(g_lehmer64_state >> 64); v.high += g_lehmer64_state.high * UINT64_C(0xda942042e4dd58b5);
g_lehmer64_state = v;
return v.high;
} }
size_t errors; size_t errors;

View File

@ -10,7 +10,8 @@ template <typename T> char *to_string(T d, char *buffer) {
return buffer + written; 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. * 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. * 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() { static inline uint64_t lehmer64() {
g_lehmer64_state *= UINT64_C(0xda942042e4dd58b5); fast_float::value128 v = fast_float::full_multiplication(g_lehmer64_state.low,UINT64_C(0xda942042e4dd58b5));
return uint64_t(g_lehmer64_state >> 64); v.high += g_lehmer64_state.high * UINT64_C(0xda942042e4dd58b5);
g_lehmer64_state = v;
return v.high;
} }
size_t errors; size_t errors;

View File

@ -11,11 +11,10 @@ public:
// Inspired from // Inspired from
// https://github.com/lemire/testingRNG/blob/master/source/wyhash.h // https://github.com/lemire/testingRNG/blob/master/source/wyhash.h
wyhash64_x_ += UINT64_C(0x60bee2bee120fc15); wyhash64_x_ += UINT64_C(0x60bee2bee120fc15);
__uint128_t tmp; fast_float::value128 tmp = fast_float::full_multiplication(wyhash64_x_, UINT64_C(0xa3b195354a39b70d));
tmp = (__uint128_t)wyhash64_x_ * UINT64_C(0xa3b195354a39b70d); uint64_t m1 = (tmp.high) ^ tmp.low;
uint64_t m1 = (tmp >> 64) ^ tmp; tmp = fast_float::full_multiplication(m1, UINT64_C(0x1b03738712fad5c9));
tmp = (__uint128_t)m1 * UINT64_C(0x1b03738712fad5c9); uint64_t m2 = (tmp.high) ^ tmp.low;
uint64_t m2 = (tmp >> 64) ^ tmp;
return m2; return m2;
} }
bool next_bool() { return (next() & 1) == 1; } bool next_bool() { return (next() & 1) == 1; }
@ -31,17 +30,17 @@ public:
}*/ }*/
int s = max - min + 1; int s = max - min + 1;
uint64_t x = next(); uint64_t x = next();
__uint128_t m = (__uint128_t)x * (__uint128_t)s; fast_float::value128 m = fast_float::full_multiplication(x, s);
uint64_t l = (uint64_t)m; uint64_t l = m.low;
if (l < s) { if (l < s) {
uint64_t t = -s % s; uint64_t t = -s % s;
while (l < t) { while (l < t) {
x = next(); x = next();
m = (__uint128_t)x * (__uint128_t)s; m = fast_float::full_multiplication(x, s);
l = (uint64_t)m; l = m.low;
} }
} }
return (m >> 64) + min; return (m.high) + min;
} }
int next_digit() { return next_ranged_int(0, 9); } int next_digit() { return next_ranged_int(0, 9); }
@ -113,7 +112,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
#endif #endif
if (st == pr) { if (st == pr) {
std::cerr << "strtof_l could not parse '" << st << std::endl; 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); return std::make_pair(d, true);
} }

View File

@ -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;
}