Merge pull request #229 from MTahaK/main

Support for float32_t and float64_t
This commit is contained in:
Daniel Lemire 2024-01-28 11:43:54 -05:00 committed by GitHub
commit c7e45fea9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 133 additions and 4 deletions

23
.github/workflows/ubuntu22-gcc13.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: Ubuntu 22.04 CI (GCC 13)
on: [push, pull_request]
jobs:
ubuntu-build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Use cmake
run: |
mkdir build &&
cd build &&
CXX=g++-13 CXXFLAGS=-Werror cmake -DFASTFLOAT_TEST=ON .. &&
cmake --build . &&
ctest --output-on-failure
- name: Use cmake CXX23
run: |
mkdir build20 &&
cd build20 &&
CXX=g++-13 CXXFLAGS=-Werror cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON -DFASTFLOAT_FIXEDWIDTH_TESTS=ON -DFASTFLOAT_CXX_STANDARD=23 -DFASTFLOAT_TEST=ON .. &&
cmake --build . &&
ctest --output-on-failure

View File

@ -7,3 +7,4 @@ Fabio Pellacini
Lénárd Szolnoki Lénárd Szolnoki
Jan Pharago Jan Pharago
Maya Warrier Maya Warrier
Taha Khokhar

View File

@ -10,7 +10,11 @@
#include <cstring> #include <cstring>
#include <limits> #include <limits>
#include <system_error> #include <system_error>
#ifdef __has_include
#if __has_include(<stdfloat>)
#include <stdfloat>
#endif
#endif
namespace fast_float { namespace fast_float {
@ -133,11 +137,58 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
} // namespace detail } // namespace detail
template<typename T, typename UC, typename> template <typename T>
FASTFLOAT_CONSTEXPR20 struct from_chars_caller
{
template <typename UC>
FASTFLOAT_CONSTEXPR20
static from_chars_result_t<UC> call(UC const * first, UC const * last,
T &value, parse_options_t<UC> options) noexcept {
return from_chars_advanced(first, last, value, options);
}
};
#if __STDCPP_FLOAT32_T__ == 1
template <>
struct from_chars_caller<std::float32_t>
{
template <typename UC>
FASTFLOAT_CONSTEXPR20
static from_chars_result_t<UC> call(UC const * first, UC const * last,
std::float32_t &value, parse_options_t<UC> options) noexcept{
// if std::float32_t is defined, and we are in C++23 mode; macro set for float32;
// set value to float due to equivalence between float and float32_t
float val;
auto ret = from_chars_advanced(first, last, val, options);
value = val;
return ret;
}
};
#endif
#if __STDCPP_FLOAT64_T__ == 1
template <>
struct from_chars_caller<std::float64_t>
{
template <typename UC>
FASTFLOAT_CONSTEXPR20
static from_chars_result_t<UC> call(UC const * first, UC const * last,
std::float64_t &value, parse_options_t<UC> options) noexcept{
// if std::float64_t is defined, and we are in C++23 mode; macro set for float64;
// set value as double due to equivalence between double and float64_t
double val;
auto ret = from_chars_advanced(first, last, val, options);
value = val;
return ret;
}
};
#endif
template<typename T, typename UC>
from_chars_result_t<UC> from_chars(UC const * first, UC const * last, from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
T &value, chars_format fmt /*= chars_format::general*/) noexcept { T &value, chars_format fmt /*= chars_format::general*/) noexcept {
return from_chars_advanced(first, last, value, parse_options_t<UC>{fmt}); return from_chars_caller<T>::call(first, last, value, parse_options_t<UC>(fmt));
} }
template<typename T, typename UC> template<typename T, typename UC>

View File

@ -85,6 +85,12 @@ target_compile_features(fast_int PRIVATE cxx_std_17)
fast_float_add_cpp_test(json_fmt) fast_float_add_cpp_test(json_fmt)
fast_float_add_cpp_test(fortran) fast_float_add_cpp_test(fortran)
option(FASTFLOAT_FIXEDWIDTH_TESTS "Require fixed width test for C++23 (build will fail if the compiler won't support it)" OFF)
if (FASTFLOAT_FIXEDWIDTH_TESTS)
fast_float_add_cpp_test(fixedwidthtest)
target_compile_features(fixedwidthtest PRIVATE cxx_std_23)
endif()
option(FASTFLOAT_EXHAUSTIVE "Exhaustive tests" OFF) option(FASTFLOAT_EXHAUSTIVE "Exhaustive tests" OFF)
if (FASTFLOAT_EXHAUSTIVE) if (FASTFLOAT_EXHAUSTIVE)

48
tests/fixedwidthtest.cpp Normal file
View File

@ -0,0 +1,48 @@
#include <cstdlib>
#include <iostream>
#include <vector>
#include <iomanip>
#include <cstring>
#include "fast_float/fast_float.h"
#include <cstdint>
#include <stdfloat>
int main()
{
// Write some testcases for the parsing of floating point numbers in the float32_t type.
// We use the from_chars function defined in this library.
const std::vector<std::float32_t> float32_test_expected{123.456f, -78.9f, 0.0001f, 3.40282e+038f};
const std::vector<std::string> float32_test{"123.456", "-78.9", "0.0001", "3.40282e+038"};
for (std::size_t i = 0; i < float32_test.size(); ++i) {
const auto& f = float32_test[i];
std::float32_t result;
auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result);
if (answer.ec != std::errc() || result != float32_test_expected[i]) {
std::cerr << "Test failed for input: " << std::quoted(f) << std::endl;
return EXIT_FAILURE;
}
}
// Test cases for std::float64_t
const std::vector<std::float64_t> float64_test_expected{1.23e4, -5.67e-8, 1.7976931348623157e+308, -1.7976931348623157e+308};
const std::vector<std::string> float64_test{"1.23e4", "-5.67e-8", "1.7976931348623157e+308", "-1.7976931348623157e+308"};
for (std::size_t i = 0; i < float64_test.size(); ++i) {
const auto& f = float64_test[i];
std::float64_t result;
auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result);
if (answer.ec != std::errc() || result != float64_test_expected[i]) {
std::cerr << "Test failed for input: " << std::quoted(f) << std::endl;
return EXIT_FAILURE;
}
}
std::cout << "All tests passed successfully." << std::endl;
return EXIT_SUCCESS;
return 0;
}