Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/mingw-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: MinGW32-CI

on: [push, pull_request]

# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both.

# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So
# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL.

jobs:
ci:
name: windows-gcc
runs-on: windows-2016

env:
CMAKE_GENERATOR: Ninja
CC: gcc
CXX: g++

steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea
- uses: actions/checkout@v2

- uses: actions/cache@v2 # we cache the scoop setup with 32-bit GCC
id: cache
with:
path: |
C:\ProgramData\scoop
key: scoop32 # static key: should be good forever
- name: Setup Windows # This should almost never run if the cache works.
if: steps.cache.outputs.cache-hit != 'true'
shell: powershell
run: |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop install sudo --global
sudo scoop install git --global
sudo scoop install ninja --global
sudo scoop install cmake --global
sudo scoop install gcc --arch 32bit --global
$env:path
Write-Host 'Everything has been installed, you are good!'
- name: Build and Test 32-bit x86
shell: powershell
run: |
$ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH"
mkdir build32
cd build32
cmake -DFASTFLOAT_TEST=ON ..
cmake --build . --verbose
ctest -j4 --output-on-failure -R basictest
49 changes: 49 additions & 0 deletions .github/workflows/mingw64-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: MinGW64-CI

on: [push, pull_request]

# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both.

# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So
# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL.

jobs:
ci:
name: windows-gcc
runs-on: windows-2016

env:
CMAKE_GENERATOR: Ninja
CC: gcc
CXX: g++

steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea
- uses: actions/checkout@v2

- uses: actions/cache@v2 # we cache the scoop setup with 64-bit GCC
id: cache
with:
path: |
C:\ProgramData\scoop
key: scoop64 # static key: should be good forever
- name: Setup Windows # This should almost never run if the cache works.
if: steps.cache.outputs.cache-hit != 'true'
shell: powershell
run: |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop install sudo --global
sudo scoop install git --global
sudo scoop install ninja --global
sudo scoop install cmake --global
sudo scoop install gcc --arch 64bit --global
$env:path
Write-Host 'Everything has been installed, you are good!'
- name: Build and Test 64-bit x64
shell: powershell
run: |
$ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH"
mkdir build64
cd build64
cmake -DFASTFLOAT_TEST=ON ..
cmake --build . --verbose
ctest -j4 --output-on-failure -R basictest
39 changes: 39 additions & 0 deletions .github/workflows/msys2-clang.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: MSYS2-CLANG-CI

on: [push, pull_request]

jobs:
windows-mingw:
name: ${{ matrix.msystem }}
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
include:
- msystem: "MINGW64"
install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-clang
type: Release
- msystem: "MINGW32"
install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-clang
type: Release
env:
CMAKE_GENERATOR: Ninja

steps:
- uses: actions/checkout@v2
- uses: msys2/setup-msys2@v2
with:
update: true
msystem: ${{ matrix.msystem }}
install: ${{ matrix.install }}
- name: Prepare build dir
run: mkdir build
- name: Configure
run: cd build && cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DFASTFLOAT_TEST=ON ..
- name: Build
run: cmake --build build
- name: Run basic tests
run: cd build && ctest --output-on-failure -R basictest
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu18.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Setup cmake
uses: jwlawson/[email protected]
with:
cmake-version: '3.9.x'
cmake-version: '3.11.x'
- name: Install older compilers
run: |
sudo -E dpkg --add-architecture i386
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu20.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup cmake
uses: jwlawson/[email protected]
with:
cmake-version: '3.9.x'
cmake-version: '3.11.x'
- name: install older compilers
run: |
sudo -E dpkg --add-architecture i386
Expand Down
14 changes: 7 additions & 7 deletions include/fast_float/float_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
#include <cstdint>
#include <cassert>

#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|| defined(__arm__) \
|| defined(__MINGW32__))
#define FASTFLOAT_32BIT
#elif (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
|| defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
|| defined(__MINGW64__) \
|| defined(__s390x__) \
|| (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)))
#define FASTFLOAT_64BIT
#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|| defined(__arm__) \
|| defined(__MINGW32__))
#define FASTFLOAT_32BIT
#else
#error Unknown platform
#error Unknown platform (not 32-bit, not 64-bit?)
#endif

#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
Expand Down Expand Up @@ -164,7 +164,7 @@ fastfloat_really_inline value128 full_multiplication(uint64_t a,
// ARM64 has native support for 64-bit multiplications, no need to emulate
answer.high = __umulh(a, b);
answer.low = a * b;
#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64))
#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
#elif defined(FASTFLOAT_64BIT)
__uint128_t r = ((__uint128_t)a) * b;
Expand Down
10 changes: 5 additions & 5 deletions tests/exhaustive32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ void allvalues() {
std::cerr << "parsing error ? " << buffer << std::endl;
abort();
}
if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (std::isnan(v)) {
if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl;
abort();
}
} else if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (result_value != v) {
std::cerr << "no match ? " << buffer << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl;
Expand Down
12 changes: 6 additions & 6 deletions tests/exhaustive32_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ bool basic_test_64bit(std::string vals, double val) {
std::cerr << " I could not parse " << vals << std::endl;
return false;
}
if(copysign(1,result_value) != copysign(1,val)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
<< std::endl;
return false;
} else if (std::isnan(val)) {
if (std::isnan(val)) {
if (!std::isnan(result_value)) {
std::cerr << vals << std::endl;
std::cerr << "not nan" << result_value << std::endl;
return false;
}
}
} else if(copysign(1,result_value) != copysign(1,val)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
<< std::endl;
return false;
} else if (result_value != val) {
std::cerr << vals << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
Expand Down
62 changes: 42 additions & 20 deletions tests/exhaustive32_midpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,21 @@ double cygwin_strtod_l(const char* start, char** end) {
ss.imbue(std::locale::classic());
ss << start;
ss >> d;
size_t nread = ss.tellg();
if(ss.fail()) { *end = nullptr; }
if(ss.eof()) { ss.clear(); }
auto nread = ss.tellg();
*end = const_cast<char*>(start) + nread;
return d;
}
float cygwin_strtof_l(const char* start, char** end) {
float d;
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << start;
ss >> d;
if(ss.fail()) { *end = nullptr; }
if(ss.eof()) { ss.clear(); }
auto nread = ss.tellg();
*end = const_cast<char*>(start) + nread;
return d;
}
Expand All @@ -29,10 +43,10 @@ template <typename T> char *to_string(T d, char *buffer) {
return buffer + written;
}

void strtod_from_string(const char * st, float& d) {
void strtof_from_string(const char * st, float& d) {
char *pr = (char *)st;
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
d = cygwin_strtod_l(st, &pr);
d = cygwin_strtof_l(st, &pr);
#elif defined(_WIN32)
static _locale_t c_locale = _create_locale(LC_ALL, "C");
d = _strtof_l(st, &pr, c_locale);
Expand All @@ -45,7 +59,7 @@ void strtod_from_string(const char * st, float& d) {
}
}

void allvalues() {
bool allvalues() {
char buffer[64];
for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
float v;
Expand All @@ -68,32 +82,32 @@ void allvalues() {

const char *string_end = to_string(midv, buffer);
float str_answer;
strtod_from_string(buffer, str_answer);
strtof_from_string(buffer, str_answer);

float result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) {
std::cerr << "parsing error ? " << buffer << std::endl;
abort();
return false;
}
if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << buffer << std::endl;
std::cerr << "v " << std::hexfloat << v << std::endl;
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
std::cerr << "midv " << std::hexfloat << midv << std::endl;
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (std::isnan(v)) {
if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl;
std::cerr << "v " << std::hexfloat << v << std::endl;
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
std::cerr << "midv " << std::hexfloat << midv << std::endl;
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
abort();
return false;
}
} else if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << buffer << std::endl;
std::cerr << "v " << std::hexfloat << v << std::endl;
std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
std::cerr << "midv " << std::hexfloat << midv << std::endl;
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
return false;
} else if (result_value != str_answer) {
std::cerr << "no match ? " << buffer << std::endl;
std::cerr << "v " << std::hexfloat << v << std::endl;
Expand All @@ -104,18 +118,26 @@ void allvalues() {
std::cout << "round down to " << std::hexfloat << str_answer << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec;
abort();
return false;
}
}
}
std::cout << std::endl;
return true;
}

inline void Assert(bool Assertion) {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
if (!Assertion) { std::cerr << "Omitting hard falure on msys/cygwin/sun systems."; }
#else
if (!Assertion) { throw std::runtime_error("bug"); }
#endif
}
int main() {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
std::cout << "Warning: msys/cygwin or solaris detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library as a gold standard." << std::endl;
#endif
allvalues();
Assert(allvalues());
std::cout << std::endl;
std::cout << "all ok" << std::endl;
return EXIT_SUCCESS;
Expand Down
12 changes: 6 additions & 6 deletions tests/long_exhaustive32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ void allvalues() {
std::cerr << "parsing error ? " << buffer << std::endl;
abort();
}
if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << buffer << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (std::isnan(v)) {
if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl;
abort();
}
} else if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << buffer << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (result_value != v) {
std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl;
Expand Down
Loading