diff --git a/.drone.jsonnet b/.drone.jsonnet index ed8d750bd..84e7659a1 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -37,7 +37,9 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch commands: [ 'set -e', - 'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -', + 'echo $DRONE_STAGE_MACHINE', + 'uname -a', + 'curl -sSL --retry 5 https://apt.llvm.org/llvm-snapshot.gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/llvm-snapshot.gpg', ] + (if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) + (if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) + @@ -68,6 +70,9 @@ local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "c environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" }, commands: [ + 'echo $DRONE_STAGE_MACHINE', + 'sw_vers', + 'uname -a', 'export LIBRARY=' + library, './.drone/drone.sh', ] @@ -94,6 +99,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") = environment: environment, commands: [ + 'echo $env:DRONE_STAGE_MACHINE', 'cmd /C .drone\\\\drone.bat ' + library, ] } diff --git a/.drone/drone.bat b/.drone/drone.bat index 2b56e63c6..c0e336562 100644 --- a/.drone/drone.bat +++ b/.drone/drone.bat @@ -7,8 +7,6 @@ set LIBRARY=%1 set DRONE_BUILD_DIR=%CD% -echo $env:DRONE_STAGE_MACHINE - set BOOST_BRANCH=develop if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master cd .. diff --git a/.drone/drone.sh b/.drone/drone.sh index 5a5469599..86ea680fa 100755 --- a/.drone/drone.sh +++ b/.drone/drone.sh @@ -6,8 +6,6 @@ set -ex export PATH=~/.local/bin:/usr/local/bin:$PATH -uname -a -echo $DRONE_STAGE_MACHINE DRONE_BUILD_DIR=$(pwd) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..23dab29e0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/doc" + schedule: + interval: "weekly" + groups: + all-dependencies: + # Groups all updates into a single PR + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 948770bdd..8c6e11e9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -246,7 +246,7 @@ jobs: linkflags: -stdlib=libc++ - toolset: clang compiler: clang++-16 - cxxstd: "03,11,14,17,20,2b" + cxxstd: "03,11,14,17,20" os: ubuntu-latest container: ubuntu:22.04 install: @@ -286,10 +286,27 @@ jobs: - "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main" source_keys: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - - toolset: clang + compiler: clang++-20 cxxstd: "03,11,14,17,20,2b" - os: macos-13 + os: ubuntu-24.04 + install: + - clang-20 + sources: + - "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main" + source_keys: + - "https://apt.llvm.org/llvm-snapshot.gpg.key" + - toolset: clang + compiler: clang++-21 + cxxstd: "03,11,14,17,20,2b" + os: ubuntu-24.04 + install: + - clang-21 + sources: + - "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main" + source_keys: + - "https://apt.llvm.org/llvm-snapshot.gpg.key" + - toolset: clang cxxstd: "03,11,14,17,20,2b" os: macos-14 @@ -392,6 +409,8 @@ jobs: sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}} locales libfmt-dev sudo locale-gen de_DE.UTF-8 + sudo locale-gen en_US.UTF-8 + sudo locale-gen fr_FR.UTF-8 sudo update-locale - name: Setup GCC Toolchain if: matrix.gcc_toolchain @@ -532,6 +551,10 @@ jobs: cxxstd: "03,11,14,17" # 20 has ICE addrmd: "64" os: windows-latest + - toolset: msvc-14.3 + cxxstd: "14,17,20,latest" + addrmd: "64" + os: windows-11-arm runs-on: ${{matrix.os}} @@ -572,7 +595,6 @@ jobs: matrix: include: - os: ubuntu-24.04 - - os: macos-13 - os: macos-14 - os: macos-15 @@ -620,7 +642,6 @@ jobs: matrix: include: - os: ubuntu-24.04 - - os: macos-13 - os: macos-14 - os: macos-15 @@ -678,7 +699,6 @@ jobs: matrix: include: - os: ubuntu-24.04 - - os: macos-13 - os: macos-14 - os: macos-15 @@ -728,13 +748,70 @@ jobs: cd ../boost-root/__build__ ctest --output-on-failure --no-tests=error + posix-cmake-test-dectest: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-24.04 + - os: macos-14 + - os: macos-15 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v4 + + - name: Install packages + if: matrix.install + run: sudo apt install ${{matrix.install}} + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + mkdir -p libs/$LIBRARY + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + cd libs/$LIBRARY/test + git clone https://github.com/cppalliance/decimal-dectest + cd ../../../ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Configure + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON -DBUILD_DECTEST_TESTING=ON .. + + - name: Build tests + run: | + cd ../boost-root/__build__ + cmake --build . --target tests + + - name: Run tests + run: | + cd ../boost-root/__build__ + ctest --output-on-failure --no-tests=error + posix-standalone-test: strategy: fail-fast: false matrix: include: - os: ubuntu-24.04 - - os: macos-13 - os: macos-14 - os: macos-15 @@ -930,52 +1007,53 @@ jobs: g++ main.cpp $(pkg-config --cflags --libs boost_decimal) -o test_pkgconfig ./test_pkgconfig - MSYS2: - defaults: - run: - shell: msys2 {0} - strategy: - fail-fast: false - matrix: - include: - - { sys: MINGW32, compiler: gcc, cxxstd: '03,11,17,20' } - - { sys: MINGW64, compiler: gcc, cxxstd: '03,11,17,20' } - - runs-on: windows-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - msystem: ${{matrix.sys}} - update: true - install: git python - pacboy: gcc:p cmake:p ninja:p - - - name: Fetch Boost.CI - uses: actions/checkout@v4 - with: - repository: boostorg/boost-ci - ref: master - path: boost-ci-cloned - - name: Get CI scripts folder - run: | - # Copy ci folder if not testing Boost.CI - [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . - rm -rf boost-ci-cloned - - - name: Setup Boost - env: - B2_COMPILER: ${{matrix.compiler}} - B2_CXXSTD: ${{matrix.cxxstd}} - B2_SANITIZE: ${{matrix.sanitize}} - B2_STDLIB: ${{matrix.stdlib}} - run: ci/github/install.sh - - - name: Run tests - run: ci/build.sh +# Symlink in docs folder breaks these runs +# MSYS2: +# defaults: +# run: +# shell: msys2 {0} +# strategy: +# fail-fast: false +# matrix: +# include: +# - { sys: MINGW32, compiler: gcc, cxxstd: '03,11,17,20' } +# - { sys: MINGW64, compiler: gcc, cxxstd: '03,11,17,20' } +# +# runs-on: windows-latest +# +# steps: +# - uses: actions/checkout@v4 +# +# - name: Setup MSYS2 environment +# uses: msys2/setup-msys2@v2 +# with: +# msystem: ${{matrix.sys}} +# update: true +# install: git python +# pacboy: gcc:p cmake:p ninja:p +# +# - name: Fetch Boost.CI +# uses: actions/checkout@v4 +# with: +# repository: boostorg/boost-ci +# ref: master +# path: boost-ci-cloned +# - name: Get CI scripts folder +# run: | +# # Copy ci folder if not testing Boost.CI +# [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . +# rm -rf boost-ci-cloned +# +# - name: Setup Boost +# env: +# B2_COMPILER: ${{matrix.compiler}} +# B2_CXXSTD: ${{matrix.cxxstd}} +# B2_SANITIZE: ${{matrix.sanitize}} +# B2_STDLIB: ${{matrix.stdlib}} +# run: ci/github/install.sh +# +# - name: Run tests +# run: ci/build.sh intel: runs-on: ubuntu-latest diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 6c3dec916..511a4fc27 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -1,4 +1,4 @@ -# ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Copyright Matt Borland 2023 - 2024. # Copyright Christopher Kormanyos 2023 - 2024. # Distributed under the Boost Software License, @@ -17,14 +17,14 @@ on: types: [opened, synchronize, reopened] jobs: gcc-gcov-native: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 defaults: run: shell: bash strategy: fail-fast: false matrix: - standard: [ c++20 ] + standard: [ c++2a ] compiler: [ g++ ] steps: - uses: actions/checkout@v4 @@ -50,6 +50,7 @@ jobs: git submodule update --init libs/static_assert git submodule update --init libs/test git submodule update --init libs/random + git submodule update --init libs/charconv ./bootstrap.sh ./b2 headers - name: gcc-gcov-native diff --git a/.gitignore b/.gitignore index 8f58ef916..03a9d04db 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ test/tidy/err/ test/tidy/tmp/ cmake-build-debug/ test/metal/bin/ +test/decimal-dectest/ # Modules *.gcm @@ -46,3 +47,6 @@ gcm.cache/ # Mac option *.DS_Store + +# Pretty Printers +*.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index 2504622e5..c3538a23e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.10...3.20) # Set version explicitly if not part of Boost superproject if(NOT BOOST_SUPERPROJECT_VERSION) - set(BOOST_DECIMAL_VERSION 5.2.0) + set(BOOST_DECIMAL_VERSION 6.0.0) else() set(BOOST_DECIMAL_VERSION ${BOOST_SUPERPROJECT_VERSION}) endif() diff --git a/README.md b/README.md index 8939f7e5d..d6fbcbca3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Decimal +# Boost.Decimal | | Master | Develop | |------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------| @@ -10,15 +10,8 @@ --- -Decimal is an implementation of IEEE-754:2008 decimal floating point numbers. -See also [1]. - -The library is header-only, and requires C++14. -It is compatible through C++14, 17, 20, 23 and beyond. - -# Notice - -Decimal is under active development and is not an official boost library. +Boost.Decimal is an implementation of [IEEE 754](https://standards.ieee.org/ieee/754/6210/) and [ISO/IEC DTR 24733](https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf) Decimal Floating Point numbers. +The library is header-only, has no dependencies, and requires C++14. # How To Use The Library @@ -95,69 +88,11 @@ class decimal_fast128_t; These types operate like built-in floating point types. They have their own implementations of the Standard-Library functions (e.g. like those found in ``, ``, ``, etc.). - The entire library can be conveniently included with `#include ` -Using the decimal types is simple. - -```cpp -#include -#include - -int main() -{ - using boost::decimal::decimal32_t; - - constexpr decimal32_t a {2, -1}; // Constructs the number 0.2 - constexpr decimal32_t b {1, -1}; // Constructs the number 0.1 - auto sum {a + b}; - - std::cout << sum << std::endl; // prints 0.3 - - const auto neg_a {2, -1, true}; // Constructs the number -0.2 - - sum += neg_a; - - std::cout << sum << std::endl; // Prints 0.1 - - return 0; -} -``` - -This intuitive straightforwardness is the same when using Standard-Library -functions (such as STL functions, `` functions and the like). - -```cpp -#include -#include -#include - -int main() -{ - using namespace boost::decimal; - - decimal64_t val {-0.25}; // Construction from a double - val = abs(val); // DO NOT call std::abs - - char buffer[256]; - auto r_to = to_chars(buffer, buffer + sizeof(buffer) - 1, val); - assert(r_to); // checks std::errc() - *r_to.ptr = '\0'; - - decimal64_t return_value; - auto r_from = from_chars(buffer, buffer + std::strlen(buffer), return_value); - - assert(val == return_value); - - return 0; -} -``` +Using the decimal types is simple and can be learned by [example](https://develop.decimal.cpp.al/decimal/examples.html). +Their usage closely resembles that of built-in binary floating point types by design. # Full Documentation -The complete documentation can be found at: https://develop.decimal.cpp.al/decimal/overview.html - -## References - -[1] IEEE Computer Society. _IEEE_ _Standard_ _for_ _Floating-Point_ _Arithmetic_, -Std. IEEE:754-2008, August 29, 2008 (doi:10.1109/IEEESTD.2008.4610935). +The complete documentation can be found at: https://develop.decimal.cpp.al diff --git a/codecov.yml b/codecov.yml index bbdf35af5..e37fe9c16 100644 --- a/codecov.yml +++ b/codecov.yml @@ -33,4 +33,5 @@ comment: ignore: # This is covered here: https://github.com/cppalliance/int128 + - include/boost/decimal/detail/int128/** - include/boost/decimal/detail/int128/* diff --git a/conan/conanfile.py b/conan/conanfile.py index b58e67d74..32c5cecce 100644 --- a/conan/conanfile.py +++ b/conan/conanfile.py @@ -19,7 +19,7 @@ class CharconvConan(ConanFile): name = "boost_decimal" - version = "5.1.2" + version = "5.2.0" description = "Boost provides free peer-reviewed portable C++ source libraries" url = "https://github.com/cppalliance/decimal" homepage = "https://github.com/cppalliance/decimal" diff --git a/doc/build_antora.sh b/doc/build_antora.sh old mode 100644 new mode 100755 diff --git a/doc/decimal-playbook.yml b/doc/decimal-playbook.yml index f32b60b45..258b070bc 100644 --- a/doc/decimal-playbook.yml +++ b/doc/decimal-playbook.yml @@ -10,5 +10,9 @@ output: dir: html ui: bundle: - url: https://github.com/boostorg/website-v2-docs/releases/download/ui-master/ui-bundle.zip + url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable output_dir: decimal/_ + supplemental_files: ./supplemental-ui +antora: + extensions: + - '@antora/lunr-extension' diff --git a/doc/modules/ROOT/examples b/doc/modules/ROOT/examples new file mode 120000 index 000000000..9f9d1de88 --- /dev/null +++ b/doc/modules/ROOT/examples @@ -0,0 +1 @@ +../../../examples \ No newline at end of file diff --git a/doc/modules/ROOT/images/dec32_debug.png b/doc/modules/ROOT/images/dec32_debug.png new file mode 100644 index 000000000..effc35db7 Binary files /dev/null and b/doc/modules/ROOT/images/dec32_debug.png differ diff --git a/doc/modules/ROOT/images/dec32_fast_debug.png b/doc/modules/ROOT/images/dec32_fast_debug.png new file mode 100644 index 000000000..86451f271 Binary files /dev/null and b/doc/modules/ROOT/images/dec32_fast_debug.png differ diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc index 539bb1a30..3ad28b886 100644 --- a/doc/modules/ROOT/nav.adoc +++ b/doc/modules/ROOT/nav.adoc @@ -1,19 +1,24 @@ * xref:overview.adoc[] * xref:basics.adoc[] * xref:examples.adoc[] -** xref:examples.adoc#examples_construction[Construction] -** xref:examples.adoc#examples_promotion[Type Promotion] +** xref:examples.adoc#examples_construction[Basic Construction] +** xref:examples.adoc#examples_basic_math[Basic Arithmetic] +** xref:examples.adoc#examples_conversions[Conversions] +*** xref:examples.adoc#examples_integer_conversions[Integer Conversions] +*** xref:examples.adoc#examples_binary_floating_conversions[Binary Floating Point Conversions] +** xref:examples.adoc#examples_promotion[Promotion and Mixed Decimal Arithmetic] ** xref:examples.adoc#examples_charconv[``] -** xref:examples.adoc#examples_rounding_mode[Rounding Mode] ** xref:examples.adoc#examples_generic_programming[Generic Programming] ** xref:examples.adoc#examples_literals_constants[Literals and Constants] -** xref:examples.adoc#examples_bit_conversions[Bit Conversions] -** xref:examples.adoc#examples_finance[Financial Applications] -** xref:examples.adoc#examples_boost_math[Boost.Math Integration] ** xref:examples.adoc#examples_format[Formatting] +*** xref:examples.adoc#examples_fmt_format[pass:[{fmt}]] *** xref:examples.adoc#examples_std_format[``] -*** xref:examples.adoc#examples_fmt_format[+{fmt}+] -** xref:examples.adoc#examples_print[``] +*** xref:examples.adoc#examples_print[``] +** xref:examples.adoc#examples_file[Read and Write to File] +* xref:financial_examples.adoc[] +** xref:financial_examples.adoc#examples_money_parsing[Parsing Pricing Data from File] +** xref:financial_examples.adoc#examples_boost_math[Boost.Math Integration] +* xref:debugger.adoc[] * xref:api_reference.adoc[] ** xref:api_reference.adoc#api_ref_types[Types] ** xref:api_reference.adoc#api_ref_structs[Structs] @@ -29,21 +34,32 @@ ** xref:decimal_fast32_t.adoc[] ** xref:decimal_fast64_t.adoc[] ** xref:decimal_fast128_t.adoc[] +* xref:binary_floating_conversions.adoc[] +* xref:cohorts.adoc[] * xref:conversions.adoc[] * xref:literals.adoc[] * xref:numbers.adoc[] * xref:cmath.adoc[] +** xref:cmath.adoc#basic_cmath_ops[Basic Operations] +** xref:cmath.adoc#cmath_exp[Exponential Functions] +** xref:cmath.adoc#cmath_power_funcs[Power Functions] +** xref:cmath.adoc#cmath_trig_funcs[Trigonometric Functions] +** xref:cmath.adoc#cmath_hyperbolic_funcs[Hyperbolic Functions] +** xref:cmath.adoc#cmath_error_funcs[Error and Gamma Functions] +** xref:cmath.adoc#cmath_nearest_int[Nearest Integer Floating Point] +** xref:cmath.adoc#cmath_manipulation_funcs[Floating Point Manipulation] +** xref:cmath.adoc#cmath_classification[Classification and Comparison] +** xref:cmath.adoc#cmath_spec_fun[Special Functions] ** xref:cmath.adoc#non_standard_cmath[Non-Standard Functions] -* xref:cstdlib.adoc[] -* xref:charconv.adoc[] -* xref:format.adoc[] -** xref:format.adoc#std_format[``] -** xref:format.adoc#fmt_format[``] -* xref:cfenv.adoc[] -* xref:cfloat.adoc[] -* xref:cstdio.adoc[] -* xref:functional.adoc[] -* xref:limits.adoc[] +* xref:cstdlib.adoc[`` Support (`strtod`)] +* xref:charconv.adoc[`` Support (`to_/from_chars`)] +* xref:format.adoc[`` and pass:[{fmt}] Support] +* xref:cfenv.adoc[`` Support (Rounding Modes)] +* xref:cfloat.adoc[`` Support (Eval Modes)] +* xref:cstdio.adoc[`` Support (`printf`)] +* xref:functional.adoc[`` Support (`hash`)] +* xref:limits.adoc[`` Support (`numeric_limits`)] +* xref:strings.adoc[`` Support (`to_string`)] * xref:config.adoc[] ** xref:config.adoc#configuration_user[User Configuration] ** xref:config.adoc#configuration_automatic[Automatic Configuration] diff --git a/doc/modules/ROOT/pages/api_reference.adoc b/doc/modules/ROOT/pages/api_reference.adoc index 8082c98ce..6b418b499 100644 --- a/doc/modules/ROOT/pages/api_reference.adoc +++ b/doc/modules/ROOT/pages/api_reference.adoc @@ -14,52 +14,46 @@ enums, constants and macros that are provided in this library. [#api_ref_types] == Types -=== IEEE 754 Compliant Types - -- xref:decimal32_t.adoc[decimal32_t] -- xref:decimal64_t.adoc[decimal64_t] -- xref:decimal128_t.adoc[decima128_t] - -=== Non-IEEE 754 Compliant Types - -- xref:decimal_fast32_t.adoc[decimal_fast32_t] -- xref:decimal_fast64_t.adoc[decimal_fast64_t] -- xref:decimal_fast128_t.adoc[decimal_fast128_t] +|=== +| IEEE 754 Compliant | Non-IEEE 754 Compliant +| xref:decimal32_t.adoc[`decimal32_t`] | xref:decimal_fast32_t.adoc[`decimal_fast32_t`] +| xref:decimal64_t.adoc[`decimal64_t`] | xref:decimal_fast64_t.adoc[`decimal_fast64_t`] +| xref:decimal128_t.adoc[`decima128_t`] | xref:decimal_fast128_t.adoc[`decimal_fast128_t`] +|=== [#api_ref_structs] == Structures -- xref:charconv.adoc#to_chars_result[to_chars_result] -- xref:charconv.adoc#from_chars_result[from_chars_result] +|=== +| xref:charconv.adoc#to_chars_result[to_chars_result] | xref:charconv.adoc#from_chars_result[from_chars_result] +|=== [#api_ref_enums] == Enums -- xref:charconv.adoc#chars_format[chars_format] +|=== +| xref:charconv.adoc#chars_format[chars_format] | xref:cfenv.adoc[rounding_mode] +|=== [#api_ref_constants] == Constants -- xref:charconv.adoc#charconv_limits[limits] -- xref:numbers.adoc[numbers] +|=== +| xref:charconv.adoc#charconv_limits[limits] | xref:numbers.adoc[numbers] +|=== [#api_ref_macros] == Macros -=== User Configuration - -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_CASSERT`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_IOSTREAM`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_CLIB`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_EXCEPTIONS`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_FAST_MATH`] -- xref:config.adoc#configuration_user[`BOOST_DECIMAL_DEC_EVAL_METHOD`] - -=== Automatic Configuration - -- xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_CXX20_CONSTEXPR`] -- xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_CONSTEXPR`] -- xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_HAS_STD_CHARCONV`] -- xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_HAS_STD_STRING_VIEW`] - +|=== +| User Configuration | Automatic Configuration +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_CASSERT`] | xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_CXX20_CONSTEXPR`] +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_IOSTREAM`] | xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_NO_CONSTEVAL_DETECTION`] +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_CLIB`] | xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_HAS_STD_CHARCONV`] +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_DISABLE_EXCEPTIONS`] | xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_HAS_STD_STRING_VIEW`] +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS`] | +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS`] | +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS`] | +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_FAST_MATH`] | +| xref:config.adoc#configuration_user[`BOOST_DECIMAL_DEC_EVAL_METHOD`] | +|=== diff --git a/doc/modules/ROOT/pages/basics.adoc b/doc/modules/ROOT/pages/basics.adoc index ea21d8f37..f0bb9c7a6 100644 --- a/doc/modules/ROOT/pages/basics.adoc +++ b/doc/modules/ROOT/pages/basics.adoc @@ -16,34 +16,53 @@ Every decimal type can be constructed in a few ways: [source, c++] ---- +namespace boost { +namespace decimal { + +enum class construction_sign +{ + negative, + positive +}; + template -constexpr decimal32_t(UnsignedInteger coefficient, Integer exponent, bool sign = false) noexcept; +constexpr decimal32_t(UnsignedInteger coefficient, Integer exponent, construction_sign resultant_sign = construction_sign::positive) noexcept; template constexpr decimal32_t(SignedInteger coefficient, Integer exponent) noexcept; + +} // namespace decimal +} // namespace boost ---- As you can see you are either allowed to pass a signed integer, or specify the signedness of the resulting number, but not both. -This is designed to reduce confusion (e.g. what would be the resulting sign of `{-3, 0, true}`?) +This is designed to reduce confusion (e.g. what would be the resulting sign of `{-3, 0, construction_sign::negative}`?) [souce, c++] ---- -boost::decimal::decimal32_t a {1, 1}; // constructs 1e1 = 10 -boost::decimal::decimal32_t b {-2, -1}; // constructs -2e-2 or -0.2 -boost::decimal::decimal32_t c {2, -1, true}; // also constructs -2e-1 or -0.2 -boost::decimal::decimal32_t e {5, 5}; // constructs 5x10^5 -boost::decimal::decimal32_t f {1234, -3} // constructs 1.234 or 1234x10^-3 +boost::decimal::decimal32_t a {1, 1}; // constructs 1e1 = 10 +boost::decimal::decimal32_t b {-2, -1}; // constructs -2e-2 or -0.2 +boost::decimal::decimal32_t c {2U, -1, construction_sign::negative}; // also constructs -2e-1 or -0.2 (Note: The coefficient must be an unsigned type) +boost::decimal::decimal32_t d {5, 5}; // constructs 5x10^5 +boost::decimal::decimal32_t e {1234, -3} // constructs 1.234 or 1234x10^-3 +---- + +Overflow and underflow are handled the same way that they are with binary floating point numbers i.e. they will construct an infinity or a zero. + +[source, c++] +---- +boost::decimal::decimal64_t overflow_value {100, 10000}; // Constructs +infinity +boost::decimal::decimal64_t underflow_value {100, -10000}; // Constructs 0 ---- === Construction from Integer -A decimal number can be explicitly or implicitly constructed from an integer. +A decimal number can be explicitly constructed from an integer. For example: [source, c++] ---- -boost::decimal::decimal64_t g = 1; -boost::decimal::decimal32_t h {-4}; +boost::decimal::decimal32_t f {-4}; ---- === Construction from Binary Floating Point @@ -56,61 +75,43 @@ For example: boost::decimal::decimal128_t pi {3.14}; ---- -NOTE: Due to the differences in decimal and binary floating point numbers there may be a difference in the resulting representation in decimal format, and thus it is not recommended to construct from binary floating point numbers - -== Fundamental Operations - -The fundamental operations of numerical type (e.g. `>`, `==`, `+`, etc.) are overloaded. +Construction from non-finite values (e.g. `std::numeric_limits::quiet_NaN()`) will yield the same non-finite value in the resulting decimal value. +Overflow or underflow will construct infinity or 0. -[source, c++] ----- -#include -#include +IMPORTANT: Due to the differences in decimal and binary floating point numbers there may be a difference in the resulting representation in decimal format, and thus it is not recommended to construct from binary floating point numbers -int main() -{ - constexpr boost::decimal::decimal32_t lhs {5}; - constexpr boost::decimal::decimal32_t rhs {1, -1}; +For more information see: xref:examples.adoc#examples_construction[Basic Construction] - assert(lhs > rhs); - assert(lhs != rhs); - assert(lhs + rhs > lhs); +== Fundamental Operations - auto new_lhs {lhs}; // Using auto is safe when constructring from existing decimal values - new_lhs += lhs; +The fundamental operations of numerical types (e.g. `>`, `==`, `+`, etc.) are provided for each type, to include mixed type arithmetic (e.g. `decimal32_t` + `decimal64_t`), and between integers and decimal types. +For more information see: xref:examples.adoc#examples_promotion[Promotion and Mixed Decimal Arithmetic]. - assert(lhs < new_lhs); +== Rounding - return 0; -} ----- +The default rounding mode for all operations is so-called "banker's rounding", which is to nearest (with ties to even). +Similar to the standard library, the active rounding mode can be changed through floating point environment variables. +For more information see: xref:cfenv.adoc[] == Using the Library The entire library can be accessed using the convenience header ``. A short example of the basic usage: +[#first_example] +.This https://github.com/cppalliance/decimal/blob/develop/examples/first_example.cpp[example] shows the very basics on how to make a complete and working program using the decimal library +==== [source, c++] ---- -#include -#include -#include - -int main() -{ - using namespace boost::decimal; - - // Outputs 0.30000000000000004 - std::cout << std::setprecision(17) << 0.1 + 0.2 << std::endl; - - // Construct the two decimal values - constexpr decimal64_t a {1, -1}; // 1e-1 or 0.1 - constexpr decimal64_t b {2, -1}; // 2e-1 or 0.2 - - // Outputs 0.30000000000000000 - std::cout << a + b << std::endl; +include::example$first_example.cpp[] +---- - return 0; -} +.Expected Output +.... +Using doubles: +0.1 + 0.2 = 0.30000000000000004 ----- +Using decimal64_t: +0.1_DD + 0.2_DD = 0.3000000000000000 +.... +==== diff --git a/doc/modules/ROOT/pages/benchmarks.adoc b/doc/modules/ROOT/pages/benchmarks.adoc index 593a3bce8..52936c83e 100644 --- a/doc/modules/ROOT/pages/benchmarks.adoc +++ b/doc/modules/ROOT/pages/benchmarks.adoc @@ -28,6 +28,8 @@ To run the GCC benchmarks you can use the following command: `gcc benchmark_libd To run the Intel benchmarks you will need both the https://www.intel.com/content/www/us/en/developer/tools/oneapi/overview.html[Intel Compiler], and the https://www.intel.com/content/www/us/en/developer/articles/tool/intel-decimal-floating-point-math-library.html[library]. You can the use the following command: `icx benchmark_libbid.c -O3 $PATH_TO_LIBBID/libbid.a -std=c17` followed by: `./a.out` +You can also use `gcc` instead of `icx`. +On windows the command is similarly: `cl benchmark_libbid.c /O2 /std:c17 ..\PATH_TO_LIBBID\cl000libbid.lib`, followed by: `.\benchmark_libbid.exe`. NOTE: The Intel benchmarks can only be run on one of their supported architectures: IA-32, IA-64, and Intel x64 @@ -92,13 +94,13 @@ Intel Compiler: | `decimal_fast128_t` | 698,945 | 4.856 -| Intel `Decimal32` +| Intel `BID_UINT32` | 2,411,294 | 16.754 -| Intel `Decimal64` +| Intel `BID_UINT64` | 3,158,422 | 21.945 -| Intel `Decimal128` +| Intel `BID_UINT128` | 3,389,883 | 23.553 |=== @@ -140,6 +142,15 @@ GCC: | GCC `_Decimal128` | 914,600 | 14.844 +| Intel `BID_UINT32` +| 3,718,385 +| 60.348 +| Intel `BID_UINT64` +| 5,721,887 +| 92.865 +| Intel `BID_UINT128` +| 7,090,648 +| 115.080 |=== === Addition @@ -172,13 +183,13 @@ Intel Compiler: | `decimal_fast128_t` | 1,367,004 | 15.092 -| Intel `Decimal32` +| Intel `BID_UINT32` | 1,242,797 | 13.721 -| Intel `Decimal64` +| Intel `BID_UINT64` | 1,689,585 | 18.653 -| Intel `Decimal128` +| Intel `BID_UINT128` | 1,958,345 | 21.620 |=== @@ -220,6 +231,15 @@ GCC: | GCC `_Decimal128` | 3,368,864 | 46.138 +| Intel `BID_UINT32` +| 2,838,194 +| 38.879 +| Intel `BID_UINT64` +| 3,297,652 +| 45.163 +| Intel `BID_UINT128` +| 2,796,283 +| 38.296 |=== === Subtraction @@ -252,13 +272,13 @@ Intel Compiler: | `decimal_fast128_t` | 1,212,405 | 16.564 -| Intel `Decimal32` +| Intel `BID_UINT32` | 1,922,108 | 26.261 -| Intel `Decimal64` +| Intel `BID_UINT64` | 1,793,879 | 24.509 -| Intel `Decimal128` +| Intel `BID_UINT128` | 2,397,372 | 32.754 |=== @@ -300,6 +320,15 @@ GCC: | GCC `_Decimal128` | 3,178,891 | 10.816 +| Intel `BID_UINT32` +| 3,762,566 +| 12.802 +| Intel `BID_UINT64` +| 3,432,814 +| 11.680 +| Intel `BID_UINT128` +| 3,725,534 +| 12.676 |=== === Multiplication @@ -332,13 +361,13 @@ Intel Compiler: | `decimal_fast128_t` | 5,959,977 | 81.870 -| Intel `Decimal32` +| Intel `BID_UINT32` | 1,375,434 | 18.894 -| Intel `Decimal64` +| Intel `BID_UINT64` | 2,052,278 | 28.191 -| Intel `Decimal128` +| Intel `BID_UINT128` | 5,964,489 | 81.932 |=== @@ -380,6 +409,15 @@ GCC: | GCC `_Decimal128` | 7,050,299 | 107.289 +| Intel `BID_UINT32` +| 2,638,999 +| 40.197 +| Intel `BID_UINT64` +| 4,605,497 +| 70.150 +| Intel `BID_UINT128` +| 13,075,436 +| 199.163 |=== === Division @@ -412,13 +450,13 @@ Intel Compiler: | `decimal_fast128_t` | 8,105,004 | 78.086 -| Intel `Decimal32` +| Intel `BID_UINT32` | 1,561,213 | 15.041 -| Intel `Decimal64` +| Intel `BID_UINT64` | 3,115,862 | 30.019 -| Intel `Decimal128` +| Intel `BID_UINT128` | 7,474,712 | 72.013 |=== @@ -460,6 +498,15 @@ GCC: | GCC `_Decimal128` | 10,257,437 | 130.490 +| Intel `BID_UINT32` +| 3,242,695 +| 40.194 +| Intel `BID_UINT64` +| 6,143,554 +| 76.151 +| Intel `BID_UINT128` +| 13,499,022 +| 167.324 |=== === `from_chars` @@ -679,6 +726,15 @@ Run using an Intel i9-11900k chipset running Windows 11 and Visual Studio 17.14. | `decimal_fast128_t` | 801,708 | 4.300 +| Intel `BID_UINT32` +| 4,372,973 +| 23.457 +| Intel `BID_UINT64` +| 9,345,300 +| 50.129 +| Intel `BID_UINT128` +| 11,504,914 +| 61.714 |=== === Addition @@ -709,6 +765,15 @@ Run using an Intel i9-11900k chipset running Windows 11 and Visual Studio 17.14. | `decimal_fast128_t` | 3,109,101 | 38.914 +| Intel `BID_UINT32` +| 4,967,728 +| 62.177 +| Intel `BID_UINT64` +| 6,268,077 +| 78.452 +| Intel `BID_UINT128` +| 4,847,330 +| 60.670 |=== === Subtraction @@ -739,6 +804,15 @@ Run using an Intel i9-11900k chipset running Windows 11 and Visual Studio 17.14. | `decimal_fast128_t` | 2,963,570 | 9.167 +| Intel `BID_UINT32` +| 4,603,462 +| 14.240 +| Intel `BID_UINT64` +| 5,627,305 +| 17.407 +| Intel `BID_UINT128` +| 5,824,263 +| 18.016 |=== === Multiplication @@ -769,6 +843,15 @@ Run using an Intel i9-11900k chipset running Windows 11 and Visual Studio 17.14. | `decimal_fast128_t` | 9,236,110 | 117.434 +| Intel `BID_UINT32` +| 3,833,363 +| 48.740 +| Intel `BID_UINT64` +| 11,671,369 +| 148.398 +| Intel `BID_UINT128` +| 62,036,577 +| 788.778 |=== === Division @@ -799,6 +882,15 @@ Run using an Intel i9-11900k chipset running Windows 11 and Visual Studio 17.14. | `decimal_fast128_t` | 11,587,763 | 129,737 +| Intel `BID_UINT32` +| 5,037,576 +| 46.401 +| Intel `BID_UINT64` +| 8,768,259 +| 98.170 +| Intel `BID_UINT128` +| 38,519,644 +| 431.269 |=== === `from_chars` diff --git a/doc/modules/ROOT/pages/binary_floating_conversions.adoc b/doc/modules/ROOT/pages/binary_floating_conversions.adoc new file mode 100644 index 000000000..ca35d16bf --- /dev/null +++ b/doc/modules/ROOT/pages/binary_floating_conversions.adoc @@ -0,0 +1,35 @@ +//// +Copyright 2025 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#bin_float] += Conversion from Binary Floating Point +:idprefix: bin_float_ + +The library deliberately does not contain any operations between a binary floating point type and the decimal floating point types. +The rationale is similar to that of the library in the first place in that you may end up with surprising results. +As shown in our xref:basics.adoc#first_example[first example] `0.1 + 0.2 != 0.3` when using `double`, so you could end up with a decimal value that does not represent exactly what you expect. +To offer minimal and explicit interoperability with types `float`, `double`, and `long double` each decimal type has an explicit constructor and conversion operator as discussed on the type specific documentation pages like xref:decimal32_t.adoc[`decimal32_t`]: + +[source, c++] +---- +namespace boost { +namespace decimal { + +class decimal32_t +{ + template + explicit decimal32_t(Float x) noexcept; + + template + explicit operator Float() const noexcept; +}; + +} // namespace decimal +} // namespace boost +---- + +*No additional support is planned* to deter use of these conversions. +If you have existing floating point values that need to be converted into decimals it is recommended to write them to string, validate the string, and then utilize the string constructors provided by this library. diff --git a/doc/modules/ROOT/pages/cfenv.adoc b/doc/modules/ROOT/pages/cfenv.adoc index 9e56a4701..77ccd7803 100644 --- a/doc/modules/ROOT/pages/cfenv.adoc +++ b/doc/modules/ROOT/pages/cfenv.adoc @@ -5,44 +5,115 @@ https://www.boost.org/LICENSE_1_0.txt //// [#cfenv] -= `` support += `` Support :idprefix: cfenv_ +WARNING: This is an expert feature. +If you have never used `std::fegetround` nor `std::fesetround` before, it is unlikely you will need anything described on this page + == IEEE 754 defines 5 rounding modes for Decimal Floating Point Types. 1. Downward -2. To nearest +2. To nearest (with ties to even) 3. To nearest from zero 4. Toward zero 5. Upward -NOTE: The default rounding mode is to nearest from zero (#3). +NOTE: The default rounding mode is to nearest with ties to even (#2) as specified in IEEE 754 Section 4.3.3. This is also colloquially known as "Banker's Rounding" -IMPORTANT: The rounding mode can only be changed at runtime. All `constexpr` calculations will use the default of to nearest from zero. +Using the following `enum class` and functions you can change the rounding mode from the default at *RUNTIME* only if xref:config.adoc#configuration_automatic[`BOOST_DECIMAL_NO_CONSTEVAL_DETECTION`] is not defined. [source, c++] ---- -#include +#include namespace boost { namespace decimal { enum class rounding_mode : unsigned { - fe_dec_downward = 1 << 0, - fe_dec_to_nearest = 1 << 1, - fe_dec_to_nearest_from_zero = 1 << 2, - fe_dec_toward_zero = 1 << 3, - fe_dec_upward = 1 << 4, - fe_dec_default = fe_dec_to_nearest_from_zero + fe_dec_downward, + fe_dec_to_nearest, + fe_dec_to_nearest_from_zero, + fe_dec_toward_zero, + fe_dec_upward, + fe_dec_default = fe_dec_to_nearest }; rounding_mode fegetround() noexcept; + +// Returns the rounding mode that has been set +// +// If your compiler defines BOOST_DECIMAL_NO_CONSTEVAL_DETECTION, +// this function will return the default rounding mode +// to alert you that the rounding mode has NOT changed rounding_mode fesetround(rounding_mode round) noexcept; } //namespace decimal } //namespace boost ---- +IMPORTANT: Much like `std::fesetround`, `boost::decimal::fesetround` is not thread safe. + +[#examples_rounding_mode] + +.This https://github.com/cppalliance/decimal/blob/develop/examples/rounding_mode.cpp[example] demonstrates how to set, get, and effects of the global rounding mode. +==== +[source, c++] +---- +include::example$rounding_mode.cpp[] +---- + +.Expected Output: +.... +The default rounding mode is: fe_dec_to_nearest +The current rounding mode is: fe_dec_upward +lhs equals: 5e+50 +rhs equals: 4e+40 + Sum with upward rounding: 5.000001e+50 +The current rounding mode is: fe_dec_downward +Sum with downward rounding: 4.999999e+50 +.... +==== + +As shown, changing the rounding mode *WILL* change your numerical results. +If you are coming from the Intel library (or other C-style libs) where every mathematical function takes a rounding mode, that is not the case in this library; the only way to change the rounding mode for individual operations is via the global rounding mode. +Before attempting to change the rounding mode ensure this is actually what you want to happen. + +You can similarly change the default rounding mode at compile time with *ANY* compiler (unlike at runtime) using similarly named macros: + +1. `BOOST_DECIMAL_FE_DEC_DOWNWARD` +2. `BOOST_DECIMAL_FE_DEC_TO_NEAREST` +3. `BOOST_DECIMAL_FE_DEC_TO_NEAREST_FROM_ZERO` +4. `BOOST_DECIMAL_FE_DEC_TOWARD_ZERO` +5. `BOOST_DECIMAL_FE_DEC_UPWARD` + +If none of the above macros are defined, the default rounding mode for compile time is the same as the default runtime (i.e. as if `BOOST_DECIMAL_FE_DEC_TO_NEAREST` were defined). +At most *ONE* of these macros are allowed to be user defined. +A `#error` will be emitted if more than one is detected. +The macro must be defined before the inclusion of any decimal library header. +The rounding mode set at compile time is thread-safe as it is read only. + +This same example can be reduced for the cases where: + +1. Compiler does not support runtime rounding mode changes + +2. You want to change the compile time rounding mode + +.This https://github.com/cppalliance/decimal/blob/develop/examples/rounding_mode.cpp[example] demonstrates how the compile time rounding mode can be set, and it's effects on compile time and run time evaluation. +==== +[source, c++] +---- +include::example$rounding_mode_compile_time.cpp[] +---- + +.Expected Output +.... +The default rounding mode is: fe_dec_to_nearest +The current rounding mode is: fe_dec_downward +.... +==== + +IMPORTANT: Prior to v5.2.0 this header was ``, but has been changed to `` for consistency with the STL naming convention. diff --git a/doc/modules/ROOT/pages/cfloat.adoc b/doc/modules/ROOT/pages/cfloat.adoc index 4e160bafb..89fc3e56e 100644 --- a/doc/modules/ROOT/pages/cfloat.adoc +++ b/doc/modules/ROOT/pages/cfloat.adoc @@ -5,10 +5,12 @@ https://www.boost.org/LICENSE_1_0.txt //// [#cfloat] -= `` support += `` Support :idprefix: cfloat_ -The following macros analogous to those from `` for the decimal floating point types: +Macros analogous to those from https://en.cppreference.com/w/cpp/header/cfloat.html[``] are provided by the library. +These macros are not available when consuming the library as a module. +In all cases `std::numeric_limits` should be preferred. [source, c++] ---- @@ -46,7 +48,7 @@ The following macros analogous to those from `` for the decimal floating #define BOOST_DECIMAL_DEC128_MAX std::numeric_limits::denorm_min() ---- -Additionally `BOOST_DECIMAL_DEC_EVAL_METHOD` is similar to `FLT_EVAL_METHOD`: https://en.cppreference.com/w/cpp/types/climits/FLT_EVAL_METHOD +Additionally `BOOST_DECIMAL_DEC_EVAL_METHOD` is similar to https://en.cppreference.com/w/cpp/types/climits/FLT_EVAL_METHOD[`FLT_EVAL_METHOD`]: The valid values are: @@ -57,4 +59,4 @@ The valid values are: | 2 | All `decimal32_t` and `decimal64_t` (or fast equivalents) operations are evaluated with the precision and range of `decimal128_t` internally, and returned as the original type. |=== -To use the functionality you must `#define BOOST_DECIMAL_DEC_EVAL_METHOD` to the value you want before you `#include `. +To use the functionality you must `#define BOOST_DECIMAL_DEC_EVAL_METHOD` to the value you want before you `#include `, or any Boost.Decimal header if you are not using the convenience header. diff --git a/doc/modules/ROOT/pages/charconv.adoc b/doc/modules/ROOT/pages/charconv.adoc index a315b4efe..181b418ee 100644 --- a/doc/modules/ROOT/pages/charconv.adoc +++ b/doc/modules/ROOT/pages/charconv.adoc @@ -1,22 +1,17 @@ //// -Copyright 2024 Matt Borland +Copyright 2024 - 2025 Matt Borland Distributed under the Boost Software License, Version 1.0. https://www.boost.org/LICENSE_1_0.txt //// [#charconv] -= `` support += `` Support :idprefix: charconv_ == The following functions analogous to those from https://en.cppreference.com/w/cpp/header/charconv[] are provided: -IMPORTANT: `std::from_chars` has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. -The standard for does not distinguish between underflow and overflow like strtod does. -`boost::decimal::from_chars` modifies `value` in order to communicate this to the user in a divergence from the standard. -This behavior is the same as that of https://www.boost.org/doc/libs/master/libs/charconv/doc/html/charconv.html#from_chars_usage_notes_for_from_chars_for_floating_point_types[`boost::charconv::from_chars_erange`]. - [#chars_format] == chars_format [source, c++] @@ -26,9 +21,10 @@ namespace decimal { enum class chars_format : unsigned { - scientific = 1 << 0, - fixed = 1 << 1, - hex = 1 << 2, + scientific, + fixed, + hex, + cohort_preserving_scientific, general = fixed | scientific }; @@ -36,6 +32,11 @@ enum class chars_format : unsigned } //namespace boost ---- +The one difference here between `` and what we provide is the option `cohort_preserving_scientific`. +This format is allowed in both `from_chars` and `to_chars` in specially defined ways to allow for cohorts to be preserved during the conversion process. + +IMPORTANT: When using `from_chars` or `to_chars` with fast types it is invalid to specify the format `cohort_preserving_scientific` as these types have no support for cohorts. + [#from_chars_result] == from_chars_result [source, c++] @@ -46,9 +47,9 @@ namespace decimal { struct from_chars_result { const char* ptr; - std::errc ptr; + std::errc ec; - friend constexpr auto operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default; + friend constexpr bool operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default; constexpr explicit operator bool() const noexcept { return ec == std::errc{}; } } @@ -67,9 +68,9 @@ namespace decimal { struct to_chars_result { char* ptr; - std::errc ptr; + std::errc ec; - friend constexpr auto operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept = default; + friend constexpr bool operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept = default; constexpr explicit operator bool() const noexcept { return ec == std::errc{}; } } @@ -111,6 +112,9 @@ constexpr std::from_chars_result from_chars(const char* first, const char* last, } //namespace boost ---- +When using the format `cohort_preserving_scientific` the number of digits in the string to be converted must not exceed the precision of the type that it is being converted to. +For example: `4.99999999999e+03` is invalid if being converted to `decimal32_t` because it is not exactly representable in the type. + IMPORTANT: If `std::chars_format` is used the function will return a `std::from_chars_result` and if `boost::decimal::chars_format` is used *OR* no format is specified then a `boost::decimal::from_chars_result` will be returned. [#to_chars] @@ -123,21 +127,21 @@ namespace boost { namespace decimal { template -BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value) noexcept; +constexpr to_chars_result to_chars(char* first, char* last, DecimalType value) noexcept; template -BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt) noexcept; +constexpr to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt) noexcept; template -BOOST_DECIMAL_CONSTEXPR to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt, int precision) noexcept; +constexpr to_chars_result to_chars(char* first, char* last, DecimalType value, chars_format fmt, int precision) noexcept; #ifdef BOOST_DECIMAL_HAS_STD_CHARCONV template -BOOST_DECIMAL_CONSTEXPR std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt) noexcept; +constexpr std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt) noexcept; template -BOOST_DECIMAL_CONSTEXPR std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt, int precision) noexcept; +constexpr std::to_chars_result to_chars(char* first, char* last, DecimalType value, std::chars_format fmt, int precision) noexcept; #endif // BOOST_DECIMAL_HAS_STD_CHARCONV @@ -145,21 +149,17 @@ BOOST_DECIMAL_CONSTEXPR std::to_chars_result to_chars(char* first, char* last, D } //namespace boost ---- -All `to_chars` functions ignore the effects of cohorts, and instead output normalized values. - -NOTE: `BOOST_DECIMAL_CONSTEXPR` is defined if: - - - `_MSC_FULL_VER` >= 192528326 - - `\\__GNUC__` >= 9 - - Compiler has: `__builtin_is_constant_evaluated()` - - pass:[C++]20 support with: `std::is_constant_evaluated()` +All `to_chars` functions, except for when using the format `cohort_preserving_scientific`, ignore the effects of cohorts, and instead output normalized values. +Additionally, when using the format `cohort_preserving_scientific` if a precision is specified the function will return `{first, std::errc::invalid_argument}`. +Per IEEE 754 specifying both a precision and cohort preservation is an invalid operation. +This follows because you are potentially rounding the number, or adding trailing zeros to the fraction which both destroy the cohort information. IMPORTANT: Same as `from_chars`, `boost::decimal::to_chars` will return a `std::to_chars_result` if `std::chars_format` is used to specify the format; otherwise it returns a `boost::decimal::to_chars_result`. The library offers an additional feature for sizing buffers without specified precision and in general format [#charconv_limits] -== limits +== Formatting Limits [source, c++] ---- #include @@ -167,37 +167,30 @@ The library offers an additional feature for sizing buffers without specified pr namespace boost { namespace decimal { -template -struct limits +template ::max_digits10> +class formatting_limits { - static constexpr int max_chars; -} - -} //namespace decimal -} //namespace boost ----- +public: -The member can then be used to size buffers such as: + static constexpr std::size_t scientific_format_max_chars; -[source, c++] ----- -#include -#include + static constexpr std::size_t fixed_format_max_chars; -int main() -{ - using namespace boost::decimal; + static constexpr std::size_t hex_format_max_chars; - decimal32_t val {5, -1}; + static constexpr std::size_t cohort_preserving_scientific_max_chars; - char buffer[limits::max_chars]; + static constexpr std::size_t general_format_max_chars; - auto r_to = to_chars(buffer, buffer + sizeof(buffer), val); - *r_to.ptr = '\0'; + static constexpr std::size_t max_chars; +}; - std::cout << buffer << std::endl; +} //namespace decimal +} //namespace boost +---- - return 0; -} +This class allows you to size buffers for `to_chars` without have to arbitrarily guess what size you need it to be. +The `Precision` is defaulted to the maximum precision of the type, which is the same assumption that is made when you use `to_chars` with an unspecified precision. +The `max_chars` variable is the largest of the 5 specified `chars_format` options. ----- +The members can then be used to size buffers such as in our `` example from the main examples page xref:examples.adoc#examples_charconv[here]. diff --git a/doc/modules/ROOT/pages/cmath.adoc b/doc/modules/ROOT/pages/cmath.adoc index d1aec7f99..65bc7412a 100644 --- a/doc/modules/ROOT/pages/cmath.adoc +++ b/doc/modules/ROOT/pages/cmath.adoc @@ -5,15 +5,17 @@ https://www.boost.org/LICENSE_1_0.txt //// [#cmath] -= `` support += `` Support :idprefix: cmath_ Decimal contains overloads for all functions from ``, and they have the same handling as built-in floating point types. -They are also all constexpr with C\\++14 unlike the built-in floating point types which require either C++23 or 26. +They are also all constexpr with pass:[C++14] unlike the built-in floating point types which require either pass:[C++23] or 26. Additionally, all functions are marked `noexcept`. -== Basic Operations +All of these functions are impacted by the global rounding mode as described in xref:cfenv.adoc[rounding modes] as well as the `DEC_FLT_EVAL_METHOD` from xref:cfloat.adoc[evaluation methods]. +== Basic Operations +[#basic_cmath_ops] |=== | Function | Description | https://en.cppreference.com/w/cpp/numeric/math/fabs[abs] | Absolute Value @@ -25,7 +27,8 @@ Additionally, all functions are marked `noexcept`. | https://en.cppreference.com/w/cpp/numeric/math/fmax[fmax] | Returns maximum value | https://en.cppreference.com/w/cpp/numeric/math/fmin[fmin] | Returns minimum value | https://en.cppreference.com/w/cpp/numeric/math/fdim[fdim] | Returns unsigned difference of two values -| https://en.cppreference.com/w/cpp/numeric/math/nan[nan] | Generates NANs +| https://en.cppreference.com/w/cpp/numeric/math/nan[nan] | Generates Quiet NANs with Payload +| https://en.cppreference.com/w/cpp/numeric/math/nan[snan] | Generates Signaling NANs with Payload (Non-Standard) |=== [source, c++] @@ -69,10 +72,23 @@ constexpr decimal32_t nand32(const char* arg) noexcept; constexpr decimal64_t nand64(const char* arg) noexcept; constexpr decimal128_t nand128(const char* arg) noexcept; +constexpr decimal_fast32_t nand32f(const char* arg) noexcept; +constexpr decimal_fast64_t nand64f(const char* arg) noexcept; +constexpr decimal_fast128_t nand128f(const char* arg) noexcept; + +constexpr decimal32_t snand32(const char* arg) noexcept; +constexpr decimal64_t snand64(const char* arg) noexcept; +constexpr decimal128_t snand128(const char* arg) noexcept; + +constexpr decimal_fast32_t snand32f(const char* arg) noexcept; +constexpr decimal_fast64_t snand64f(const char* arg) noexcept; +constexpr decimal_fast128_t snand128f(const char* arg) noexcept; + } // namespace decimal } // namespace boost ---- +[#cmath_exp] == Exponential Functions |=== @@ -118,7 +134,8 @@ constexpr DecimalType log1p(DecimalType x) noexcept; } // namespace boost ---- -=== Power Functions +[#cmath_power_funcs] +== Power Functions |=== | Function | Description @@ -154,6 +171,7 @@ constexpr DecimalType hypot(DecimalType x, DecimalType y, DecimalType z) noexcep } // namespace boost ---- +[#cmath_trig_funcs] == Trigonometric Functions |=== @@ -199,7 +217,7 @@ constexpr DecimalType atan2(DecimalType x, DecimalType y) noexcept; } // namespace boost ---- - +[#cmath_hyperbolic_funcs] == Hyperbolic Functions |=== @@ -241,6 +259,7 @@ constexpr DecimalType atanh(DecimalType x) noexcept; } // namespace boost ---- +[#cmath_error_funcs] == Error and Gamma Functions |=== @@ -274,6 +293,7 @@ constexpr DecimalType lgamma(DecimalType x) noexcept; } // namespace boost ---- +[#cmath_nearest_int] == Nearest integer floating point operations |=== @@ -330,7 +350,8 @@ constexpr long long llrint(DecimalType x) noexcept; } // namespace boost ---- -== Floating point manipulation functions +[#cmath_manipulation_funcs] +== Floating Point Manipulation Functions |=== | Function | Description @@ -387,7 +408,8 @@ constexpr DecimalType copysign(DecimalType mag, DecimalType sgn) noexcept; } // namespace boost ---- -== Classification and comparison +[#cmath_classification] +== Classification and Comparison |=== | Function | Description @@ -448,7 +470,10 @@ constexpr bool isunordered(DecimalType x, DecimalType y) noexcept; } // namespace boost ---- -== C++17 Mathematical Special Functions +[#cmath_spec_fun] +== Special Functions + +These are the special functions that were added in pass:[C++17]. NOTE: This section does not currently contain all functions specified by C++17, but it does contain the ones that are more commonly useful like the Beta Function. @@ -519,7 +544,7 @@ constexpr DecimalType riemann_zeta(IntegralType n) noexcept; The following are convenience functions, or are prescribed in IEEE 754-2019 as required for decimal floating point types. -=== issignaling +=== `issignaling` [source, c++] ---- @@ -528,8 +553,22 @@ constexpr bool issignaling(Decimal x) noexcept; ---- Effects: If x is an sNaN returns true, otherwise returns false. +This function does not signal even if x is an sNaN per IEEE 754 section 5.7.2. + +=== `read_payload` + +[source, c++] +---- +template +constexpr auto read_payload(Decimal x) noexcept + -> typename T::significand_type; +---- + +Effects: if x is either a qNaN or an sNaN, returns the payload of the NaN, otherwise returns 0. -=== samequantum +This function allows the payloads of nans that are set by the functions xref:basic_cmath_ops[`nan`] or xref:basic_cmath_ops[`snan`] to be returned. + +=== `samequantum` [source, c++] ---- @@ -555,7 +594,7 @@ If both x and y are NaN, or infinity, they have the same quantum exponents. If exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -=== quantexp +=== `quantexp` [source, c++] ---- @@ -579,7 +618,7 @@ Effects: if x is finite, returns its quantum exponent. Otherwise, `INT_MIN` is returned. -=== quantized +=== `quantized` [source, c++] ---- @@ -615,7 +654,7 @@ If both operands are infinity, the result is infinity, with the same sign as x. The quantize functions do not signal underflow. -=== frexp10 +=== `frexp10` [source, c++] ---- @@ -633,6 +672,7 @@ constexpr auto frexp10(Decimal num, int* expptr) noexcept; This function is very similar to https://en.cppreference.com/w/cpp/numeric/math/frexp[frexp], but returns the significand and an integral power of 10 since the `FLT_RADIX` of this type is 10. The significand is normalized to the number of digits of precision the type has (e.g. for decimal32_t it is [1'000'000, 9'999'999]). +For further discussion on normalized form see the page on xref:cohorts.adoc[cohorts]. === `normalize` @@ -651,7 +691,7 @@ constexpr Decimal normalize(Decimal val) noexcept; ---- Similar to the `frexp10` function above, but rather than returning the normalized significand, and exponent of the Decimal number, it returns a normalized number. -This removes the effects of xref:basics.adoc[cohorts] on the IEEE 754 compliant types. +This removes the effects of xref:cohorts.adoc[cohorts] on the IEEE 754 compliant types which for the example of `decimal32_t` means the significand will be in the range [1'000'000, 9'999'999]. This function has *NO* effect on fast types since they are always normalized internally. === `rescale` @@ -672,3 +712,47 @@ constexpr Decimal rescale(Decimal val, int precision = 0); The function returns the decimal type with number of fractional digits equal to the value of precision. `rescale` is similar to https://en.cppreference.com/w/cpp/numeric/math/trunc[trunc], and with the default precision argument of 0 it is identical. + +NOTE: This function was previously known as `trunc_to` which was deprecated in v5.0.0 and removed in v6.0.0 + +=== `comparetotal` + +[source, c++] +---- +#include + +namespace boost { +namespace decimal { + +template +constexpr bool comparetotal(DecimalType x, DecimalType y) noexcept; + +} // namespace decimal +} // namespace boost +---- + +This function is an extended version of normal ordering to take into account payloads of NANs, and canonical forms. + +Effects: + +. If x < y returns `true` + +. If x > y returns `false` + +. If x == y: +.. -0 < +0 is `true` +.. +0 < -0 is `false` +.. If x and y have the same sign: +... If x and y are both negative, `comparetotal(x, y)` is `true` IFF the exponent of x pass:[>=] exponent of y +... Otherwise, `comparetotal(x, y)` is `true` IFF the exponent of x pass:[<=] y + +. If x and y are unordered because x or y is a NAN: +.. `comparetotal(-NAN, y)` is `true` +.. `comparetotal(x, +NAN)` is `true` +.. If x and y are both NAN: +... `comparetotal(-NAN, +NAN)` returns `true` +... `comparetotal(+SNAN, +QNAN)` returns `true` +... `comparetotal(-QNAN, -SNAN)` returns `true` +... `comparetotal(NAN, NAN)` +.... If both `NAN` are positive returns `true` if the payload of `x` is less than the payload of `y` +.... If both `NAN` are negative returns `true` if the payload of `x` is greater than the payload of `y` diff --git a/doc/modules/ROOT/pages/cohorts.adoc b/doc/modules/ROOT/pages/cohorts.adoc new file mode 100644 index 000000000..f05f4b1c0 --- /dev/null +++ b/doc/modules/ROOT/pages/cohorts.adoc @@ -0,0 +1,106 @@ +//// +Copyright 2025 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#cohorts] += Cohorts +:idprefix: cohorts_ + +As stated in the library overview, one of the major differences between binary floating point and decimal floating point is the existence of cohorts. +From IEEE 754-2008: "The set of representations a floating-point number maps to is called the floating-point +number’s cohort; the members of a cohort are distinct representations of the same floating-point number." + +For example `decimal32_t` has a precision of 7. +That means all the following are valid ways to represent the number 300 using that type: + +. 3e+2 +. 30e+1 +. 300e+0 +. 3000e-1 +. 30000e-2 +. 300000e-3 +. 3000000e-4 + +These values can be useful in certain applications, like preserving the precision of results. +A value is said to be *normalized* when the effects of these cohorts is removed. +This is done by appending zeros to the significand and reducing the exponent until the significand has the same number of significant digits as the type can represent. +For example 1 - 6 above would all be represented the same as value 7. +By default, most methods *DO NOT* observe cohorts. +Below is an example of how cohorts can be preserved if one so wishes. + +== Cohort Preserving `` Example + +This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/charconv_cohort_preservation.cpp[charconv_cohort_preservation.cpp]. + +[source, c++] +---- +include::example$charconv_cohort_preservation.cpp[] +---- + +Expected Output: +---- +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3e+02 + +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3.0e+02 + +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3.00e+02 + +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3.000e+02 + +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3.0000e+02 + +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Values are equal and NOT bitwise equal. +Successful Roundtrip of value: 3.00000e+02 + +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and NOT bitwise equal. +Values are equal and bitwise equal. +Successful Roundtrip of value: 3.000000e+02 +---- diff --git a/doc/modules/ROOT/pages/config.adoc b/doc/modules/ROOT/pages/config.adoc index d23ebc7ce..c0b300b88 100644 --- a/doc/modules/ROOT/pages/config.adoc +++ b/doc/modules/ROOT/pages/config.adoc @@ -22,7 +22,9 @@ The following configuration macros are available: - `BOOST_DECIMAL_DISABLE_EXCEPTIONS`: This allows the user to disable any calls to `throw`. This macro will also be set automatically in the presence of `-fno-exceptions` or various `/EH` flags on MSVC. -- `BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS`: Allows a binary floating-point type (e.g. `double`) to be implicitly converted to a decimal floating point type. +- `BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS`: Allows any integer type to be implicitly converted to any decimal type. + +- `BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS`: Allows a binary floating-point type (e.g. `double`) to be implicitly converted to a decimal floating point type. This option is not recommended, but can be useful if you want to use specific functionality from the standard library with internal conversions such as: [source, c++] @@ -36,6 +38,8 @@ std::complex test_val {half, half}; const auto res = std::acos(test_val); ---- +- `BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS`: Defines both `BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS` and `BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS` + - `BOOST_DECIMAL_FAST_MATH` performs optimizations similar to that of the `-ffast-math` compiler flag such as removing all checks for non-finite values. This flag increases the performance of the basis operations (e.g. add, sub, mul, div, and comparisons) by up to 20%. Again, it must be defined before inclusion of decimal headers like so: @@ -46,19 +50,13 @@ Again, it must be defined before inclusion of decimal headers like so: #include ---- -- `BOOST_DECIMAL_DEC_EVAL_METHOD`: See section for explanation +- `BOOST_DECIMAL_DEC_EVAL_METHOD`: See xref:cfloat.adoc[``] section for explanation [#configuration_automatic] == Automatic Configuration Macros - `BOOST_DECIMAL_CXX20_CONSTEXPR`: This is defined to `constexpr` when compiling with C++20 or greater, otherwise it expands to nothing. -- `BOOST_DECIMAL_CONSTEXPR`: This is defined to `constexpr` when any of the following are met: - * _MSC_FULL_VER >= 192528326 - * __GNUC__ >= 9 - * Compiler has: __builtin_is_constant_evaluated() - * C++20 support with: std::is_constant_evaluated() - - `BOOST_DECIMAL_HAS_STD_CHARCONV`: This macro is defined if header `` exists and the language standard used is >= C++17 * We only need the structs and enums out of the header so we are not concerned with being overly restrictive about the feature test macros. ** Known compilers that support this lighter requirement are: GCC >= 10, Clang >= 13, and MSVC >= 14.2 diff --git a/doc/modules/ROOT/pages/conversions.adoc b/doc/modules/ROOT/pages/conversions.adoc index fe719c1c8..1cbf5d2f5 100644 --- a/doc/modules/ROOT/pages/conversions.adoc +++ b/doc/modules/ROOT/pages/conversions.adoc @@ -9,6 +9,7 @@ https://www.boost.org/LICENSE_1_0.txt :idprefix: conversions_ IEEE 754 specifies two different encodings for decimal floating point types: Binary Integer Significand Field (BID), and Densely Packed Decimal Significand Field (DPD). +The former is designed for software implementations and the latter for hardware implementations. Internally this library is implemented in the BID format for the IEEE-754 compliant types. Should the user want to capture the bit format in BID or convert to DPD we offer a family of conversion functions: `to_bid`, `from_bid`, `to_dpd`, and `from_dpd` that allow conversion to or from the bit strings regardless of encoding. @@ -16,20 +17,17 @@ Should the user want to capture the bit format in BID or convert to DPD we offer ---- #include #include +#include namespace boost { namespace decimal { -namespace detail { - struct uint128_t { std::uint64_t high; std::uint64_t low; }; -} // namespace detail - // ----- BID Conversions ----- constexpr std::uint32_t to_bid_d32(decimal32_t val) noexcept; @@ -48,9 +46,9 @@ constexpr std::uint64_t to_bid_d64f(decimal_fast64_t val) noexcept; constexpr decimal_fast64_t from_bid_d64f(std::uint64_t bits) noexcept; -constexpr detail::uint128 to_bid_d128(decimal128_t val) noexcept; +constexpr uint128_t to_bid_d128(decimal128_t val) noexcept; -constexpr decimal128_t from_bid_d128(detail::uint128 bits) noexcept; +constexpr decimal128_t from_bid_d128(uint128_t bits) noexcept; // Automatic detection if your platform has built-in unsigned __int128 or not to enable/disable the overload #ifdef BOOST_DECIMAL_HAS_INT128 @@ -59,9 +57,9 @@ constexpr decimal128_t from_bid_d128(unsigned __int128 bits) noexcept; #endif // BOOST_DECIMAL_HAS_INT128 -constexpr detail::uint128_t to_bid_d128f(decimal_fast128_t val) noexcept; +constexpr uint128_t to_bid_d128f(decimal_fast128_t val) noexcept; -constexpr decimal128_t from_bid_d128f(detail::uint128_t bits) noexcept; +constexpr decimal128_t from_bid_d128f(uint128_t bits) noexcept; #ifdef BOOST_DECIMAL_HAS_INT128 @@ -79,7 +77,7 @@ template constexpr T from_bid(std::uint64_t bits) noexcept; template -constexpr T from_bid(detail::uint128 bits) noexcept; +constexpr T from_bid(uint128_t bits) noexcept; // ----- DPD Conversions ----- @@ -91,9 +89,9 @@ constexpr std::uint64_t to_dpd_d64(decimal64_t val) noexcept; constexpr std::uint64_t to_dpd_d64f(decimal_fast64_t val) noexcept; -constexpr detail::uint128 to_dpd_d128(decimal128_t val) noexcept; +constexpr uint128_t to_dpd_d128(decimal128_t val) noexcept; -constexpr detail::uint128 to_dpd_d128f(decimal_fast128_t val) noexcept; +constexpr uint128_t to_dpd_d128f(decimal_fast128_t val) noexcept; template constexpr auto to_dpd(T val) noexcept; @@ -105,13 +103,66 @@ template constexpr T from_dpd(std::uint64_t bits) noexcept; template -constexpr T from_dpd(detail::uint128 bits) noexcept; +constexpr T from_dpd(uint128_t bits) noexcept; #ifdef BOOST_DECIMAL_HAS_INT128 + template constexpr T from_dpd(unsigned __int128 bits) noexcept; + #endif } // namespace decimal } // namespace boost ---- + +== Bit Conversions Example + +The following example is copied and pasted from the examples/ folder of the library and is called https://github.com/cppalliance/decimal/blob/develop/examples/bit_conversions.cpp[bit_conversions.cpp]. + +[source, c++] +---- +#include +#include +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; + using boost::decimal::from_bid; + using boost::decimal::from_dpd; + using boost::decimal::to_bid; + using boost::decimal::to_dpd; + + // First we construct a decimal value and then convert it into both BID and DPD encoded bits + const decimal32_t decimal_value {5}; + const std::uint32_t BID_bits {to_bid(decimal_value)}; + const std::uint32_t DPD_bits {to_dpd(decimal_value)}; + + // Display the difference between the hex values of both bit encodings + std::cout << std::hex + << "BID format: " << BID_bits << '\n' + << "DPD format: " << DPD_bits << std::endl; + + // Recover the original value by encoding two new decimals using the from_bid and from_dpd functions + const decimal32_t bid_decimal {from_bid(BID_bits)}; + const decimal32_t dpd_decimal {from_dpd(DPD_bits)}; + + if (bid_decimal == dpd_decimal) + { + // These should both have recovered the original value of 5 + return 0; + } + else + { + // Something has gone wrong recovering the decimal values + return 1; + } +} +---- +Output: +---- +BID format: 32800005 +DPD format: 22500005 +---- diff --git a/doc/modules/ROOT/pages/cstdio.adoc b/doc/modules/ROOT/pages/cstdio.adoc index 323f21773..db7dea146 100644 --- a/doc/modules/ROOT/pages/cstdio.adoc +++ b/doc/modules/ROOT/pages/cstdio.adoc @@ -5,7 +5,7 @@ https://www.boost.org/LICENSE_1_0.txt //// [#cstdio] -= `` support += `` Support :idprefix: cstdio_ The following functions analogous to those from `` are provided: @@ -30,6 +30,8 @@ int printf(const char* format, Dec... values) noexcept; } //namespace boost ---- +These functions are limited in their support to only decimal floating point types, and are not a complete replacement for their `std::` equivalents. + == Type Modifiers The type modifiers to be used are: diff --git a/doc/modules/ROOT/pages/cstdlib.adoc b/doc/modules/ROOT/pages/cstdlib.adoc index 93a4f85c8..c9b39a0b0 100644 --- a/doc/modules/ROOT/pages/cstdlib.adoc +++ b/doc/modules/ROOT/pages/cstdlib.adoc @@ -5,10 +5,10 @@ https://www.boost.org/LICENSE_1_0.txt //// [#cstdlib] -= `` support += `` Support :idprefix: cstdlib_ -The following functions analogous to those from `` are provided: +The following functions analogous to those from https://en.cppreference.com/w/cpp/string/byte/strtof.html[``] are provided: [source, c++] ---- diff --git a/doc/modules/ROOT/pages/debugger.adoc b/doc/modules/ROOT/pages/debugger.adoc new file mode 100644 index 000000000..4603ca5aa --- /dev/null +++ b/doc/modules/ROOT/pages/debugger.adoc @@ -0,0 +1,63 @@ +//// +Copyright 2025 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#debug] += Debugger Support +:idprefix: debug_ + +Currently, Boost.Decimal supports pretty printing with LLDB and GDB. + +== LLDB + +To load the pretty printer, add the following line to your `.lldbinit`: + +[source] +---- +command script import /path/to/decimal/extra/decimal_printer_lldb.py +---- + +== GDB + +To load the pretty printer, add the following line to your `.gdbinit`: + +[source] +---- +source /path/to/decimal/extra/decimal_printer_gdb.py +---- + +or you can source it manually in GDB: + +[source] +---- +(gdb) source /path/to/decimal/extra/decimal_printer_gdb.py +---- + +== Example + +Once you have loaded a pretty printer, you can run the below example to see how different values are represented with the pretty printer. +This expected output of the example below was taken from LLDB, but the results should be quite similar when using GDB. + +.The following example can be run with the debugger to show a variety of values +==== + +[source,c++] +---- +include::example$debugger.cpp[] +---- + +*_Expected Output for T = decimal32_t:_* + +image::dec32_debug.png[] + +*_Expected Output for T = decimal_fast32_t:_* + +image::dec32_fast_debug.png[] +==== + +The reason for the difference in how `decimal32_t` and `decimal_fast32_t` is displayed is due to xref:cohorts.adoc[Cohorts and Normalization] + +. `decimal32_t`, `decimal64_t` and `decimal128_t` debuggers are cohort preserving +. `decimal_fast32_t`, `decimal_fast64_t` and `decimal_fast128_t` debuggers are always normalized diff --git a/doc/modules/ROOT/pages/decimal128_t.adoc b/doc/modules/ROOT/pages/decimal128_t.adoc index 6cc18da6d..c423bc513 100644 --- a/doc/modules/ROOT/pages/decimal128_t.adoc +++ b/doc/modules/ROOT/pages/decimal128_t.adoc @@ -22,6 +22,9 @@ https://www.boost.org/LICENSE_1_0.txt | Smallest Subnormal Value | 1e-6176 |=== +IMPORTANT: Prior to v5.0.0 this type was known as `decimal32`. +This name has been removed in v6.0.0. + The encoding of decimal128_t is in the `xref:conversions.adoc[BID format]`. [source, c++] @@ -51,11 +54,20 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept; template explicit constexpr decimal128_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal128_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal128_t(const std::string& str); +#else +explicit constexpr decimal128_t(std::string_view str); +#endif + template -constexpr decimal128_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal128_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template -constexpr decimal128_t(SignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal128_t(SignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal128_t& operator=(const Integeral& RHS) noexcept; @@ -94,7 +106,10 @@ explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; }; // class decimal128_t @@ -102,3 +117,136 @@ explicit constexpr operator decimal64_t() const noexcept; } //namespace boost ---- + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal128_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal128_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal128_t(const std::string& str); +#else +explicit constexpr decimal128_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal128_t& operator++(); +constexpr decimal128_t operator++(int); +constexpr decimal128_t& operator--(); +constexpr decimal128_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal128_t& operator+=(RHS rhs); +constexpr decimal128_t& operator-=(RHS rhs); +constexpr decimal128_t& operator*=(RHS rhs); +constexpr decimal128_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; +---- + +Conversion to `decimal_fast128_t` is lossless in all cases. + +Conversion to all other decimal types is subject to: + +. Current rounding mode if the number of digits exceeds the precision of the target type. +. Overflow constructs `INF`. +. Underflow constructs `0`. + +== Non-Member Operator Behavior + +See xref:generic_decimal.adoc#operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/decimal32_t.adoc b/doc/modules/ROOT/pages/decimal32_t.adoc index fb3b7aebe..1d0a5004b 100644 --- a/doc/modules/ROOT/pages/decimal32_t.adoc +++ b/doc/modules/ROOT/pages/decimal32_t.adoc @@ -22,6 +22,9 @@ https://www.boost.org/LICENSE_1_0.txt | Smallest Subnormal Value | 1e-101 |=== +IMPORTANT: Prior to v5.0.0 this type was known as `decimal32`. +This name has been removed in v6.0.0. + The encoding of decimal32_t is in the `xref:conversions.adoc[BID format]`. [source, c++] @@ -43,7 +46,7 @@ public: // 3.2.2.1 construct/copy/destroy constexpr decimal32_t() noexcept = default; -// 3.2.2.2 Conversion form floating-point type +// 3.2.2.2 Conversion from floating-point type template explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t(Float val) noexcept; @@ -51,8 +54,17 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t(Float val) noexcept; template explicit constexpr decimal32_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal32_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal32_t(const std::string& str); +#else +explicit constexpr decimal32_t(std::string_view str); +#endif + template -constexpr decimal32_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal32_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal32_t(SignedIntegral coeff, Integral exp) noexcept; @@ -93,8 +105,11 @@ explicit constexpr operator std::float32_t() const noexcept; explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; }; // class decimal32_t @@ -102,3 +117,130 @@ explicit constexpr operator decimal128_t() const noexcept; } //namespace boost ---- + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal32_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal32_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal32_t(const std::string& str); +#else +explicit constexpr decimal32_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal32_t& operator++(); +constexpr decimal32_t operator++(int); +constexpr decimal32_t& operator--(); +constexpr decimal32_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal32_t& operator+=(RHS rhs); +constexpr decimal32_t& operator-=(RHS rhs); +constexpr decimal32_t& operator*=(RHS rhs); +constexpr decimal32_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; +---- + +Losslessly converts the current decimal value to all other decimal types. + +== Non-Member Operator Behavior + +See xref:generic_decimal.adoc#operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/decimal64_t.adoc b/doc/modules/ROOT/pages/decimal64_t.adoc index 380b6bd79..004ff5fe8 100644 --- a/doc/modules/ROOT/pages/decimal64_t.adoc +++ b/doc/modules/ROOT/pages/decimal64_t.adoc @@ -22,6 +22,9 @@ https://www.boost.org/LICENSE_1_0.txt | Smallest Subnormal Value | 1e-398 |=== +IMPORTANT: Prior to v5.0.0 this type was known as `decimal64`. +This name has been removed in v6.0.0. + The encoding of decimal64_t is in the `xref:conversions.adoc[BID format]`. [source, c++] @@ -51,8 +54,17 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t(Float val) noexcept; template explicit constexpr decimal64_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal64_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal64_t(const std::string& str); +#else +explicit constexpr decimal64_t(std::string_view str); +#endif + template -constexpr decimal64_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal64_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal64_t(SignedIntegral coeff, Integral exp) noexcept; @@ -94,7 +106,10 @@ explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; }; // class decimal64_t @@ -102,3 +117,136 @@ explicit constexpr operator decimal128_t() const noexcept; } //namespace boost ---- + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal64_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal64_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal64_t(const std::string& str); +#else +explicit constexpr decimal64_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal64_t& operator++(); +constexpr decimal64_t operator++(int); +constexpr decimal64_t& operator--(); +constexpr decimal64_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal64_t& operator+=(RHS rhs); +constexpr decimal64_t& operator-=(RHS rhs); +constexpr decimal64_t& operator*=(RHS rhs); +constexpr decimal64_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; +---- + +Conversion to `decimal32_t or `decimal_fast32_t` is subject to: + +. Current rounding mode if the number of digits exceeds the precision of `decimal32_t` +. Overflow constructs `INF` +. Underflow constructs `0` + +Conversion to all other decimal types is lossless in all cases. + +== Non-Member Operator Behavior + +See xref:generic_decimal.adoc#operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/decimal_fast128_t.adoc b/doc/modules/ROOT/pages/decimal_fast128_t.adoc index b5d5a2acd..037450b45 100644 --- a/doc/modules/ROOT/pages/decimal_fast128_t.adoc +++ b/doc/modules/ROOT/pages/decimal_fast128_t.adoc @@ -24,7 +24,10 @@ As is often the case this trades space for time by having greater storage width | Smallest Subnormal Value | Flushed to 0 |=== -*IMPORTANT* `decimal_fast32_t` does not support subnormal values +IMPORTANT: `decimal_fast128_t` does not support subnormal values + +IMPORTANT: Prior to v5.0.0 this type was known as `decimal128_fast`. +This name has been removed in v6.0.0. [source, c++] ---- @@ -53,8 +56,17 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t(Float val) noexcept; template explicit constexpr decimal_fast128_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal_fast128_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast128_t(const std::string& str); +#else +explicit constexpr decimal_fast128_t(std::string_view str); +#endif + template -constexpr decimal_fast128_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal_fast128_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal_fast128_t(SignedIntegral coeff, Integral exp) noexcept; @@ -96,7 +108,10 @@ explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; }; // class decimal_fast128_t @@ -104,3 +119,137 @@ explicit constexpr operator decimal64_t() const noexcept; } //namespace boost ---- + + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal_fast128_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal_fast128_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast128_t(const std::string& str); +#else +explicit constexpr decimal_fast128_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal_fast128_t& operator++(); +constexpr decimal_fast128_t operator++(int); +constexpr decimal_fast128_t& operator--(); +constexpr decimal_fast128_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal_fast128_t& operator+=(RHS rhs); +constexpr decimal_fast128_t& operator-=(RHS rhs); +constexpr decimal_fast128_t& operator*=(RHS rhs); +constexpr decimal_fast128_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; +---- + +Conversion to `decimal128_t` is lossless in all cases. + +Conversion to any other decimal type is subject to: + +. Current rounding mode if the number of digits exceeds the precision of the target type. +. Overflow constructs `INF`. +. Underflow constructs `0`. + +== Non-Member Operator Behavior + +See xref:fast_types.adoc#fast_operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/decimal_fast32_t.adoc b/doc/modules/ROOT/pages/decimal_fast32_t.adoc index 47953a5df..ae6b1b911 100644 --- a/doc/modules/ROOT/pages/decimal_fast32_t.adoc +++ b/doc/modules/ROOT/pages/decimal_fast32_t.adoc @@ -24,7 +24,10 @@ As is often the case this trades space for time by having greater storage width | Smallest Subnormal Value | Flushed to 0 |=== -*IMPORTANT* `decimal_fast32_t` does not support subnormal values +IMPORTANT: `decimal_fast32_t` does not support subnormal values + +IMPORTANT: Prior to v5.0.0 this type was known as `decimal32_fast`. +This name has been removed in v6.0.0. [source, c++] ---- @@ -53,8 +56,17 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t(Float val) noexcept; template explicit constexpr decimal_fast32_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal_fast32_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast32_t(const std::string& str); +#else +explicit constexpr decimal_fast32_t(std::string_view str); +#endif + template -constexpr decimal_fast32_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal_fast32_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal_fast32_t(SignedIntegral coeff, Integral exp) noexcept; @@ -95,8 +107,11 @@ explicit constexpr operator std::float32_t() const noexcept; explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; +explicit constexpr operator decimal32_t() const noexcept; explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; }; // class decimal_fast32_t @@ -104,3 +119,130 @@ explicit constexpr operator decimal128_t() const noexcept; } //namespace boost ---- + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal_fast32_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal_fast32_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast32_t(const std::string& str); +#else +explicit constexpr decimal_fast32_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal_fast32_t& operator++(); +constexpr decimal_fast32_t operator++(int); +constexpr decimal_fast32_t& operator--(); +constexpr decimal_fast32_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal_fast32_t& operator+=(RHS rhs); +constexpr decimal_fast32_t& operator-=(RHS rhs); +constexpr decimal_fast32_t& operator*=(RHS rhs); +constexpr decimal_fast32_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal64_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; +---- + +Losslessly converts the current decimal value to other decimal type. + +== Non-Member Operator Behavior + +See xref:fast_types.adoc#fast_operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/decimal_fast64_t.adoc b/doc/modules/ROOT/pages/decimal_fast64_t.adoc index 7794b01b7..24515cf6b 100644 --- a/doc/modules/ROOT/pages/decimal_fast64_t.adoc +++ b/doc/modules/ROOT/pages/decimal_fast64_t.adoc @@ -24,7 +24,10 @@ As is often the case this trades space for time by having greater storage width | Smallest Subnormal Value | Flushed to 0 |=== -*IMPORTANT* `decimal_fast64_t` does not support subnormal values +IMPORTANT: `decimal_fast64_t` does not support subnormal values + +IMPORTANT: Prior to v5.0.0 this type was known as `decimal64_fast`. +This name has been removed in v6.0.0. [source, c++] ---- @@ -53,8 +56,17 @@ explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t(Float val) noexcept; template explicit constexpr decimal_fast64_t(Integer val) noexcept; +// Extension: Construction from (c)string +explicit constexpr decimal_fast64_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast64_t(const std::string& str); +#else +explicit constexpr decimal_fast64_t(std::string_view str); +#endif + template -constexpr decimal_fast64_t(UnsignedIntegral coeff, Integral exp, bool sign = false) noexcept; +constexpr decimal_fast64_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept; template constexpr decimal_fast64_t(SignedIntegral coeff, Integral exp) noexcept; @@ -96,7 +108,10 @@ explicit constexpr operator std::float64_t() const noexcept; explicit constexpr operator std::bfloat16_t() const noexcept; explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; }; // class decimal_fast64_t @@ -104,3 +119,136 @@ explicit constexpr operator decimal128_t() const noexcept; } //namespace boost ---- + +== Operator Behavior + +=== Construction to and from binary floating-point type + +[source, c++] +---- +// 3.2.2.2 Conversion from floating-point type +template +explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t(Float val) noexcept; + +// 3.2.6 Conversion to floating-point type +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; +explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + +// If C++23 and are available +explicit constexpr operator std::float16_t() const noexcept; +explicit constexpr operator std::float32_t() const noexcept; +explicit constexpr operator std::float64_t() const noexcept; +explicit constexpr operator std::bfloat16_t() const noexcept; +---- + +See: xref:binary_floating_conversions.adoc[] + +=== Construction From Integral Type + +[source,c++] +---- +// 3.2.2.3 Conversion from integral type +template +explicit constexpr decimal_fast64_t(Integer val) noexcept; +---- + +Constructs a decimal value subject to the current rounding mode (if necessary). + +=== Construction From String + +[source,c++] +---- +// Extension: Construction from (c)string +explicit constexpr decimal_fast64_t(const char* str); + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +explicit inline decimal_fast64_t(const std::string& str); +#else +explicit constexpr decimal_fast64_t(std::string_view str); +#endif +---- + +Constructs a decimal value that matches `str` subject to: + +. If `str` is a `nullptr` or of length 0 either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. If `str` is an invalid string either: +.. `throw std::runtime_error` +.. Constructs a `QNAN` in a no exception environment +. On overflow constructs `INF` +. On underflow constructs `0` +. Rounds value represented by `str` according to current rounding mode + +=== Conversion to Integral Type + +[source,c++] +---- +// 3.2.2.4 Conversion to integral type + +explicit constexpr operator int() const noexcept; +explicit constexpr operator unsigned() const noexcept; +explicit constexpr operator long() const noexcept; +explicit constexpr operator unsigned long() const noexcept; +explicit constexpr operator long long() const noexcept; +explicit constexpr operator unsigned long long() const noexcept; +---- + +Constructs an integer representation of the decimal value subject to: + +. If the decimal value is `INF` returns `std::numeric_limits::max()` +. If the decimal value is `NAN` returns `std::numeric_limits::max()` +. If the decimal value exceeds the range of the `IntegerType` returns `std::numeric_limits::max()` + +=== Increment and Decrement Operators + +[source,c++] +---- +// 3.2.2.5 increment and decrement operators: +constexpr decimal_fast64_t& operator++(); +constexpr decimal_fast64_t operator++(int); +constexpr decimal_fast64_t& operator--(); +constexpr decimal_fast64_t operator--(int); +---- + +Increments/Decrements the decimal value subject to: + +. If the decimal value is `NAN` returns `QNAN` +. If the decimal value is `INF` returns `INF` + +=== Compound Operators + +[source, c++] +---- +// 3.2.2.6 compound assignment: +constexpr decimal_fast64_t& operator+=(RHS rhs); +constexpr decimal_fast64_t& operator-=(RHS rhs); +constexpr decimal_fast64_t& operator*=(RHS rhs); +constexpr decimal_fast64_t& operator/=(RHS rhs); +---- + +Matches the behavior of xref:generic_decimal.adoc#operator_behavior[addition, subtraction, multiplication, and division]. + +=== Conversion to Other Decimal Types + +[source,c++] +---- +explicit constexpr operator decimal32_t() const noexcept; +explicit constexpr operator decimal_fast32_t() const noexcept; +explicit constexpr operator decimal_fast64_t() const noexcept; +explicit constexpr operator decimal128_t() const noexcept; +explicit constexpr operator decimal_fast128_t() const noexcept; +---- + +Conversion to `decimal32_t` or `decimal_fast32_t` is subject to: + +. Current rounding mode if the number of digits exceeds the precision of `decimal32_t` +. Overflow constructs `INF` +. Underflow constructs `0` + +Conversion to `decimal128_t` or `decimal_fast128_t` is lossless in all cases. + +== Non-Member Operator Behavior + +See xref:fast_types.adoc#fast_operator_behavior[here] for behavior of non-member operators. diff --git a/doc/modules/ROOT/pages/design.adoc b/doc/modules/ROOT/pages/design.adoc index e9a23ebb3..a7465dd75 100644 --- a/doc/modules/ROOT/pages/design.adoc +++ b/doc/modules/ROOT/pages/design.adoc @@ -5,7 +5,7 @@ https://www.boost.org/LICENSE_1_0.txt //// [#design] -= Design Decisions += Design Decisions and Standards Deviations :idprefix: design_ == C++14 Requirement @@ -20,7 +20,72 @@ This allows Boost.Decimal to better emulate the functionality a built-in type wo Boost.Math requires C++14 as the minimum language standard for the library. By meeting this requirement, and Boost.Math's conceptual requirements for a user-defined type we are able to provide the statistics, interpolation, quadrature, etc. out of the box. -=== No Binary Floating Point Operations -The library deliberately does not contain any operations between a binary floating point type and the decimal floating point types. -The rationale is similar to that of the library in the first place in that you may end up with surprising results. -Conversion operators and constructors are available for all decimal types should the user want to explicit cast one side of the operation to conduct the operation. +== IEEE Deviations + +=== `` Functions Do Not Meet the Definition of Correctly Rounded + +IEEE 754 specifies for correct rounding: "This standard’s method of converting an infinitely precise result to a floating-point number, as determined by the applicable rounding direction. A floating-point number so obtained is said to be correctly rounded." +None of these functions meet the definition of correctly rounded (which would imply precision of https://en.wikipedia.org/wiki/Unit_in_the_last_place[0.5 ULP]). +From the https://www.netlib.org/misc/intel/README.txt[Intel libdfp README]: "binary floating-point mathematical functions +implemented for example in C or other compiler math libraries are in general +not correctly rounded either". +Technically IEEE 754 differentiates the specification for mandatory operations (e.g. `fma`, `sqrt`, etc.) in Clause 5, and recommended operations (e.g. `exp`, `log`, etc.) in Clause 9, but our statement about half ULP precision applies to all non-boolean result `` functions. +This does not apply to Clause 5 functions like `isnan` which has a boolean result because ULP precision does not apply. + +=== Floating Point Exception Flags are not Supported + +The normal method in pass:[C++] to set and get the current floating point exception flags is via http://en.cppreference.com/w/cpp/numeric/fenv/feexceptflag.html[`std::fegetexceptflag` and `std::fesetexceptflag`]. +The decision then becomes do we support `constexpr` or floating point exceptions? +We find that the former is far more useful than the latter. +The alternative to would be to use C style functions such as: + +[source, C++] +---- +decimal64_t dec64_add(decimal64_t a, decimal64_t b, rounding_mode round, int* floating_point_flags); +---- + +This style of function is used in Intel libdfp because it is a C library. +We find this to be unidiomatic and unergonomic for a modern pass:[C++] library. + +== C++ Standards Deviations + +=== `from_chars` Distinguishes Overflow from Underflow + +`std::from_chars` has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. +The standard for does not distinguish between underflow and overflow like strtod does. +`boost::decimal::from_chars` modifies `value` in order to communicate this to the user in a divergence from the standard. +This behavior is the same as that of https://www.boost.org/doc/libs/master/libs/charconv/doc/html/charconv.html#from_chars_usage_notes_for_from_chars_for_floating_point_types[`boost::charconv::from_chars_erange`]. + +=== `from_chars` Supports Rounding Mode + +The pass:[C++] specification states that `from_chars` resulting value is to be rounded to nearest. +Since the types in this library are more sensitive to rounding mode differences, `from_chars` rounds using the current global rounding mode as reported by `fegetround()`. + +=== `from_chars` and `to_chars` both have an additional `chars_format` option + +In order to support an IEEE 754 requirement to print a value to include its cohort information we introduced an additional `chars_format` option, `cohort_preserving_scientific`. +Cohort preservation only makes sense in scientific format because it is the actual representation of the layout of the type, and thus no other cohort preserving formats are supported. + +[#non-finite-deviation] +=== `istream` of Non-finite Values is Allowed + +Unlike built-in binary floating point types the library allows input of non-finite values such as the below: + +[source, c++] +---- +std::istringstream is("INF"); +decimal32_t x; +is >> x; +const auto endpos {is.tellg()}; + +assert(isinf(x)); +assert(endpos == 3); +---- + +The result of `tellg()` will only parse until a complete non-finite value is found and then terminate. +For example `nanfinity` will construct a `NAN` and set `endpos = 3`, or `nan(snan)JUNK` will construct `SNAN` and set `endpos = 9` since `nan(snan)` contains a valid payload. +This is designed to match the value of `r.ptr` in xref:charconv.adoc[``]. + +=== Locale Facets are Unsupported + +Facets as discussed in https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf[N2849] section 3.10 are unimplemented. diff --git a/doc/modules/ROOT/pages/examples.adoc b/doc/modules/ROOT/pages/examples.adoc index a09b7ec65..be05b45bb 100644 --- a/doc/modules/ROOT/pages/examples.adoc +++ b/doc/modules/ROOT/pages/examples.adoc @@ -8,312 +8,403 @@ https://www.boost.org/LICENSE_1_0.txt = Examples :idprefix: examples_ -All examples can be found in the library `examples/` folder as well. +The following examples will help you get up and running with many of the major parts of the library. +All of these examples can be found in the library `examples/` folder as well. [#examples_construction] -== Construction from an Integer and Exponent - +== Basic Construction +.This https://github.com/cppalliance/decimal/blob/develop/examples/basic_construction.cpp[example] demonstrates the basic use of the various constructors offered by the decimal types +==== [source, c++] ---- -#include -#include - -int main() -{ - constexpr boost::decimal::decimal32_t a {2, -1}; // Constructs the number 0.2 - constexpr boost::decimal::decimal32_t b {1, -1}; // Constructs the number 0.1 - boost::decimal::decimal32_t sum {a + b}; - - std::cout << sum << std::endl; // prints 0.3 - - const boost::decimal::decimal32_t neg_a {2, -1, true}; // Constructs the number -0.2 - - sum += neg_a; - - std::cout << sum << std::endl; // Prints 0.1 - - return 0; -} +include::example$basic_construction.cpp[] ---- -This is the recommended way of constructing a fractional number as opposed to `decimal32_t a {0.2}`. -The representation is exact with integers whereas you may get surprising or unwanted conversion from binary floating point - -[#examples_promotion] -== Promotion - +.Expected Output +.... +Val_1: 100 +Val_2: 100 +Val_3: -100 +Overflow constructs infinity +Underflow constructs zero +NaN constructs NaN +Values constructed from const char* and std::string are the same +Can not construct from invalid string +.... +==== + +[#examples_basic_math] +== Basic Arithmetic + +.This https://github.com/cppalliance/decimal/blob/develop/examples/basic_arithmetic.cpp[example] demonstrates the behavior and functionality of arithmetic using a single type +==== [source, c++] ---- -#include -#include -#include - -int main() -{ - using namespace boost::decimal; - - decimal32_t x {1}; // Constructs from an integer - decimal64_t y {2}; - - auto sum {x + y}; - - assert(std::is_same::value); - - return 0; -} +include::example$basic_arithmetic.cpp[] ---- -[#examples_charconv] -== charconv - -[source, c++] +.Expected Output: +.... +A: -5.123456891234567 +B: 3.123456891234567 +A + B: -2 +abs(A + B): 2 +sqrt(abs(A + B)): 1.414213562373095 +Wolfram Alpha sqrt(2): 1.414213562373095 +.... +==== + +[#examples_math_results] +.This https://github.com/cppalliance/decimal/blob/develop/examples/addition.cpp[example] shows the differences in arithmetic results between decimal floating point and binary floating point +==== +[source,c++] +---- +include::example$addition.cpp[] ---- -#include -#include -#include - -int main() -{ - using namespace boost::decimal; - - decimal64_t val {0.25}; // Construction from a double (not recommended but explicit construction is allowed) - char buffer[256]; - auto r_to = to_chars(buffer, buffer + sizeof(buffer) - 1, val); - assert(r_to); // checks std::errc() - *r_to.ptr = '\0'; +.Expected Output: +.... +Decimal Result: 100 + Float Result: 99.999 +.... +==== - decimal64_t return_value; - auto r_from = from_chars(buffer, buffer + std::strlen(buffer), return_value); - assert(r_from); +[#examples_conversions] +== Conversions - assert(val == return_value); +[#examples_integer_conversions] +=== Integral Conversions - std::cout << " Initial Value: " << val << '\n' - << "Returned Value: " << return_value << std::endl; +.This https://github.com/cppalliance/decimal/blob/develop/examples/integral_conversions.cpp[example] shows how to construct an integral value from decimal type and vice versa, as well as the behavior - return 0; -} +==== +[source, c++] ---- -Output: +include::example$integral_conversions.cpp[] ---- - Initial Value: 0.25 -Returned Value: 0.25 + +.Expected Output +.... +Decimal QNAN converts to Integer Max +Decimal INF converts to Integer Max + decimal64_t pi: 3.141592653589793 +std::uint32_t pi: 3 + +Conversions will be lossless + decimal64_t digits10: 16 +std::uint32_t digits10: 9 + std::uint32_t max: 4294967295 +decimal64_t from max: 4294967295 + +Conversions will be lossy + decimal32_t digits10: 7 +std::uint64_t digits10: 19 + std::uint64_t max: 18446744073709551615 +decimal32_t from max: 1.844674e+19 +.... +==== + +[#examples_binary_floating_conversions] +=== Binary Floating Point Conversions + +.This https://github.com/cppalliance/decimal/blob/develop/examples/binary_float_conversions.cpp[example] shows how to construct a binary floating point value from decimal type and vice versa, as well as the behavior +==== +[source,c++] +---- +include::example$binary_float_conversions.cpp[] ---- -[#examples_rounding_mode] -== Rounding Mode +.Expected Output: +.... +Decimal QNAN converts to double QNAN +Decimal INFINITY converts to double INFINITY +decimal64_t pi: 3.141592653589793 + double pi: 3.141592653589793 + Converted pi: 3.141592653589793 +decimal32_t pi: 3.141593 +.... +==== + +[#examples_promotion] +== Promotion and Mixed Decimal Arithmetic + +.This https://github.com/cppalliance/decimal/blob/develop/examples/promotion.cpp[example] demonstrates the behaviors of promotion between types, and mixed decimal type arithmetic +==== [source, c++] ---- -#include -#include - -int main() -{ - auto default_rounding_mode = boost::decimal::fegetround(); // Default is fe_dec_to_nearest_from_zero +include::example$promotion.cpp[] +---- - auto new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_to_nearest); +.Expected Output: +.... +decimal32_t value (a): 5.2 +decimal64_t value (b): 3.9 +a is greater than b +5.2 is less than 1e+385 +1e+385 is less than inf +The result of a + b is a decimal64_t: 9.1 +The result of 2*c is a decimal64_t: 18.2 +18.2 is greater than 5 +.... +==== - assert(default_rounding_mode != new_rounding_mode); +[#examples_charconv] +== `` - return 0; -} +.This https://github.com/cppalliance/decimal/blob/develop/examples/charconv.cpp[example] demonstrates the fundamentals of the `` like functions provided by the library +==== +[source, c++] +---- +include::example$charconv.cpp[] ---- +.Expected Output: +.... +Initial decimal: -7123450 +Value from string: 3.1415 +Value in scientific format: -7.12345e+06 +Value in scientific format with precision 20: -7.12345000000000000000e+06 +.... +==== + [#examples_generic_programming] == Generic Programming +.This https://github.com/cppalliance/decimal/blob/develop/examples/adl.cpp[example] demonstrates how to write generic code that accepts both built-in floating point types, and decimal floating point values from this library +==== [source, c++] ---- -#include -#include -#include +include::example$adl.cpp[] +---- -int error_counter = 0; +Expected Output: +.... +Float: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 -template -bool float_equal(T lhs, T rhs) -{ - using std::fabs; - return fabs(lhs - rhs) < std::numeric_limits::epsilon(); // numeric_limits is overloaded for all decimal types -} +Double: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 -template -void test(T val) -{ - using std::sin; // ADL allows builtin and decimal types to both be used - if (!float_equal(sin(val), -sin(-val))) // sin(x) == -sin(-x) - { - ++error_counter; - } -} +Long Double: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 -int main() -{ - test(-0.5F); - test(-0.5); - test(-0.5L); +decimal32_t: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 - test(boost::decimal::decimal32_t{5, -1, true}); - test(boost::decimal::decimal64_t{5, -1, true}); - test(boost::decimal::decimal128_t{5, -1, true}); +decimal64_t: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 - return error_counter; -} ----- +decimal128_t: +sin(-0.5) = -0.479426 +-sin(0.5) = -0.479426 +.... +==== [#examples_literals_constants] == Literals and Constants +.This https://github.com/cppalliance/decimal/blob/develop/examples/literals.cpp[example] demonstrates how to construct values using literals, and the usage of numerical constants that are provided by the library +==== [source, c++] ---- -#include -#include - -template -bool float_equal(T lhs, T rhs) -{ - using std::fabs; - return fabs(lhs - rhs) < std::numeric_limits::epsilon(); // numeric_limits is overloaded for all decimal types -} - +include::example$literals.cpp[] +---- -int main() -{ - using namespace boost::decimal; +Expected Output: +.... +32-bit Pi: 3.141593 +64-bit Pi: 3.141592653589793 +32-bit UDL Pi: 3.141593 +Rounded UDL has the same value as the 32-bit constant +64-bit UDL Pi: 3.141592653589793 +Rounded UDL has the same value as the 64-bit constant +.... +==== - const auto pi_32 {"3.141592653589793238"_DF}; - const auto pi_64 {"3.141592653589793238"_DD}; +[#examples_format] +== Formatting - assert(float_equal(pi_32, static_cast(pi_64))); // Explicit conversion between decimal types - assert(float_equal(pi_32, boost::decimal::numbers::pi_v)); // Constants available in numbers namespace - assert(float_equal(pi_64, numbers::pi)); // Default constant type is decimal64_t +Boost.Decimal allows you to format your output with both `` and `` depending on your compiler support. +pass:[{fmt}] support is available starting with pass:[C++14] so long as you have the library available, but `` requires pass:[C++20] and compiler support - return 0; -} ----- +[#examples_fmt_format] +=== `` -[#examples_bit_conversions] -== Bit Conversions +.This https://github.com/cppalliance/decimal/blob/develop/examples/fmt_format.cpp[example] demonstrates the various formatting options provided by the library to support usage of pass:[{fmt}] +==== [source, c++] ---- -#include +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This example demonstrates usage and formatting of decimal types with fmt + +#include // For type decimal32_t +#include // For type decimal64_t +#include // For {fmt} support #include -#include - -using namespace boost::decimal; int main() { - const decimal_fast32_t fast_type {5}; - const std::uint32_t BID_bits {to_bid(fast_type)}; - const std::uint32_t DPD_bits {to_dpd(fast_type)}; - - std::cout << std::hex - << "BID format: " << BID_bits << '\n' - << "DPD format: " << DPD_bits << std::endl; - - const decimal32_t bid_decimal {from_bid(BID_bits)}; - const decimal32_t dpd_decimal {from_dpd(DPD_bits)}; + constexpr boost::decimal::decimal64_t val1 {"3.14"}; + constexpr boost::decimal::decimal32_t val2 {"3.141"}; + + // The easiest is no specification which is general format + // Given these values they will print in fixed format + std::cout << "Default Format:\n"; + std::cout << fmt::format("{}", val1) << '\n'; + std::cout << fmt::format("{}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + std::cout << "Scientific Format:\n"; + std::cout << fmt::format("{:e}", val1) << '\n'; + std::cout << fmt::format("{:e}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + // Here this gives one digit of precision rounded according to current rounding mode + std::cout << "Scientific Format with Specified Precision:\n"; + std::cout << fmt::format("{:.1e}", val1) << '\n'; + std::cout << fmt::format("{:.1e}", val2) << "\n\n"; + + // This combines the padding modifier (10), precision (3 digits), and a type modifier (e) + std::cout << "Scientific Format with Specified Precision and Padding:\n"; + std::cout << fmt::format("{:10.3e}", val1) << '\n'; + std::cout << fmt::format("{:10.3e}", val2) << '\n'; - return !(bid_decimal == dpd_decimal); + return 0; } ---- -Output: ----- -BID format: 31fc4b40 -DPD format: 35f00000 ----- - -[#examples_finance] -== Financial Applications -=== Simple Moving Average +Expected Output: +.... +Default Format: +3.14 +3.141 -In the examples folder there is a file named `moving_average.cpp`. -This example shows how to parse historical stock data from file and use it. -This serves as a framework for other calculations for securities. +Scientific Format: +3.14e+00 +3.141e+00 -=== Currency Conversion -In the examples folder there is a file named `currency_conversion.cpp`. -This example shows how to simply convert currencies based off a given exchange rate. +Scientific Format with Specified Precision: +3.1e+00 +3.1e+00 -[#examples_boost_math] -== Boost.Math Integration +Scientific Format with Specified Precision and Padding: +03.140e+00 +03.141e+00 +.... +==== -=== Bollinger Bands - -In the examples folder there is a file named `statistics.cpp`. -This example demonstrates how to parse a file, and then leverage Boost.Math to compute statistics of that data set culminating with the values of the Bollinger Bands. -This example could be extended with the simple moving average to create full bands based on the period of the moving average you would like. - -[#examples_format] -== Formatting - -Boost.Decimal allows you to format your output with both `` and `` depending on your compiler support. +IMPORTANT: If you are using the convenience header `` the header `` is *NOT* automatically included since it requires an external library. +You must include it yourself. [#examples_std_format] === `` -If your compiler provides `` you can use that to format the output of your values: +Taking the above example of pass:[{fmt}] and replacing all instances of `namespace fmt` with `namespace std` gives us another working example. +.This https://github.com/cppalliance/decimal/blob/develop/examples/format.cpp[example] demonstrates how to use `` with the library in-place or in addition to pass:[{fmt}] +==== [source, c++] ---- -#include -#include -#include +include::example$format.cpp[] +---- -int main() -{ - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; +.Expected Output: +.... +Default Format: +3.14 +3.141 - std::cout << std::format("{:10.3e}", val1) << '\n'; - std::cout << std::format("{:10.3e}", val2) << std::endl; +Scientific Format: +3.14e+00 +3.141e+00 - return 0; -} ----- +Scientific Format with Specified Precision: +3.1e+00 +3.1e+00 -[#examples_fmt_format] -=== `` +Scientific Format with Specified Precision and Padding: +03.140e+00 +03.141e+00 +.... +==== -We also provide support for `{fmt}` so you can easily just swap the namespaces and headers on the above example: +[#examples_print] +=== `` +.This https://github.com/cppalliance/decimal/blob/develop/examples/print.cpp[example] demonstrates how to use `` with the library +==== [source, c++] ---- #include -#include -#include +#include int main() { constexpr boost::decimal::decimal64_t val1 {314, -2}; constexpr boost::decimal::decimal32_t val2 {3141, -3}; - std::cout << fmt::format("{:10.3e}", val1) << '\n'; - std::cout << fmt::format("{:10.3e}", val2) << std::endl; + std::print("{:10.3e}\n", val1); + std::print("{:10.3e}\n", val2); return 0; } ---- -[#examples_print] -== `` +.Expected Output: +.... +03.140e+00 +03.141e+00 +.... +==== -We can make one final change to our `` example where instead of using `std::cout`, we use pass:[C++23's] ``: +[#examples_file] +== Reading From and Writing To File -[source, c++] +.This example shows how to read and write decimal values efficiently to and from file, rather than using `to_chars` and `from_chars` +==== +[source,c++] +---- +include::example$to_from_file.cpp[] ---- -#include -#include -int main() -{ - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; +.Expected Output: +.... + Current value: 0.000506 +Value as bytes: 2dcd4c57 - std::print("{:10.3e}\n", val1); - std::print("{:10.3e}\n", val2); + Current value: -3.808117e+34 +Value as bytes: c0ba1b75 - return 0; -} ----- + Current value: -1.656579e-12 +Value as bytes: a9994703 + + Current value: 2.040449e+10 +Value as bytes: 349f2281 + + Current value: -5.16665e+43 +Value as bytes: c587e239 + + Current value: -9.25265e+32 +Value as bytes: c00e1e51 + + Current value: -5.766669e-11 +Value as bytes: aa57fe0d + + Current value: -7.641908e+38 +Value as bytes: c2f49b34 + + Current value: 6.31977e+29 +Value as bytes: 3e606e9a + + Current value: 9.210438e-24 +Value as bytes: 68ec8a46 + +Successfully recovered all values from file +.... +==== diff --git a/doc/modules/ROOT/pages/fast_types.adoc b/doc/modules/ROOT/pages/fast_types.adoc index 530f974bb..0a3baab3d 100644 --- a/doc/modules/ROOT/pages/fast_types.adoc +++ b/doc/modules/ROOT/pages/fast_types.adoc @@ -9,7 +9,7 @@ https://www.boost.org/LICENSE_1_0.txt :idprefix: fast_types_ Now that we have seen the three basic types as specified in IEEE-754 there are three additional adjacent types: `decimal_fast32_t`, `decimal_fast64_t`, and `decimal_fast128_t`. -These types yield identical computational results but with faster performance. +These types yield similar computational results but with faster performance. These types make the classic tradeoff of space for time as they require more storage width than the IEEE 754 conformant type. For example `decimal32_t` is fundamentally: @@ -48,3 +48,339 @@ assert(a == b); In this example `a` and `b` both have different encodings (cohorts), so they must be normalized before comparison. `decimal_fast32_t` and the other fast types store the significand and exponent in a normalized fashion, so once again we can skip that step for every operation. + +For behavior of the individual operators see the xref:generic_decimal.adoc#operator_behavior[reference section] for the IEEE decimal types. + +== Limitations + +. These types are not uniformly faster for all operations. +One known corner case is `to_chars` with the shortest precision. +Since these types are normalized they will normally have a number of trailing zeros to accomplish the normalization. +In the case where we want to output the shortest precision we must identify and remove these trailing zeros. + +. With these types no cohort information exists, as the type stores its value in a normalized fashion. +.. Because the information is stored normalized these types do not support sub-normal values. +Any value that would be a sub-normal is flushed to 0 instead. + +== Overview + +[source, c++] +---- + +// Paragraph numbers are from ISO/IEC DTR 24733 + +namespace boost { +namespace decimal { + +class decimal_fast32_t; + +class decimal_fast64_t; + +class decimal_fast128_t; + +// 3.2.7 unary arithmetic operators: +constexpr decimal_fast32_t operator+(decimal_fast32_t rhs) noexcept; +constexpr decimal_fast64_t operator+(decimal_fast64_t rhs) noexcept; +constexpr decimal_fast128_t operator+(decimal_fast128_t rhs) noexcept; + +constexpr decimal_fast32_t operator-(decimal_fast32_t rhs) noexcept; +constexpr decimal_fast64_t operator-(decimal_fast64_t rhs) noexcept; +constexpr decimal_fast128_t operator-(decimal_fast128_t rhs) noexcept; + +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast128_t lhs, RHS rhs) noexcept; + +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast128_t lhs, RHS rhs) noexcept; + +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast128_t lhs, RHS rhs) noexcept; + +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast128_t lhs, RHS rhs) noexcept; + +// 3.2.9 comparison operators: +// LHS and RHS can be any integer or decimal type + +constexpr bool operator==(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator==(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator!=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator<(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator<=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator>(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator>=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal_fast128_t lhs, RHS rhs) noexcept; + +// If C++20 is available +// LHS and RHS can be any integer or decimal type + +constexpr std::partial_ordering operator<=>(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr std::partial_ordering operator<=>(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr std::partial_ordering operator<=>(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr std::partial_ordering operator<=>(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr std::partial_ordering operator<=>(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr std::partial_ordering operator<=>(LHS lhs, decimal_fast128_t rhs) noexcept; + +// 3.2.10 Formatted input: +// These functions are locale dependent +template +std::basic_istream& +operator>>(std::basic_istream& is, +decimal_fast32_t& d); + +template +std::basic_istream& +operator>>(std::basic_istream & is, +decimal_fast64_t& d); + +template +std::basic_istream& +operator>>(std::basic_istream & is, +decimal_fast128_t& d); + +// 3.2.11 Formatted output: +// These functions are locale dependent +template +std::basic_ostream& +operator<<(std::basic_ostream& os, +decimal_fast32_t d); + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, +decimal_fast64_t d); + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, +decimal_fast128_t d); + +} //namespace decimal +} //namespace boost + +---- + +=== 3.2.8 Note +In the event of binary arithmetic between a non-decimal type and a decimal type the arithmetic will occur between the native types, and the result will be returned as the same type as the decimal operand. (e.g. decimal_fast32_t * uint64_t -> decimal_fast32_t) + +In the event of binary arithmetic between two decimal types the result will be the higher precision type of the two (e.g. decimal64_t + decimal_fast32_t -> decimal64_t). +If the binary arithmetic is between an IEEE type, and it's fast equivalent, the result is the fast type (e.g. decimal_fast128_t - decimal128_t -> decimal_fast128_t). + + +[#fast_operator_behavior] +== Operator Behaviors + +=== Unary Plus + +[source,c++] +---- +// 3.2.7 unary arithmetic operators: +constexpr decimal_fast32_t operator+(decimal_fast32_t rhs) noexcept; +constexpr decimal_fast64_t operator+(decimal_fast64_t rhs) noexcept; +constexpr decimal_fast128_t operator+(decimal_fast128_t rhs) noexcept; +---- + +Returns `rhs` unmodified in all cases. + +=== Unary Minus + +[source,c++] +---- +constexpr decimal_fast32_t operator-(decimal_fast32_t rhs) noexcept; +constexpr decimal_fast64_t operator-(decimal_fast64_t rhs) noexcept; +constexpr decimal_fast128_t operator-(decimal_fast128_t rhs) noexcept; +---- + +Returns negated `rhs` in all cases. + +=== Addition + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal_fast128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs + rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` and `rhs` are `INF` of opposite sign, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs + rhs` overflows, returns `INF` +. If `lhs + rhs` underflows, returns `0` + +=== Subtraction + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal_fast128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs - rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` and `rhs` are `INF` of opposite sign, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs - rhs` overflows, returns `INF` +. If `lhs - rhs` underflows, returns `0` + +=== Multiplication + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal_fast128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs * rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If either `lhs` or `rhs` are `INF` and the other is `0`, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs * rhs` overflows, returns `INF` +. If `lhs * rhs` underflows, returns `0` + +=== Division + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal_fast128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs / rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` is `INF`: +.. Returns `QNAN` if `rhs` is `INF` +.. Returns `INF` if `rhs` is not `INF` +. If `rhs` is `0` returns `INF` +. If `rhs` is `INF` returns `0` +. If `lhs / rhs` overflows, returns `INF` +. If `lhs / rhs` underflows, returns `0` + +=== Comparison Operators + +[source, c++] +---- +// 3.2.9 comparison operators: +// LHS and RHS can be any integer or decimal type + +constexpr bool operator==(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator==(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator!=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator<(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator<=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator>(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal_fast128_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast32_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast64_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal_fast128_t rhs) noexcept; +constexpr bool operator>=(decimal_fast32_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal_fast64_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal_fast128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of the comparison subject to: + +. If `lhs` or `rhs` returns `false` +.. This includes the case where both `lhs` and `rhs` are `NAN` diff --git a/doc/modules/ROOT/pages/file_structure.adoc b/doc/modules/ROOT/pages/file_structure.adoc index 435101391..40d3944bb 100644 --- a/doc/modules/ROOT/pages/file_structure.adoc +++ b/doc/modules/ROOT/pages/file_structure.adoc @@ -37,5 +37,6 @@ boost/ ├── iostream.hpp ├── literals.hpp ├── numbers.hpp - └── string.hpp + ├── string.hpp + └── uint128_t.hpp ---- diff --git a/doc/modules/ROOT/pages/financial_examples.adoc b/doc/modules/ROOT/pages/financial_examples.adoc new file mode 100644 index 000000000..872f82abd --- /dev/null +++ b/doc/modules/ROOT/pages/financial_examples.adoc @@ -0,0 +1,49 @@ +//// +Copyright 2023 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#examples_finance] += Financial Examples +:idprefix: financial_examples_ + +Below are a few additional examples as to how the Decimal library can be used in the context of financial applications. +All of these examples can be found in the library `examples/` folder as well. + +== Parsing Pricing Data from File +[#examples_money_parsing] +.This https://github.com/cppalliance/decimal/blob/develop/examples/numerical_parsing.cpp[example] demonstrates the numerical differences between parsing of monetary values between using `decimal32_t` and `float` +==== +[source, c++] +---- +include::example$numerical_parsing.cpp[] +---- + +.Expected Output +.... +Number of data points: 252 + Sum from MS Excel: 52151.99 +Sum using decimal32_t: 52151.99 + Sum using float: 52151.96 +.... +==== + +[#examples_boost_math] +== Boost.Math to Calculate Bollinger Bands +.This https://github.com/cppalliance/decimal/blob/develop/examples/statistics.cpp[example] demonstrates how we can use the decimal library with existing Boost.Math facilities to perform statistical analysis +==== +[source, c++] +---- +include::example$statistics.cpp[] +---- + +.Expected Output +.... + Mean Closing Price: $207.20 +Median Closing Price: $214.26 + Standard Deviation: $25.45 +Upper Bollinger Band: $258.11 +Lower Bollinger Band: $156.30 +.... +==== diff --git a/doc/modules/ROOT/pages/format.adoc b/doc/modules/ROOT/pages/format.adoc index b5af291f3..0261be999 100644 --- a/doc/modules/ROOT/pages/format.adoc +++ b/doc/modules/ROOT/pages/format.adoc @@ -5,17 +5,37 @@ https://www.boost.org/LICENSE_1_0.txt //// [#format] -= Formating support += Formatting Support :idprefix: format_ -Boost.Decimal supports formatting with both `` (when C++20 and header are both available) and ``. - -[#std_format] -== `` +Boost.Decimal supports formatting with both `` (when C++20 and header are both available), and `` with all language standards. Format is supported when using C++20 and a compiler with appropriate support: GCC >= 13, Clang >= 18, MSVC >= 19.40 -=== Type Modifiers +== Locale Modifier + +If a format string begins with "L" the current global locale will be applied. +This can be set as so: + +[source, c++] +---- +// Locale can be any valid locale that is installed on your system +const char* locale = "de_DE.UTF-8"; +const std::locale a(locale); +std::locale::global(a); +---- + +== Sign Modifier + +|=== +| Modifier | Format +| "+" | All values will have a sign +| "-" | Only negative values have a sign +| " " | Positive values have a leading space, +Negative have a minus sign +|=== + +== Type Modifiers The following type modifiers are the same as those used by built-in floating point values: @@ -24,19 +44,20 @@ The following type modifiers are the same as those used by built-in floating poi | "g" or "G" | General | "e" or "E" | Scientific | "f" | Fixed -| "a" or "A" | Hex +| "x" or "X" | Hex +| "a" or "A" | Cohort Preserving Scientific |=== Example usage for scientific format would be: `{:e}` NOTE: The uppercase format will return with all applicable values in uppercase (e.g. 3.14E+02 vs 3.14e+02) -=== Precision Modifiers +== Precision Modifiers Precision can be specified in the same way as built-in floating point values. For example a scientific format with 3 digits or precision would be: `{:.3e}` -=== Padding Modifiers +== Padding Modifiers If you want all values to be printed with a fixed width padding is allowed before the precision modifier. For example with `{:10.3e}`: @@ -46,48 +67,82 @@ For example with `{:10.3e}`: Note the space at the front of these string to keep with width at 10 characters -=== Examples +== String Literal Support -The example is padding modifiers can be done like so +If you want the result to be a different string width than `char` you can specify this with the format string. +For example if you want the result to be `wchar_t` you can use `L"{}"`. +`wchar_t`, `char16_t`, `char32_t` are supported from pass:[C++17]. +`char8_t` is supported from pass:[C++23]. -[source, c++] ----- -#include // or -#include -#include +IMPORTANT: `std::format` only supports `char` and `wchar_t` types per the pass:[C++] specification. -int main() -{ - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; +== Putting it All Together - std::cout << std::format("{:10.3e}", val1) << '\n'; - std::cout << std::format("{:10.3e}", val2) << std::endl; +The appropriate order for the full format specifier is: - return 0; -} ----- +String literal pass:["{Sign, Padding, Precision, Type, Locale}"] + +== Examples -[#fmt_format] -== `` +This example can be found in the examples/ folder as https://github.com/cppalliance/decimal/blob/develop/examples/fmt_format.cpp[fmt_format.cpp] -Support for `{fmt}` is available as long as `` is present. -All the above information on modifiers is the same for fmtlib, just in a different namespace (i.e. `fmt::` instead of `std::`). +The header `` is *NOT* part of the convenience header, because it is an optional dependency on a potentially compiled library. [source, c++] ---- #include -#include // or +#include +#include #include int main() { - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; - + constexpr boost::decimal::decimal64_t val1 {"3.14"}; + constexpr boost::decimal::decimal32_t val2 {"3.141"}; + + // The easiest is no specification which is general format + // Given these values they will print in fixed format + std::cout << "Default Format:\n"; + std::cout << fmt::format("{}", val1) << '\n'; + std::cout << fmt::format("{}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + std::cout << "Scientific Format:\n"; + std::cout << fmt::format("{:e}", val1) << '\n'; + std::cout << fmt::format("{:e}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + // Here this gives one digit of precision rounded according to current rounding mode + std::cout << "Scientific Format with Specified Precision:\n"; + std::cout << fmt::format("{:.1e}", val1) << '\n'; + std::cout << fmt::format("{:.1e}", val2) << "\n\n"; + + // This combines the padding modifier (10), precision (3 digits), and a type modifier (e) + std::cout << "Scientific Format with Specified Precision and Padding:\n"; std::cout << fmt::format("{:10.3e}", val1) << '\n'; - std::cout << fmt::format("{:10.3e}", val2) << std::endl; + std::cout << fmt::format("{:10.3e}", val2) << '\n'; return 0; } ---- + +Output: +---- +Default Format: +3.14 +3.141 + +Scientific Format: +3.14e+00 +3.141e+00 + +Scientific Format with Specified Precision: +3.1e+00 +3.1e+00 + +Scientific Format with Specified Precision and Padding: +03.140e+00 +03.141e+00 +---- + +This same example can be run with `` by replacing namespaces `fmt::` with `std::`. diff --git a/doc/modules/ROOT/pages/functional.adoc b/doc/modules/ROOT/pages/functional.adoc index 300217a35..4d1bc12f2 100644 --- a/doc/modules/ROOT/pages/functional.adoc +++ b/doc/modules/ROOT/pages/functional.adoc @@ -5,10 +5,10 @@ https://www.boost.org/LICENSE_1_0.txt //// [#functional] -= `` support += `` Support :idprefix: functional_ -The following functions from `` are overloaded: +The following functions from https://en.cppreference.com/w/cpp/utility/hash.html[``] are overloaded: [source, c++] ---- diff --git a/doc/modules/ROOT/pages/generic_decimal.adoc b/doc/modules/ROOT/pages/generic_decimal.adoc index 422d875b7..ef00faec9 100644 --- a/doc/modules/ROOT/pages/generic_decimal.adoc +++ b/doc/modules/ROOT/pages/generic_decimal.adoc @@ -160,3 +160,178 @@ decimal128_t d); In the event of binary arithmetic between a non-decimal type and a decimal type the arithmetic will occur between the native types, and the result will be returned as the same type as the decimal operand. (e.g. decimal32_t * uint64_t -> decimal32_t) In the event of binary arithmetic between two decimal types the result will be the higher precision type of the two (e.g. decimal64_t + decimal32_t -> decimal64_t) + +== 3.2.10 Note + +xref:design.adoc#non-finite-deviation[Non-finite values are supported] + +[#operator_behavior] +== Operator Behaviors + +=== Unary Plus + +[source,c++] +---- +// 3.2.7 unary arithmetic operators: +constexpr decimal32_t operator+(decimal32_t rhs) noexcept; +constexpr decimal64_t operator+(decimal64_t rhs) noexcept; +constexpr decimal128_t operator+(decimal128_t rhs) noexcept; +---- + +Returns `rhs` unmodified in all cases. + +=== Unary Minus + +[source,c++] +---- +constexpr decimal32_t operator-(decimal32_t rhs) noexcept; +constexpr decimal64_t operator-(decimal64_t rhs) noexcept; +constexpr decimal128_t operator-(decimal128_t rhs) noexcept; +---- + +Returns negated `rhs` in all cases. + +=== Addition + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator+(decimal128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs + rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` and `rhs` are `INF` of opposite sign, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs + rhs` overflows, returns `INF` +. If `lhs + rhs` underflows, returns `0` + +=== Subtraction + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator-(decimal128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs - rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` and `rhs` are `INF` of opposite sign, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs - rhs` overflows, returns `INF` +. If `lhs - rhs` underflows, returns `0` + +=== Multiplication + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator*(decimal128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs * rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If either `lhs` or `rhs` are `INF` and the other is `0`, returns `QNAN` +. If either `lhs` or `rhs` are `INF`, returns `INF` of same sign +. If `lhs * rhs` overflows, returns `INF` +. If `lhs * rhs` underflows, returns `0` + +=== Division + +[source,c++] +---- +// 3.2.8 binary arithmetic operators: +// LHS and RHS can be any integer or decimal type + +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal32_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal64_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal128_t rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal32_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal64_t lhs, RHS rhs) noexcept; +constexpr /* see 3.2.8 */ operator/(decimal128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of `lhs / rhs` subject to: + +. If either `lhs` or `rhs` are `NAN`, returns `QNAN` +. If `lhs` is `INF`: +.. Returns `QNAN` if `rhs` is `INF` +.. Returns `INF` if `rhs` is not `INF` +. If `rhs` is `0` returns `INF` +. If `rhs` is `INF` returns `0` +. If `lhs / rhs` overflows, returns `INF` +. If `lhs / rhs` underflows, returns `0` + +=== Comparison Operators + +[source, c++] +---- +// 3.2.9 comparison operators: +// LHS and RHS can be any integer or decimal type + +constexpr bool operator==(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator==(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator==(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator==(decimal128_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator!=(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator!=(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator!=(decimal128_t lhs, RHS rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator<(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator<(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator<(decimal128_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator<=(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator<=(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator<=(decimal128_t lhs, RHS rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator>(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator>(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator>(decimal128_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal32_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal64_t rhs) noexcept; +constexpr bool operator>=(LHS lhs, decimal128_t rhs) noexcept; +constexpr bool operator>=(decimal32_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal64_t lhs, RHS rhs) noexcept; +constexpr bool operator>=(decimal128_t lhs, RHS rhs) noexcept; +---- + +Returns the result of the comparison subject to: + +. If `lhs` or `rhs` returns `false` +.. This includes the case where both `lhs` and `rhs` are `NAN` diff --git a/doc/modules/ROOT/pages/limits.adoc b/doc/modules/ROOT/pages/limits.adoc index 39179b542..332b07d31 100644 --- a/doc/modules/ROOT/pages/limits.adoc +++ b/doc/modules/ROOT/pages/limits.adoc @@ -5,7 +5,7 @@ https://www.boost.org/LICENSE_1_0.txt //// [#limits] -= `` support += `` Support :idprefix: limits_ The following from `` are overloaded for each type with associated values for reference: diff --git a/doc/modules/ROOT/pages/literals.adoc b/doc/modules/ROOT/pages/literals.adoc index 85b20e272..499568359 100644 --- a/doc/modules/ROOT/pages/literals.adoc +++ b/doc/modules/ROOT/pages/literals.adoc @@ -20,40 +20,40 @@ namespace decimal { constexpr auto operator "" _DF(const char* str) -> decimal32_t constexpr auto operator "" _df(const char* str) -> decimal32_t -constexpr auto operator "" _DF(unsigned long long v) -> decimal32_t -constexpr auto operator "" _df(unsigned long long v) -> decimal32_t +constexpr auto operator "" _DF(const char* str, std::size_t len) -> decimal32_t +constexpr auto operator "" _df(const char* str, std::size_t len) -> decimal32_t constexpr auto operator "" _DD(const char* str) -> decimal64_t constexpr auto operator "" _dd(const char* str) -> decimal64_t -constexpr auto operator "" _DD(unsigned long long v) -> decimal64_t -constexpr auto operator "" _dd(unsigned long long v) -> decimal64_t +constexpr auto operator "" _DD(const char* str, std::size_t len) -> decimal64_t +constexpr auto operator "" _dd(const char* str, std::size_t len) -> decimal64_t constexpr auto operator "" _DL(const char* str) -> decimal128_t constexpr auto operator "" _dl(const char* str) -> decimal128_t -constexpr auto operator "" _DL(unsigned long long v) -> decimal128_t -constexpr auto operator "" _dl(unsigned long long v) -> decimal128_t +constexpr auto operator "" _DL(const char* str, std::size_t len) -> decimal128_t +constexpr auto operator "" _dl(const char* str, std::size_t len) -> decimal128_t // ----- Fast Type Literals ----- constexpr auto operator "" _DFF(const char* str) -> decimal_fast32_t constexpr auto operator "" _dff(const char* str) -> decimal_fast32_t -constexpr auto operator "" _DFF(unsigned long long v) -> decimal_fast32_t -constexpr auto operator "" _dff(unsigned long long v) -> decimal_fast32_t +constexpr auto operator "" _DFF(const char* str, std::size_t len) -> decimal_fast32_t +constexpr auto operator "" _dff(const char* str, std::size_t len) -> decimal_fast32_t constexpr auto operator "" _DDF(const char* str) -> decimal_fast64_t constexpr auto operator "" _ddf(const char* str) -> decimal_fast64_t -constexpr auto operator "" _DDF(unsigned long long v) -> decimal_fast64_t -constexpr auto operator "" _ddf(unsigned long long v) -> decimal_fast64_t +constexpr auto operator "" _DDF(const char* str, std::size_t len) -> decimal_fast64_t +constexpr auto operator "" _ddf(const char* str, std::size_t len) -> decimal_fast64_t constexpr auto operator "" _DLF(const char* str) -> decimal_fast128_t constexpr auto operator "" _dlf(const char* str) -> decimal_fast128_t -constexpr auto operator "" _DLF(unsigned long long v) -> decimal_fast128_t -constexpr auto operator "" _dlf(unsigned long long v) -> decimal_fast128_t +constexpr auto operator "" _DLF(const char* str, std::size_t len) -> decimal_fast128_t +constexpr auto operator "" _dlf(const char* str, std::size_t len) -> decimal_fast128_t } //namespace decimal } //namespace boost diff --git a/doc/modules/ROOT/pages/overview.adoc b/doc/modules/ROOT/pages/overview.adoc index 7a750c40a..9a3c22eee 100644 --- a/doc/modules/ROOT/pages/overview.adoc +++ b/doc/modules/ROOT/pages/overview.adoc @@ -6,7 +6,7 @@ https://www.boost.org/LICENSE_1_0.txt [#overview] -= Decimal: IEEE 754 Decimal Floating Point Numbers += Boost.Decimal: IEEE 754 Decimal Floating Point Numbers Matt Borland and Chris Kormanyos @@ -23,6 +23,7 @@ Decimal floating point numbers avoid this issue by storing the significand in ba The other major difference between binary and decimal floating point types is that the latter allows for multiple representations of the same number. For example 1e5 could also be stored as 0.1e6, 0.01e7, so on and so forth. These are referred to as cohorts which binary does not have as there is only one way to represent each number in binary floating point. +For more information on cohorts please see the xref:cohorts.adoc[cohort section] of the documentation. == Use Cases diff --git a/doc/modules/ROOT/pages/strings.adoc b/doc/modules/ROOT/pages/strings.adoc new file mode 100644 index 000000000..d3632a52e --- /dev/null +++ b/doc/modules/ROOT/pages/strings.adoc @@ -0,0 +1,90 @@ +//// +Copyright 2025 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#strings] += `` Support +:idprefix: string_ + +== Construction from `std::string` and `std::string_view` + +Each of the decimal types have constructors that look like the following + +[source, c++] +---- +namespace boost { +namespace decimal { + +class decimal32_t +{ + + constexpr decimal32_t(const char* str) + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + inline decimal32_t::decimal32_t(const std::string& str); + #else + constexpr decimal32_t::decimal32_t(std::string_view str); + #endif +}; + +} // namespace decimal +} // namespace boost +---- + +These constructors allow for construction from C-strings, `std::string`, and from `std::string_view` when available. +They construct the value as though calling `from_chars` without a specified format. +If the input string is invalid these constructors will `throw std::runtime_error`. +If you are using a no exceptions environment instead of throwing the constructor will return a Quiet NAN. + +== Conversions from `std::string` + +[source,c++] +---- +#include + +namespace boost { +namespace decimal { + +inline auto stod32(const std::string& str, std::size_t* idx = nullptr) -> decimal32_t; + +inline auto stod32f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast32_t; + +inline auto stod64(const std::string& str, std::size_t* idx = nullptr) -> decimal64_t; + +inline auto stod64f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast64_t; + +inline auto stod128(const std::string& str, std::size_t* idx = nullptr) -> decimal128_t; + +inline auto stod128f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast128_t + +} // namespace decimal +} // namespace boost +---- + +Attempts conversion of `str` to the decimal type specified as if with `from_chars(str, idx)` subject to: + +. Overflow throws `std::out_of_range` or in a no exceptions environment returns `std::numeric_limits::signaling_NaN()` with unset value of `idx`. + +. If the string can not be converted into a decimal value throws `std::out_of_range` or in a no exceptions environment returns `std::numeric_limits::signaling_NaN()` with unset value of `idx`. + +The returned value `idx` is the number of characters. + +== `to_string` + +[source, c++] +---- +#include + +namespace boost { +namespace decimal { + +template +std::string to_string(const DecimalType value) + +} // namespace decimal +} // namespace boost +---- + +The `to_string` format returns a `std::string` of the decimal value formated as though using `to_chars` with general formatting, and no specified precision. diff --git a/doc/package-lock.json b/doc/package-lock.json index a4abd7e46..ee9afea7a 100644 --- a/doc/package-lock.json +++ b/doc/package-lock.json @@ -1,1608 +1,2242 @@ { - "name": "doc", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "devDependencies": { - "@antora/cli": "3.1.10", - "@antora/site-generator": "3.1.10", - "antora": "3.1.10" - } - }, - "node_modules/@antora/asciidoc-loader": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.10.tgz", - "integrity": "sha512-np0JkOV37CK7V4eDZUZXf4fQuCKYW3Alxl8FlyzBevXi2Ujv29O82JLbHbv1cyTsvGkGNNB+gzJIx9XBsQ7+Nw==", - "dev": true, - "dependencies": { - "@antora/logger": "3.1.10", - "@antora/user-require-helper": "~3.0", - "@asciidoctor/core": "~2.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/cli": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.10.tgz", - "integrity": "sha512-gp8u9aVM0w1DtWSsB5PwvEfFYKrooPENLhN58RAfdgTrcsTsWw+CDysFZPgEaHB0Y1ZbanR82ZH/f6JVKGcZfQ==", - "dev": true, - "dependencies": { - "@antora/logger": "3.1.10", - "@antora/playbook-builder": "3.1.10", - "@antora/user-require-helper": "~3.0", - "commander": "~11.1" - }, - "bin": { - "antora": "bin/antora" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/content-aggregator": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.10.tgz", - "integrity": "sha512-OT6ZcCA7LrtNfrAZUr3hFh+Z/1isKpsfnqFjCDC66NEMqIyzJO99jq0CM66rYlYhyX7mb5BwEua8lHcwpOXNow==", - "dev": true, - "dependencies": { - "@antora/expand-path-helper": "~3.0", - "@antora/logger": "3.1.10", - "@antora/user-require-helper": "~3.0", - "braces": "~3.0", - "cache-directory": "~2.0", - "fast-glob": "~3.3", - "hpagent": "~1.2", - "isomorphic-git": "~1.25", - "js-yaml": "~4.1", - "multi-progress": "~4.0", - "picomatch": "~4.0", - "progress": "~2.0", - "should-proxy": "~1.0", - "simple-get": "~4.0", - "vinyl": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/content-classifier": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.10.tgz", - "integrity": "sha512-3JJl4IIiTX00v/MirK603NoqIcHjGYAaRWt3Q4U03tI1Fv2Aho/ypO3FE45069jFf0Dx2uDJfp5kapb9gaIjdQ==", - "dev": true, - "dependencies": { - "@antora/asciidoc-loader": "3.1.10", - "@antora/logger": "3.1.10", - "mime-types": "~2.1", - "vinyl": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/document-converter": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.10.tgz", - "integrity": "sha512-qi9ctgcKal8tZtWflVo66w+4zCJoBmUKRV+eA9aRRR09KDdU9r514vu1adWNgniPppISr90zD13V5l2JUy/2CQ==", - "dev": true, - "dependencies": { - "@antora/asciidoc-loader": "3.1.10" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/expand-path-helper": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@antora/expand-path-helper/-/expand-path-helper-3.0.0.tgz", - "integrity": "sha512-7PdEIhk97v85/CSm3HynCsX14TR6oIVz1s233nNLsiWubE8tTnpPt4sNRJR+hpmIZ6Bx9c6QDp3XIoiyu/WYYA==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/file-publisher": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.10.tgz", - "integrity": "sha512-DPR/0d1P+kr3qV4T0Gh81POEO/aCmNWIp/oLUYAhr0HHOcFzgpTUUoLStgcYynZPFRIB7EYKSab+oYSCK17DGA==", - "dev": true, - "dependencies": { - "@antora/expand-path-helper": "~3.0", - "@antora/user-require-helper": "~3.0", - "vinyl": "~3.0", - "yazl": "~2.5" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/logger": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.10.tgz", - "integrity": "sha512-WSuIxEP2tVrhWtTj/sIrwBDjpi4ldB/1Kpiu4PXmY4/qeWP8thW6u8nXdwdDcWss5zqkZWjourvWKwVq7y8Wjg==", - "dev": true, - "dependencies": { - "@antora/expand-path-helper": "~3.0", - "pino": "~9.2", - "pino-pretty": "~11.2", - "sonic-boom": "~4.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/navigation-builder": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.10.tgz", - "integrity": "sha512-aLMK49nYsSB3mEZbLkmUXDAUYmscv2AFWu+5c3eqVGkQ6Wgyd79WQ6Bz3/TN9YqkzGL+PqGs0G39F0VQzD23Hw==", - "dev": true, - "dependencies": { - "@antora/asciidoc-loader": "3.1.10" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/page-composer": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.10.tgz", - "integrity": "sha512-JoEg8J8HVsnPmAgUrYSGzf0C8rQefXyCi/18ucy0utyfUvlJNsZvUbGUPx62Het9p0JP0FkAz2MTLyDlNdArVg==", - "dev": true, - "dependencies": { - "@antora/logger": "3.1.10", - "handlebars": "~4.7", - "require-from-string": "~2.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/playbook-builder": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.10.tgz", - "integrity": "sha512-UB8UmRYfkKgActTUlotdVS4FKGjaZgTnSXE7Fns1xb3/3HRanWvI+Yze1OmCkGC33cTpoQFnSYp7ySEH8LaiBw==", - "dev": true, - "dependencies": { - "@iarna/toml": "~2.2", - "convict": "~6.2", - "js-yaml": "~4.1", - "json5": "~2.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/redirect-producer": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.10.tgz", - "integrity": "sha512-IbWJGh6LmsxJQ821h0B9JfooofFZBgFLZxsbp/IoTLkBFGLFAY5tDRvB6rvubfNLRoSjM8VjEUXGqVLlwZOb+g==", - "dev": true, - "dependencies": { - "vinyl": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/site-generator": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.10.tgz", - "integrity": "sha512-NCULYtwUjIyr5FGCymhfG/zDVUmZ6pfmCPorka8mAzo4/GDx1T7bgaRL9rEIyf2AMqcm7apQiAz03mpU4kucsw==", - "dev": true, - "dependencies": { - "@antora/asciidoc-loader": "3.1.10", - "@antora/content-aggregator": "3.1.10", - "@antora/content-classifier": "3.1.10", - "@antora/document-converter": "3.1.10", - "@antora/file-publisher": "3.1.10", - "@antora/logger": "3.1.10", - "@antora/navigation-builder": "3.1.10", - "@antora/page-composer": "3.1.10", - "@antora/playbook-builder": "3.1.10", - "@antora/redirect-producer": "3.1.10", - "@antora/site-mapper": "3.1.10", - "@antora/site-publisher": "3.1.10", - "@antora/ui-loader": "3.1.10", - "@antora/user-require-helper": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/site-mapper": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.10.tgz", - "integrity": "sha512-KY1j/y0uxC2Y7RAo4r4yKv9cgFm8aZoRylZXEODJnwj3tffbZ2ZdRzSWHp6fN0QX/Algrr9JNd9CWrjcj2f3Zw==", - "dev": true, - "dependencies": { - "@antora/content-classifier": "3.1.10", - "vinyl": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/site-publisher": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.10.tgz", - "integrity": "sha512-G4xcUWvgth8oeEQwiu9U1cE0miQtYHwKHOobUbDBt2Y6LlC5H31zQQmAyvMwTsGRlvYRgLVtG6j9d6JBwQ6w9Q==", - "dev": true, - "dependencies": { - "@antora/file-publisher": "3.1.10" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/ui-loader": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.10.tgz", - "integrity": "sha512-H1f5wI5a5HjLuE/Wexvc8NZy8w83Bhqjka7t1DbwOOqP+LyxFGLx/QbBVKdTtgFNDHVMtNBlplQq0ixeoTSh0A==", - "dev": true, - "dependencies": { - "@antora/expand-path-helper": "~3.0", - "braces": "~3.0", - "cache-directory": "~2.0", - "fast-glob": "~3.3", - "hpagent": "~1.2", - "js-yaml": "~4.1", - "picomatch": "~4.0", - "should-proxy": "~1.0", - "simple-get": "~4.0", - "vinyl": "~3.0", - "yauzl": "~3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@antora/user-require-helper": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@antora/user-require-helper/-/user-require-helper-3.0.0.tgz", - "integrity": "sha512-KIXb8WYhnrnwH7Jj21l1w+et9k5GvcgcqvLOwxqWLEd0uVZOiMFdqFjqbVm3M+zcrs1JXWMeh2LLvxBbQs3q/Q==", - "dev": true, - "dependencies": { - "@antora/expand-path-helper": "~3.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@asciidoctor/core": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@asciidoctor/core/-/core-2.2.8.tgz", - "integrity": "sha512-oozXk7ZO1RAd/KLFLkKOhqTcG4GO3CV44WwOFg2gMcCsqCUTarvMT7xERIoWW2WurKbB0/ce+98r01p8xPOlBw==", - "dev": true, - "dependencies": { - "asciidoctor-opal-runtime": "0.3.3", - "unxhr": "1.0.1" - }, - "engines": { - "node": ">=8.11", - "npm": ">=5.0.0", - "yarn": ">=1.1.0" - } - }, - "node_modules/@iarna/toml": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/antora": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/antora/-/antora-3.1.10.tgz", - "integrity": "sha512-FcXPfqxi5xrGF2fTrFiiau45q8w0bzRcnfk97nxvpvztPDHX/lUOrBF/GpaGl1JT5K085VkI3/dbxTlvWK1jjw==", - "dev": true, - "dependencies": { - "@antora/cli": "3.1.10", - "@antora/site-generator": "3.1.10" - }, - "bin": { - "antora": "bin/antora" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/asciidoctor-opal-runtime": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz", - "integrity": "sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==", - "dev": true, - "dependencies": { - "glob": "7.1.3", - "unxhr": "1.0.1" - }, - "engines": { - "node": ">=8.11" - } - }, - "node_modules/async-lock": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", - "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", - "dev": true - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", - "dev": true, - "optional": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cache-directory": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cache-directory/-/cache-directory-2.0.0.tgz", - "integrity": "sha512-7YKEapH+2Uikde8hySyfobXBqPKULDyHNl/lhKm7cKf/GJFdG/tU/WpLrOg2y9aUrQrWUilYqawFIiGJPS6gDA==", - "dev": true, - "dependencies": { - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/clean-git-ref": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", - "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==", - "dev": true - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convict": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz", - "integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==", - "dev": true, - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "yargs-parser": "^20.2.7" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/diff3": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", - "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-copy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", - "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", - "dev": true - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-redact": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", - "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/help-me": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", - "dev": true - }, - "node_modules/hpagent": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", - "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/isomorphic-git": { - "version": "1.25.10", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.25.10.tgz", - "integrity": "sha512-IxGiaKBwAdcgBXwIcxJU6rHLk+NrzYaaPKXXQffcA0GW3IUrQXdUPDXDo+hkGVcYruuz/7JlGBiuaeTCgIgivQ==", - "dev": true, - "dependencies": { - "async-lock": "^1.4.1", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^4.0.1" - }, - "bin": { - "isogit": "cli.cjs" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "name": "doc", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "doc", + "dependencies": { + "@antora/lunr-extension": "^1.0.0-alpha.12" + }, + "devDependencies": { + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14", + "antora": "3.1.14" + } + }, + "node_modules/@antora/asciidoc-loader": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.14.tgz", + "integrity": "sha512-4xxisnoBFrlLNY6f3xZtyyfgm+tBLsqesTcEStfc8jtXUMYJ4b2DWIzo1vULmxvZ7yY5+Q7YqEvS5o6kIWAG0A==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/logger": "3.1.14", + "@antora/user-require-helper": "~3.0", + "@asciidoctor/core": "~2.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/cli": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.14.tgz", + "integrity": "sha512-I6WcygMU2bFInjdURJjkYjo7K5M8B3lBB53v9OO0IcY0LhEY8Wa7IlZ7wVinf5qEjHvaYzRGTZVl6RsJtVt7Sw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/logger": "3.1.14", + "@antora/playbook-builder": "3.1.14", + "@antora/user-require-helper": "~3.0", + "commander": "~11.1" + }, + "bin": { + "antora": "bin/antora" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/cli/node_modules/@antora/playbook-builder": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.14.tgz", + "integrity": "sha512-Ss2r7In00u/n9Da+JOxEqIE8NeRosf+f+agzH3Te09JV/mpgZKxEOE5V/VuP+TNNq4ww1eu5aOS8DiU2PYwj4Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@iarna/toml": "~2.2", + "convict": "~6.2", + "js-yaml": "~4.1", + "json5": "~2.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/content-aggregator": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.14.tgz", + "integrity": "sha512-FVuBgnrGPiktYqK1WHbGF8O8l4m5KHlkxoJumrbacgFo8SKuiRFEo31zalxrCUsv8QM3UBEgX+LdHrve/9CGLg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "@antora/logger": "3.1.14", + "@antora/user-require-helper": "~3.0", + "braces": "~3.0", + "cache-directory": "~2.0", + "fast-glob": "~3.3", + "hpagent": "~1.2", + "isomorphic-git": "~1.25", + "js-yaml": "~4.1", + "multi-progress": "~4.0", + "picomatch": "~4.0", + "progress": "~2.0", + "should-proxy": "~1.0", + "simple-get": "~4.0", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/content-classifier": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.14.tgz", + "integrity": "sha512-y8Fk+KU1lqD3aawOu3ZFK92YfOZ1k3YBJhLI9QIFM6Ck4STPnf7AwYbhfOtjODlwer5/OhFmfhjUB2hn7onGnA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/asciidoc-loader": "3.1.14", + "@antora/logger": "3.1.14", + "mime-types": "~2.1", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/document-converter": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.14.tgz", + "integrity": "sha512-f6wFnL+489DI0ZDgoxYWzbxxWqPviRiJ56OHS1NixEfvJ7OpRBDPEbX1xnsIeiyFBgqX4+nY92MsCWKTa+Gf3w==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/asciidoc-loader": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/expand-path-helper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@antora/expand-path-helper/-/expand-path-helper-3.0.0.tgz", + "integrity": "sha512-7PdEIhk97v85/CSm3HynCsX14TR6oIVz1s233nNLsiWubE8tTnpPt4sNRJR+hpmIZ6Bx9c6QDp3XIoiyu/WYYA==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/file-publisher": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.14.tgz", + "integrity": "sha512-fTaAnkyKSOlsxQM1TBFCAmiERA6Q67XleDCD2bMPVgfcENmo0Xfx59KwCHaA92IcRSmMftydlXHPaFxNh0UVsg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "@antora/user-require-helper": "~3.0", + "vinyl": "~3.0", + "yazl": "~2.5" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/logger": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.14.tgz", + "integrity": "sha512-kVEeGqZbXR903hPIm+BlN97fLdQ3LoUzE/BOPZ6vRp9m9Mmbnm67Kg7fSYkfTMLB0S2UWpAPFg22RdsU5ZoAzA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "pino": "~9.2", + "pino-pretty": "~11.2", + "sonic-boom": "~4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/lunr-extension": { + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/@antora/lunr-extension/-/lunr-extension-1.0.0-alpha.12.tgz", + "integrity": "sha512-iiEXpJae8tCH22ao7kZ4I+eyQ/3IeFIFK1G5I9QLpkCezaVPotI8eLFY7e0xDI+zsqJEfCOsfoZGYXso6xCYlA==", + "license": "MPL-2.0", + "workspaces": [ + "." + ], + "dependencies": { + "htmlparser2": "~9.1", + "lunr": "~2.3", + "lunr-languages": "~1.10" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/navigation-builder": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.14.tgz", + "integrity": "sha512-/637YLGD7oUHGSfEfszXkk4ASfIhDAg5Xs9035J1dV07XYRlGqmtUb15rtapbcECpcQFjCyM5jFQYSNNvLrGcQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/asciidoc-loader": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/page-composer": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.14.tgz", + "integrity": "sha512-RfA+67TxCqUPrQbZdrfjgLpHh8MR2z2du7cyF3HGX4N6DpqEBvz81NHHl3rA3fj6BQZPQbGm2OYAMU6wzJ6Pog==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/logger": "3.1.14", + "handlebars": "~4.7", + "require-from-string": "~2.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/redirect-producer": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.14.tgz", + "integrity": "sha512-5koAwRk1cZrvE/qfOWKXqb3jtxrZbWA5EYHYGFEoato5By3cbC42blH4Bre9/48pjyS6znFpbZhYUBpT7PRhZA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-generator": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.14.tgz", + "integrity": "sha512-hQIUVtM9+xwleYWc4fIRZmiKl2p+ItOJuUm2+Hkdh07BZsySxkMOxxCyZsvTn9rc+4R94CYqDQCYElwFwdB2WA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/asciidoc-loader": "3.1.14", + "@antora/content-aggregator": "3.1.14", + "@antora/content-classifier": "3.1.14", + "@antora/document-converter": "3.1.14", + "@antora/file-publisher": "3.1.14", + "@antora/logger": "3.1.14", + "@antora/navigation-builder": "3.1.14", + "@antora/page-composer": "3.1.14", + "@antora/playbook-builder": "3.1.14", + "@antora/redirect-producer": "3.1.14", + "@antora/site-mapper": "3.1.14", + "@antora/site-publisher": "3.1.14", + "@antora/ui-loader": "3.1.14", + "@antora/user-require-helper": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-generator/node_modules/@antora/playbook-builder": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.14.tgz", + "integrity": "sha512-Ss2r7In00u/n9Da+JOxEqIE8NeRosf+f+agzH3Te09JV/mpgZKxEOE5V/VuP+TNNq4ww1eu5aOS8DiU2PYwj4Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@iarna/toml": "~2.2", + "convict": "~6.2", + "js-yaml": "~4.1", + "json5": "~2.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-mapper": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.14.tgz", + "integrity": "sha512-3qbETtwadl+fWREjzrBUxPUorMcMiZ+hdkB1El9z7it9KzKh0Yp7Je0+2uTxGX+Lov9uik48dZJ9e/mr5PeaRQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/content-classifier": "3.1.14", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-publisher": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.14.tgz", + "integrity": "sha512-8apyEmgepUc7ms9CTEIPwN3tGtWwLqR6fbLMLs7hibqmOSR880Ut/4GRGb97sqcGQXSHdIyWK2oJKzRl1Akb6Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/file-publisher": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/ui-loader": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.14.tgz", + "integrity": "sha512-LVvTdKQOB44CmJ1JQDu8sJf6rrLZMxPAWWackdg2JtGyGHHpd80/MBcv4BSFk7//cJQ13Oqm/7JCbhD51KAFjg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "braces": "~3.0", + "cache-directory": "~2.0", + "fast-glob": "~3.3", + "hpagent": "~1.2", + "js-yaml": "~4.1", + "picomatch": "~4.0", + "should-proxy": "~1.0", + "simple-get": "~4.0", + "vinyl": "~3.0", + "yauzl": "~3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/user-require-helper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@antora/user-require-helper/-/user-require-helper-3.0.0.tgz", + "integrity": "sha512-KIXb8WYhnrnwH7Jj21l1w+et9k5GvcgcqvLOwxqWLEd0uVZOiMFdqFjqbVm3M+zcrs1JXWMeh2LLvxBbQs3q/Q==", + "dev": true, + "dependencies": { + "@antora/expand-path-helper": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@asciidoctor/core": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@asciidoctor/core/-/core-2.2.8.tgz", + "integrity": "sha512-oozXk7ZO1RAd/KLFLkKOhqTcG4GO3CV44WwOFg2gMcCsqCUTarvMT7xERIoWW2WurKbB0/ce+98r01p8xPOlBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asciidoctor-opal-runtime": "0.3.3", + "unxhr": "1.0.1" + }, + "engines": { + "node": ">=8.11", + "npm": ">=5.0.0", + "yarn": ">=1.1.0" + } + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/antora": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/antora/-/antora-3.1.14.tgz", + "integrity": "sha512-z8HshJsT6pUfdDOUJ15RGtpOM9LmL6JXU5JBshoR/9/xd+1qLmKPkOnUv+HrijAk93r1imxZOdkmIqhLcv8B8A==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14" + }, + "bin": { + "antora": "bin/antora" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/asciidoctor-opal-runtime": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz", + "integrity": "sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "7.1.3", + "unxhr": "1.0.1" + }, + "engines": { + "node": ">=8.11" + } + }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimisted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", - "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - } - }, - "node_modules/multi-progress": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multi-progress/-/multi-progress-4.0.0.tgz", - "integrity": "sha512-9zcjyOou3FFCKPXsmkbC3ethv51SFPoA4dJD6TscIp2pUmy26kBDZW6h9XofPELrzseSkuD7r0V+emGEeo39Pg==", - "dev": true, - "peerDependencies": { - "progress": "^2.0.0" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", - "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pino": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.2.0.tgz", - "integrity": "sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==", - "dev": true, - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.2.0", - "pino-std-serializers": "^7.0.0", - "process-warning": "^3.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^4.0.1", - "thread-stream": "^3.0.0" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/cache-directory": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cache-directory/-/cache-directory-2.0.0.tgz", + "integrity": "sha512-7YKEapH+2Uikde8hySyfobXBqPKULDyHNl/lhKm7cKf/GJFdG/tU/WpLrOg2y9aUrQrWUilYqawFIiGJPS6gDA==", + "dev": true, + "license": "LGPL-3.0+", + "dependencies": { + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convict": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz", + "integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "yargs-parser": "^20.2.7" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "dev": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "dev": true + }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", - "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", - "dev": true, - "dependencies": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - } - }, - "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz", - "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==", - "dev": true, - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-pretty": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.2.2.tgz", - "integrity": "sha512-2FnyGir8nAJAqD3srROdrF1J5BIcMT4nwj7hHSc60El6Uxlym00UbCCd8pYIterstVBFlMyF1yFV8XdGIPbj4A==", - "dev": true, - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^3.0.2", - "fast-safe-stringify": "^2.1.1", - "help-me": "^5.0.0", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.0.0", - "pump": "^3.0.0", - "readable-stream": "^4.0.0", - "secure-json-parse": "^2.4.0", - "sonic-boom": "^4.0.1", - "strip-json-comments": "^3.1.1" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isomorphic-git": { + "version": "1.25.10", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.25.10.tgz", + "integrity": "sha512-IxGiaKBwAdcgBXwIcxJU6rHLk+NrzYaaPKXXQffcA0GW3IUrQXdUPDXDo+hkGVcYruuz/7JlGBiuaeTCgIgivQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-lock": "^1.4.1", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "license": "MIT" + }, + "node_modules/lunr-languages": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.10.0.tgz", + "integrity": "sha512-BBjKKcwrieJlzwwc9M5H/MRXGJ2qyOSDx/NXYiwkuKjiLOOoouh0WsDzeqcLoUWcX31y7i8sb8IgsZKObdUCkw==", + "license": "MPL-1.1" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + } + }, + "node_modules/multi-progress": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multi-progress/-/multi-progress-4.0.0.tgz", + "integrity": "sha512-9zcjyOou3FFCKPXsmkbC3ethv51SFPoA4dJD6TscIp2pUmy26kBDZW6h9XofPELrzseSkuD7r0V+emGEeo39Pg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "progress": "^2.0.0" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pino": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.2.0.tgz", + "integrity": "sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dev": true, + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz", + "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.2.2.tgz", + "integrity": "sha512-2FnyGir8nAJAqD3srROdrF1J5BIcMT4nwj7hHSc60El6Uxlym00UbCCd8pYIterstVBFlMyF1yFV8XdGIPbj4A==", + "dev": true, + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz", + "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "bin": { - "pino-pretty": "bin.js" - } - }, - "node_modules/pino-pretty/node_modules/readable-stream": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz", - "integrity": "sha512-cbAdYt0VcnpN2Bekq7PU+k363ZRsPwJoEEJOEtSJQlJXzwaxt3FIo/uL+KeDSGIjJqtkwyge4KQgD2S2kd+CQw==", - "dev": true, - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-std-serializers": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", - "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", - "dev": true - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", - "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true, + "license": "ISC" + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", - "dev": true, - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/should-proxy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/should-proxy/-/should-proxy-1.0.4.tgz", - "integrity": "sha512-RPQhIndEIVUCjkfkQ6rs6sOR6pkxJWCNdxtfG5pP0RVgUYbK5911kLTF0TNcCC0G3YCGd492rMollFT2aTd9iQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/sonic-boom": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", - "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", - "dev": true, - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/streamx": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", - "integrity": "sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "dependencies": { - "streamx": "^2.12.5" - } - }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4" - } - }, - "node_modules/thread-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", - "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", - "dev": true, - "dependencies": { - "real-require": "^0.2.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/should-proxy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/should-proxy/-/should-proxy-1.0.4.tgz", + "integrity": "sha512-RPQhIndEIVUCjkfkQ6rs6sOR6pkxJWCNdxtfG5pP0RVgUYbK5911kLTF0TNcCC0G3YCGd492rMollFT2aTd9iQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unxhr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.0.1.tgz", - "integrity": "sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg==", - "dev": true, - "engines": { - "node": ">=8.11" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", - "dev": true, - "dependencies": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yauzl": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", - "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "pend": "~1.2.0" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3" - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dev": true, + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unxhr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.0.1.tgz", + "integrity": "sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.11" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vinyl": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", + "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3" } } } +} diff --git a/doc/package.json b/doc/package.json index f749805b6..4b00fd905 100644 --- a/doc/package.json +++ b/doc/package.json @@ -1,7 +1,10 @@ { "devDependencies": { - "@antora/cli": "3.1.10", - "@antora/site-generator": "3.1.10", - "antora": "3.1.10" + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14", + "antora": "3.1.14" + }, + "dependencies": { + "@antora/lunr-extension": "^1.0.0-alpha.12" } } diff --git a/doc/supplemental-ui/css/site-extra.css b/doc/supplemental-ui/css/site-extra.css new file mode 100644 index 000000000..f723e8c70 --- /dev/null +++ b/doc/supplemental-ui/css/site-extra.css @@ -0,0 +1,171 @@ +/* Overall code block styling - Modern dark theme */ +.listingblock .content pre, +.listingblock .content pre.highlight, +pre.highlight code.language-c\+\+ { + background-color: #1e1e2e !important; + border: 1px solid #313244 !important; + border-radius: 8px !important; + padding: 1.25rem !important; + overflow-x: auto !important; + font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace !important; + font-size: 0.9rem !important; + line-height: 1.6 !important; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important; +} + +/* Base code color */ +.listingblock code, +code.language-c\+\+, +code.hljs { + color: #cdd6f4 !important; + background: transparent !important; +} + +/* C++ Syntax Highlighting - highlight.js classes */ + +/* Keywords (int, if, else, while, return, constexpr, etc.) */ +.hljs-keyword, +.hljs-selector-tag { + color: #cba6f7 !important; /* Purple */ + font-weight: 600 !important; +} + +/* Built-in types and namespaces (std, boost, etc.) */ +.hljs-built_in { + color: #89dceb !important; /* Cyan */ +} + +/* Strings */ +.hljs-string, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #a6e3a1 !important; /* Green */ +} + +/* Comments */ +.hljs-comment, +.hljs-quote { + color: #6c7086 !important; /* Gray */ + font-style: italic !important; +} + +/* Preprocessor directives (#include, #define, #ifndef, etc.) */ +.hljs-meta { + color: #f9e2af !important; /* Yellow */ +} + +/* Meta keywords inside preprocessor (include, define, etc.) */ +.hljs-meta-keyword { + color: #fab387 !important; /* Peach */ + font-weight: 500 !important; +} + +/* Meta strings (header files in #include) */ +.hljs-meta-string { + color: #a6e3a1 !important; /* Green */ +} + +/* Types and class names */ +.hljs-type, +.hljs-class .hljs-title, +.hljs-title.class_ { + color: #89dceb !important; /* Cyan */ + font-weight: 500 !important; +} + +/* Function names */ +.hljs-function .hljs-title, +.hljs-title.function_ { + color: #89b4fa !important; /* Blue */ + font-weight: 500 !important; +} + +/* Numbers */ +.hljs-number, +.hljs-literal { + color: #fab387 !important; /* Peach */ +} + +/* Operators and punctuation */ +.hljs-operator, +.hljs-punctuation { + color: #94e2d5 !important; /* Teal */ +} + +/* Variables and parameters */ +.hljs-variable, +.hljs-params { + color: #cdd6f4 !important; /* Light gray */ +} + +/* Template parameters */ +.hljs-template-tag { + color: #f5c2e7 !important; /* Pink */ +} + +/* Attributes */ +.hljs-attribute { + color: #f38ba8 !important; /* Red */ +} + +/* Selection highlighting */ +.listingblock ::selection, +.hljs ::selection { + background-color: #45475a !important; + color: #f5e0dc !important; +} + +/* Optional: Line numbers if you add them later */ +.listingblock .linenos, +.hljs-ln-numbers { + color: #585b70 !important; + margin-right: 1rem !important; + padding-right: 0.5rem !important; + border-right: 1px solid #313244 !important; + user-select: none !important; +} + +/* Make sure inline code also gets styled */ +code.hljs-inline { + background-color: #313244 !important; + padding: 0.2em 0.4em !important; + border-radius: 3px !important; + font-size: 0.85em !important; +} + +/* Plain listing blocks (output blocks without syntax highlighting) */ +.doc .listingblock:not(:has(.hljs)) > .content > pre, +.doc .listingblock > .content > pre:not(.highlight), +.doc .literalblock > pre { + background-color: #f8f9fa !important; /* Light background */ + color: #24292e !important; /* Dark text */ + border: 1px solid #e1e4e8 !important; + border-radius: 6px !important; + padding: 1rem !important; + font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace !important; + font-size: 0.875rem !important; + line-height: 1.5 !important; +} + +/* Ensure text in plain blocks is dark */ +.doc .listingblock:not(:has(.hljs)) code, +.doc .literalblock code { + color: #24292e !important; /* Dark text */ + background: transparent !important; +} + +/* Alternative: Target blocks that come after "Expected Output:" text */ +.paragraph:has(> p:contains("Expected Output")) + .listingblock > .content > pre { + background-color: #f8f9fa !important; + color: #24292e !important; + border: 1px solid #d73a49 !important; /* Red border for output */ +} + +/* If the blocks have a specific role or class, use this more specific selector */ +.listingblock.output > .content > pre, +.listingblock .content > pre.output { + background-color: #fafbfc !important; + color: #24292e !important; + border-left: 4px solid #28a745 !important; /* Green left border */ + border-radius: 4px !important; +} diff --git a/doc/supplemental-ui/partials/footer-content.hbs b/doc/supplemental-ui/partials/footer-content.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/doc/supplemental-ui/partials/head-styles.hbs b/doc/supplemental-ui/partials/head-styles.hbs new file mode 100644 index 000000000..6b488beb1 --- /dev/null +++ b/doc/supplemental-ui/partials/head-styles.hbs @@ -0,0 +1,6 @@ + + + diff --git a/doc/supplemental-ui/partials/header-content.hbs b/doc/supplemental-ui/partials/header-content.hbs new file mode 100644 index 000000000..12efb2cf6 --- /dev/null +++ b/doc/supplemental-ui/partials/header-content.hbs @@ -0,0 +1,50 @@ +
+ +
+ diff --git a/doc/supplemental-ui/partials/pagination.hbs b/doc/supplemental-ui/partials/pagination.hbs new file mode 100644 index 000000000..902e4a890 --- /dev/null +++ b/doc/supplemental-ui/partials/pagination.hbs @@ -0,0 +1,16 @@ +{{#if (or page.previous page.next)}} + +{{/if}} diff --git a/doc/supplemental-ui/partials/toolbar.hbs b/doc/supplemental-ui/partials/toolbar.hbs new file mode 100644 index 000000000..cf076165a --- /dev/null +++ b/doc/supplemental-ui/partials/toolbar.hbs @@ -0,0 +1,9 @@ + diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 000000000..2211df63d --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +*.txt diff --git a/examples/addition.cpp b/examples/addition.cpp new file mode 100644 index 000000000..4b9b059e9 --- /dev/null +++ b/examples/addition.cpp @@ -0,0 +1,37 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This example shows the difference in the results of repeated addition + +#include // For type decimal32_t and std::numeric_limits support +#include // For decimal support to +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; + + constexpr decimal32_t decimal_one_tenth {"0.1"}; // Construct constant 0.1 from string for lossless conversion + constexpr float float_one_tenth {0.1f}; // Construct floating point constant from literal + + decimal32_t decimal_value {}; // Construct decimal 0 to start from + float float_value {}; // Construct float 0 to start from + + // We now add 0.1 1000 times which should result exactly in 100 + // What we actually find is that the decimal32_t value does result in exactly 100 + // With type float the result is not 100 due to inexact representation + for (int i {}; i < 1000; ++i) + { + decimal_value += decimal_one_tenth; // Decimal types support compound arithmetic as expected + float_value += float_one_tenth; + } + + // Each of the decimal types has complete support for std::numeric_limits, + // which we leverage here with set precision to show any fractional part of the number (if applicable) + std::cout << std::setprecision(std::numeric_limits::digits10) + << "Decimal Result: " << decimal_value << "\n" + << std::setprecision(std::numeric_limits::digits10) + << " Float Result: " << float_value << std::endl; +} diff --git a/examples/adl.cpp b/examples/adl.cpp index 1ad40a0c6..166c109a5 100644 --- a/examples/adl.cpp +++ b/examples/adl.cpp @@ -1,41 +1,55 @@ // Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt - -#include -#include +// +// This example shows how we are able to use adl with Boost.Decimal to allow a template function +// to use both built-in binary floating point types, as well as Boost.Decimal types + +#include // For type decimal32_t +#include // For type decimal64_t +#include // For type decimal128_t +#include // For support +#include // For sin function +#include #include -int error_counter = 0; - -template -bool float_equal(T lhs, T rhs) -{ - using std::fabs; - return fabs(lhs - rhs) < std::numeric_limits::epsilon(); // numeric_limits is overloaded for all decimal types -} - template -void test(T val) +void sin_identity(T val) { - using std::sin; // ADL allows builtin and decimal types to both be used - if (!float_equal(sin(val), -sin(-val))) // sin(x) == -sin(-x) - { - ++error_counter; - } + // ADL allows builtin and decimal types to both be used + // Boost.Decimal is not allowed to overload std::sin so it must be provided in its own namespace + // You must also include using std::sin to ensure that it is found for the float, double, and long double cases. + // It is preferred to have using statements for the functions you intend to use instead of using namespace XXX. + using std::sin; + using boost::decimal::sin; + + // sin(x) = -sin(-x) + // The call here MUST be unqualified, or you will get compiler errors + // For example calling std::sin here would not allow any of the decimal types to be used + std::cout << "sin(" << val << ") = " << sin(val) << '\n' + << "-sin(" << -val << ") = " << -sin(-val) << "\n\n"; } int main() { - test(-0.5F); - test(-0.5); - test(-0.5L); + // Because of the two using statements in the above function we can now call it with built-in floating point, + // or our decimal types as show below - test(boost::decimal::decimal32_t{-5, -1}); - test(boost::decimal::decimal64_t{-5, -1}); - test(boost::decimal::decimal128_t{-5, -1}); + std::cout << "Float:\n"; + sin_identity(-0.5F); - return error_counter; -} + std::cout << "Double:\n"; + sin_identity(-0.5); + + std::cout << "Long Double:\n"; + sin_identity(-0.5L); + std::cout << "decimal32_t:\n"; + sin_identity(boost::decimal::decimal32_t{"-0.5"}); + std::cout << "decimal64_t:\n"; + sin_identity(boost::decimal::decimal64_t{"-0.5"}); + + std::cout << "decimal128_t:\n"; + sin_identity(boost::decimal::decimal128_t{"-0.5"}); +} diff --git a/examples/basic_arithmetic.cpp b/examples/basic_arithmetic.cpp new file mode 100644 index 000000000..8f0331168 --- /dev/null +++ b/examples/basic_arithmetic.cpp @@ -0,0 +1,47 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates some of the basic numerical operations with the decimal types + +#include // For type decimal64_t +#include // For decimal overloads of functions +#include // For decimal support of and +#include +#include + +int main() +{ + using boost::decimal::decimal64_t; // Type decimal64_t + + constexpr decimal64_t a {"-5.123456891234567"}; // Constructs -5.123456 from string + constexpr decimal64_t b {"3.123456891234567"}; // Constructs 3.123456 from string + constexpr decimal64_t c {a + b}; + + // Here we can see that the result is exact + constexpr decimal64_t neg_two {-2}; + static_assert(c == neg_two, "Result should be exact"); + + // We can use std::setprecision and std::numeric_limits in their usual ways + std::cout << std::setprecision(std::numeric_limits::digits10) + << "A: " << a << '\n' + << "B: " << b << '\n' + << "A + B: " << c << '\n'; + + // The decimal library provides comprehensive implementations of the functions + // that you would expect to have with the builtin floating point types + // + // They are all located in namespace boost::decimal::, + // as overloading namespace std is not allowed + + constexpr decimal64_t abs_c {boost::decimal::abs(c)}; + std::cout << "abs(A + B): " << abs_c << '\n'; + + // All cmath functions are constexpr even if their std:: counterparts are not + constexpr decimal64_t sqrt_two {boost::decimal::sqrt(abs_c)}; + + // Value compute by N[Sqrt[2], 50] using Wolfram Alpha or Mathematica + constexpr decimal64_t wa_sqrt_two {"1.4142135623730950488016887242096980785696718753769"}; + std::cout << "sqrt(abs(A + B)): " << sqrt_two << '\n' + << "Wolfram Alpha sqrt(2): " << wa_sqrt_two << '\n'; +} diff --git a/examples/basic_construction.cpp b/examples/basic_construction.cpp index 560e1a8c4..7ec722da5 100644 --- a/examples/basic_construction.cpp +++ b/examples/basic_construction.cpp @@ -1,18 +1,32 @@ // Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates some of the very basic ways you con construct decimal types +// This includes: from integer; integer and exponent; integer exponent and sign; string -#include +#include // For decimal32_t type +#include // For support of decimal types +#include // For isnan and isinf +#include #include -#include int main() { - using namespace boost::decimal; + using boost::decimal::decimal32_t; // The decimal32_t type + using boost::decimal::construction_sign; // An enum class for specifying sign during certain instances of construction + using boost::decimal::isinf; // Analogous to std::isinf but for decimal types + using boost::decimal::isnan; // Analogous to std::isnan but for decimal types - constexpr decimal32_t val_1 {100}; // Construction from an integer - constexpr decimal32_t val_2 {10, 1}; // Construction from a signed integer and exponent - constexpr decimal32_t val_3 {1U, 2, false}; // Construction from an unsigned integer, exponent, and sign + // Construction from an integer + constexpr decimal32_t val_1 {100}; + + // Construction from a signed integer and exponent + constexpr decimal32_t val_2 {10, 1}; + + // Construction from an unsigned integer, exponent, and sign + // The sign enum is named construction_sign, and has two members: positive and negative + constexpr decimal32_t val_3 {1U, 2, construction_sign::negative}; std::cout << "Val_1: " << val_1 << '\n' << "Val_2: " << val_2 << '\n' @@ -23,23 +37,70 @@ int main() std::cout << "All equal values" << std::endl; } - constexpr decimal64_t val_4 {decimal64_t{2, -1} + decimal64_t{1, -1}}; - constexpr double float_val_4 {0.2 + 0.1}; - const decimal64_t val_5 { float_val_4 }; + // Demonstration of the overflow and underflow handling + // A value that overflows constructs an infinity (which can be queried using isinf) + // A value that underflows constructs a zero + constexpr decimal32_t overflow_value {100, 10000}; + if (isinf(overflow_value)) + { + std::cout << "Overflow constructs infinity" << std::endl; + } - std::cout << std::setprecision(17) << "Val_4: " << val_4 << '\n' - << "Float: " << float_val_4 << '\n' - << "Val_5: " << val_5 << '\n'; + constexpr decimal32_t underflow_value {100, -10000}; + constexpr decimal32_t zero {0}; + if (underflow_value == zero) + { + std::cout << "Underflow constructs zero" << std::endl; + } - if (val_4 == val_5) + // Construction of NANs can be done using numeric limits, + // and checked using the normal isnan function + constexpr decimal32_t non_finite_from_float {std::numeric_limits::quiet_NaN()}; + if (isnan(non_finite_from_float)) { - std::cout << "Floats are equal" << std::endl; + std::cout << "NaN constructs NaN" << std::endl; } - else + + // We can also construct both from a C-string (const char*) and from a std::string + + const char* c_string_value {"4.3e-02"}; + const decimal32_t from_c_string {c_string_value}; + const decimal32_t from_std_string {std::string(c_string_value)}; + + if (from_c_string == from_std_string) { - std::cout << "Floats are not equal" << std::endl; + std::cout << "Values constructed from const char* and std::string are the same" << '\n'; } - return 0; -} + // If we attempt construction for a string that cannot be converted into a decimal value, + // the constructor will do 1 of 2 things: + // 1) In a noexcept environment the constructor will return a quiet NaN + // 2) Otherwise it will throw + // + // The exception environment is detected automatically, + // or can be set by defining BOOST_DECIMAL_DISABLE_EXCEPTIONS + + const char* bad_string {"Junk_String"}; + #ifndef BOOST_DECIMAL_DISABLE_EXCEPTIONS + + try + { + const decimal32_t throwing_value {bad_string}; + std::cout << throwing_value << '\n'; + } + catch (const std::runtime_error& e) + { + std::cout << e.what() << std::endl; + } + + #else + + const decimal32_t nan_value {bad_string}; + if (isnan(nan_value)) + { + std::cout << "Bad string construction has formed a NAN" << std::endl; + } + + #endif +} diff --git a/examples/binary_float_conversions.cpp b/examples/binary_float_conversions.cpp new file mode 100644 index 000000000..3b1a5f3a6 --- /dev/null +++ b/examples/binary_float_conversions.cpp @@ -0,0 +1,79 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates how to convert various types to decimal types and back, +// along with edge case handling + +#include // For type decimal32_t +#include // For type decimal64_t +#include // For decimal support of cmath functions +#include // For decimal support of and +#include // For decimal support of +#include +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; // Type decimal32_t + using boost::decimal::decimal64_t; // Type decimal64_t + + // Non-finite values construct the equivalent non-finite value in binary floating point + constexpr decimal64_t decimal_qnan {std::numeric_limits::quiet_NaN()}; + const double double_from_qnan {static_cast(decimal_qnan)}; + + // Note here that we must use boost::decimal::isnan for decimal types, + // as it is illegal to overload std::isnan + if (boost::decimal::isnan(decimal_qnan) && std::isnan(double_from_qnan)) + { + std::cout << "Decimal QNAN converts to double QNAN\n"; + } + + constexpr decimal64_t decimal_inf {std::numeric_limits::infinity()}; + const double double_from_inf {static_cast(decimal_inf)}; + + // Same as the above but with INF instead of NAN + if (boost::decimal::isinf(decimal_inf) && std::isinf(double_from_inf)) + { + std::cout << "Decimal INFINITY converts to double INFINITY\n"; + } + + // For finite values we make a best effort approach to covert to double + // We are able to decompose the decimal floating point value into a sign, significand, and exponent. + // From there we use the methods outline in Daniel Lemire's "Number Parsing at a Gigabyte a Second", + // to construct the binary floating point value. + // See: https://arxiv.org/pdf/2101.11408 + + // Construct the decimal64_t version of pi using our pre-computed constants from + constexpr decimal64_t decimal_pi {boost::decimal::numbers::pi_v}; + const double double_from_pi {static_cast(decimal_pi)}; + + std::cout << std::setprecision(std::numeric_limits::digits10) + << "decimal64_t pi: " << decimal_pi << '\n' + << " double pi: " << double_from_pi << '\n'; + + // To construct a decimal64_t from double we use the methods described in "Ryu: fast float-to-string conversion" + // See: https://dl.acm.org/doi/10.1145/3192366.3192369 + // This paper shows how to decompose a double into it's sign, significand, and exponent + // Once we have those components we can use the normal constructors of the decimal types to construct + // Since we are using the normal constructors here, + // any construction from this conversion is subject to the current rounding mode + // Such as with a lossy conversion like shown (double -> decimal32_t) + + const decimal64_t decimal_from_double {static_cast(double_from_pi)}; + const decimal32_t lossy_decimal_from_double {static_cast(double_from_pi)}; + + std::cout << " Converted pi: " << decimal_from_double << '\n' + << "decimal32_t pi: " << lossy_decimal_from_double << '\n'; + + + // Other than what has already been shown, + // there are no other ways in the library to convert between decimal types and binary floating point types + // The reason for this is to discourage their use. + // + // You can use intermediate representations like strings if you want to make these conversions, + // and want to be sure about what the resulting value will be + + return 0; +} diff --git a/examples/bit_conversions.cpp b/examples/bit_conversions.cpp index 86a15863f..a40d496b1 100644 --- a/examples/bit_conversions.cpp +++ b/examples/bit_conversions.cpp @@ -2,24 +2,41 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include +#include +#include +#include #include -#include - -using namespace boost::decimal; int main() { - const decimal_fast32_t fast_type {5}; - const std::uint32_t BID_bits {to_bid(fast_type)}; - const std::uint32_t DPD_bits {to_dpd(fast_type)}; + using boost::decimal::decimal32_t; + using boost::decimal::from_bid; + using boost::decimal::from_dpd; + using boost::decimal::to_bid; + using boost::decimal::to_dpd; + + // First we construct a decimal value and then convert it into both BID and DPD encoded bits + const decimal32_t decimal_value {5}; + const std::uint32_t BID_bits {to_bid(decimal_value)}; + const std::uint32_t DPD_bits {to_dpd(decimal_value)}; + // Display the difference between the hex values of both bit encodings std::cout << std::hex << "BID format: " << BID_bits << '\n' << "DPD format: " << DPD_bits << std::endl; + // Recover the original value by encoding two new decimals using the from_bid and from_dpd functions const decimal32_t bid_decimal {from_bid(BID_bits)}; const decimal32_t dpd_decimal {from_dpd(DPD_bits)}; - return !(bid_decimal == dpd_decimal); + if (bid_decimal == dpd_decimal) + { + // These should both have recovered the original value of 5 + return 0; + } + else + { + // Something has gone wrong recovering the decimal values + return 1; + } } diff --git a/examples/charconv.cpp b/examples/charconv.cpp index feec96662..27f32f794 100644 --- a/examples/charconv.cpp +++ b/examples/charconv.cpp @@ -1,31 +1,100 @@ // Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates the various ways that support can be used with the decimal library +// NOTE: need not be included to use this functionality -#include -#include -#include +#include // For the type decimal64_t +#include // For support +#include // For decimal support +#include // +#include // For std::strlen int main() { - using namespace boost::decimal; + using boost::decimal::decimal64_t; // The type decimal64_t + using boost::decimal::to_chars; // The to_chars functions + using boost::decimal::to_chars_result; // The return type of to_chars + using boost::decimal::from_chars; // The from_chars functions + using boost::decimal::from_chars_result;// The return type of from_chars + using boost::decimal::chars_format; // The enum class of the different formatting options + using boost::decimal::formatting_limits;// Allows the user to correctly size buffers - decimal64_t val {0.25}; // Construction from a double (not recommended but explicit construction is allowed) + const char* initial_value {"-7.12345e+06"}; - char buffer[256]; - auto r_to = to_chars(buffer, buffer + sizeof(buffer) - 1, val); - assert(r_to); // checks std::errc() - *r_to.ptr = '\0'; + decimal64_t initial_decimal; + const from_chars_result r_initial {from_chars(initial_value, initial_value + std::strlen(initial_value), initial_decimal)}; - decimal64_t return_value; - BOOST_DECIMAL_ATTRIBUTE_UNUSED auto r_from = from_chars(buffer, buffer + std::strlen(buffer), return_value); - assert(r_from); + // from_chars_result contains a value of std::errc, but also has a bool operator for better checks like this + // Regular should be getting this bool operator in C++26 + if (!r_initial) + { + // LCOV_EXCL_START + // Here you can handle an error condition in any way you see fit + // For the purposes of our example we log and abort + std::cout << "Unexpected failure" << std::endl; + return 1; + // LCOV_EXCL_STOP + } + else + { + std::cout << "Initial decimal: " << initial_decimal << '\n'; + } - assert(val == return_value); + // boost::decimal::from_chars deviates from the C++ standard by allowing a std::string, + // or a std::string_view (when available) + // + // It is also perfectly acceptable to use an auto return type for even more brevity when using from_chars + const std::string string_value {"3.1415"}; + decimal64_t string_decimal; + const auto r_string {from_chars(string_value, string_decimal)}; + if (r_string) + { + std::cout << "Value from string: " << string_decimal << '\n'; + } - std::cout << " Initial Value: " << val << '\n' - << "Returned Value: " << return_value << std::endl; + // We can now compare the various ways to print the value + // First we will review the formatting_limits struct + // This struct contains a number of members that allow the to_chars buffer to be correctly sized + // + // First formatting_limits takes a type and optionally a precision as template parameters + // It then has members each corresponding to the maximum number of characters needed to print the type + // + // 1) scientific_format_max_chars + // 2) fixed_format_max_chars + // 3) hex_format_max_chars + // 4) cohort_preserving_scientific_max_chars + // 5) general_format_max_chars + // 6) max_chars - Equal to the maximum value of 1 to 5 to allow to_chars of any format + // + // Each of these will give you one additional character so you can write a null terminator to the end + // NOTE: to_chars IS NOT default null terminated - return 0; -} + char scientific_buffer[formatting_limits::scientific_format_max_chars]; + const to_chars_result r_sci {to_chars(scientific_buffer, + scientific_buffer + sizeof(scientific_buffer), initial_decimal, chars_format::scientific)}; + if (r_sci) + { + *r_sci.ptr = '\0'; // to_chars does not null terminate per the C++ standard + std::cout << "Value in scientific format: " << scientific_buffer << '\n'; + } + // else handle the error how you would like + + // If we went to print the value to some specified precision our buffer will need more space + // Formatting limits takes a precision in this case + // + // Also as with from_chars it's perfectly fine to use an auto return type with to_chars + constexpr int required_precision {20}; + char precision_20_scientific_buffer[formatting_limits::scientific_format_max_chars]; + const auto r_sci20 {to_chars(precision_20_scientific_buffer, + precision_20_scientific_buffer + sizeof(precision_20_scientific_buffer), + initial_decimal, chars_format::scientific, required_precision)}; + if (r_sci20) + { + *r_sci20.ptr = '\0'; + std::cout << "Value in scientific format with precision 20: " << precision_20_scientific_buffer << '\n'; + } + // else handle the error how you would like +} diff --git a/examples/charconv_cohort_preservation.cpp b/examples/charconv_cohort_preservation.cpp new file mode 100644 index 000000000..62097c382 --- /dev/null +++ b/examples/charconv_cohort_preservation.cpp @@ -0,0 +1,113 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates the effects of cohorts and how to maintain them with + +#include // For the type decimal32_t +#include // For decimal support for +#include // For decimal support for +#include +#include +#include +#include + +static constexpr std::size_t N {7}; + +// All the following decimal values will compare equal, +// but since they have different numbers of 0s in the significand they will not be bitwise equal +constexpr std::array decimals = { + boost::decimal::decimal32_t{3, 2}, + boost::decimal::decimal32_t{30, 1}, + boost::decimal::decimal32_t{300, 0}, + boost::decimal::decimal32_t{3000, -1}, + boost::decimal::decimal32_t{30000, -2}, + boost::decimal::decimal32_t{300000, -3}, + boost::decimal::decimal32_t{3000000, -4}, +}; + +// These strings represent the same values as the constructed ones shown above +constexpr std::array strings = { + "3e+02", + "3.0e+02", + "3.00e+02", + "3.000e+02", + "3.0000e+02", + "3.00000e+02", + "3.000000e+02", +}; + +int main() +{ + using boost::decimal::decimal32_t; // For type decimal32_t + using boost::decimal::from_chars; // decimal specific from_chars + using boost::decimal::chars_format; // chars_format enum with decimal specific option shown here + + // In some instances we want to preserve the cohort of our values + // In the above strings array all of these values compare equal, + // but will NOT be bitwise equal once constructed. + + for (std::size_t i = 0; i < N; ++i) + { + decimal32_t string_val; + const auto r_from = from_chars(strings[i], string_val, chars_format::cohort_preserving_scientific); + + if (!r_from) + { + // Unexpected failure + return 1; + } + + for (std::size_t j = 0; j < N; ++j) + { + // Now that we have constructed a value from string + // we can compare it bitwise to all the members of the decimal array + // to show the difference between operator== and bitwise equality + // + // All members of a cohort are supposed to compare equal with operator==, + // and likewise will hash equal to + std::uint32_t string_val_bits; + std::uint32_t constructed_val_bits; + + std::memcpy(&string_val_bits, &string_val, sizeof(string_val_bits)); + std::memcpy(&constructed_val_bits, &decimals[j], sizeof(constructed_val_bits)); + + if (string_val == decimals[j]) + { + std::cout << "Values are equal and "; + if (string_val_bits == constructed_val_bits) + { + std::cout << "bitwise equal.\n"; + } + else + { + std::cout << "NOT bitwise equal.\n"; + } + } + } + + // The same chars_format option applies to to_chars which allows us to roundtrip the values + char buffer[boost::decimal::formatting_limits::cohort_preserving_scientific_max_chars] {}; + const auto r_to = to_chars(buffer, buffer + sizeof(buffer), string_val, chars_format::cohort_preserving_scientific); + + if (!r_to) + { + // Unexpected failure + return 1; + } + + *r_to.ptr = '\0'; // charconv does not null terminate per the C++ specification + + if (std::strcmp(strings[i], buffer) == 0) + { + std::cout << "Successful Roundtrip of value: " << buffer << "\n\n"; + } + else + { + std::cout << "Failed\n\n"; + return 1; + } + } + + return 0; +} diff --git a/examples/currency_conversion.cpp b/examples/currency_conversion.cpp deleted file mode 100644 index e791c8993..000000000 --- a/examples/currency_conversion.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2025 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#include -#include -#include - -using namespace boost::decimal; - -auto convert_currency(decimal64_t amount, decimal64_t exchange_rate) -> decimal64_t -{ - return amount * exchange_rate; -} - -int main() -{ - const auto usd_amount = strtod64("1000.50", nullptr); - const auto usd_to_eur_rate = strtod64("0.92", nullptr); - - const decimal64_t eur_amount = convert_currency(usd_amount, usd_to_eur_rate); - constexpr decimal64_t exact_eur_amount(92046, -2); - - std::cout << "USD: " << std::fixed << std::setprecision(2) << usd_amount << "\n"; - std::cout << "EUR: " << std::fixed << std::setprecision(2) << eur_amount << "\n"; - - return !(eur_amount == exact_eur_amount); -} diff --git a/examples/debugger.cpp b/examples/debugger.cpp new file mode 100644 index 000000000..3864d30aa --- /dev/null +++ b/examples/debugger.cpp @@ -0,0 +1,59 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This example, when run with the pretty printers, shows how various values are represented + +#include // For type decimal32_t +#include // For type decimal64_t +#include // For type decimal128_t +#include // For type decimal_fast32_t +#include // For nan function to write payload to nans +#include + +template +void debug_values() +{ + // Displays the maximum and minimum values that the type can hold + // from numeric_limits + const T max {std::numeric_limits::max()}; + const T min {std::numeric_limits::min()}; + + // A number whose representation will change based on IEEE vs fast type + // In the IEEE case 3.140e+00 will be displayed as the pretty printer is cohort preserving + const T short_num {"3.140"}; + + // Shows how infinities will be displayed + const T pos_inf {std::numeric_limits::infinity()}; + const T neg_inf {-std::numeric_limits::infinity()}; + + // Shows how the different kinds of NANs will be displayed + const T qnan {std::numeric_limits::quiet_NaN()}; + const T snan {std::numeric_limits::signaling_NaN()}; + + // Shows how a payload added to a QNAN will be displayed + const T payload_nan {boost::decimal::nan("7")}; + + // Break Here: + static_cast(max); + static_cast(min); + static_cast(short_num); + static_cast(pos_inf); + static_cast(neg_inf); + static_cast(qnan); + static_cast(snan); + static_cast(payload_nan); +} + +int main() +{ + debug_values(); + debug_values(); + debug_values(); + + debug_values(); + debug_values(); + debug_values(); + + return 0; +} diff --git a/examples/first_example.cpp b/examples/first_example.cpp new file mode 100644 index 000000000..9c2f486c5 --- /dev/null +++ b/examples/first_example.cpp @@ -0,0 +1,26 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include // This includes the entire decimal library +#include +#include + +int main() +{ + using namespace boost::decimal::literals; // The literals are in their own namespace like std::literals + + // First we show the result of 0.1 + 0.2 using regular doubles + std::cout << std::fixed << std::setprecision(17) + << "Using doubles:\n" + << "0.1 + 0.2 = " << 0.1 + 0.2 << "\n\n"; + + // Construct the two decimal values + // We construct using the literals defined by the library + constexpr boost::decimal::decimal64_t a {0.1_DD}; + constexpr boost::decimal::decimal64_t b {0.2_DD}; + + // Now we display the result of the same calculation using decimal64_t + std::cout << "Using decimal64_t:\n" + << "0.1_DD + 0.2_DD = " << a + b << std::endl; +} diff --git a/examples/fmt_format.cpp b/examples/fmt_format.cpp index df821fd4e..8ca34bc40 100644 --- a/examples/fmt_format.cpp +++ b/examples/fmt_format.cpp @@ -1,21 +1,42 @@ // Copyright 2025 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This example demonstrates usage and formatting of decimal types with fmt -#include +#include // For type decimal32_t +#include // For type decimal64_t +#include // For {fmt} support #include #if defined(BOOST_DECIMAL_HAS_FMTLIB_SUPPORT) && defined(BOOST_DECIMAL_TEST_FMT) -#include - int main() { - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; - + constexpr boost::decimal::decimal64_t val1 {"3.14"}; + constexpr boost::decimal::decimal32_t val2 {"3.141"}; + + // The easiest is no specification which is general format + // Given these values they will print in fixed format + std::cout << "Default Format:\n"; + std::cout << fmt::format("{}", val1) << '\n'; + std::cout << fmt::format("{}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + std::cout << "Scientific Format:\n"; + std::cout << fmt::format("{:e}", val1) << '\n'; + std::cout << fmt::format("{:e}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + // Here this gives one digit of precision rounded according to current rounding mode + std::cout << "Scientific Format with Specified Precision:\n"; + std::cout << fmt::format("{:.1e}", val1) << '\n'; + std::cout << fmt::format("{:.1e}", val2) << "\n\n"; + + // This combines the padding modifier (10), precision (3 digits), and a type modifier (e) + std::cout << "Scientific Format with Specified Precision and Padding:\n"; std::cout << fmt::format("{:10.3e}", val1) << '\n'; - std::cout << fmt::format("{:10.3e}", val2) << std::endl; + std::cout << fmt::format("{:10.3e}", val2) << '\n'; return 0; } diff --git a/examples/format.cpp b/examples/format.cpp index e2b3b68c2..e54b4a181 100644 --- a/examples/format.cpp +++ b/examples/format.cpp @@ -1,21 +1,45 @@ // Copyright 2025 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This example demonstrates usage and formatting of decimal types with -#include +#include // For type decimal32_t +#include // For type decimal64_t +#include // For support (when available) #include +// This macro is defined in boost/decimal/format.hpp if the platform has support #ifdef BOOST_DECIMAL_HAS_FORMAT_SUPPORT #include int main() { - constexpr boost::decimal::decimal64_t val1 {314, -2}; - constexpr boost::decimal::decimal32_t val2 {3141, -3}; - + constexpr boost::decimal::decimal64_t val1 {"3.14"}; + constexpr boost::decimal::decimal32_t val2 {"3.141"}; + + // The easiest is no specification which is general format + // Given these values they will print in fixed format + std::cout << "Default Format:\n"; + std::cout << std::format("{}", val1) << '\n'; + std::cout << std::format("{}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + std::cout << "Scientific Format:\n"; + std::cout << std::format("{:e}", val1) << '\n'; + std::cout << std::format("{:e}", val2) << "\n\n"; + + // Next we can add a type modifier to get scientific formatting + // Here this gives one digit of precision rounded according to current rounding mode + std::cout << "Scientific Format with Specified Precision:\n"; + std::cout << std::format("{:.1e}", val1) << '\n'; + std::cout << std::format("{:.1e}", val2) << "\n\n"; + + // This combines the padding modifier (10), precision (3 digits), and a type modifier (e) + std::cout << "Scientific Format with Specified Precision and Padding:\n"; std::cout << std::format("{:10.3e}", val1) << '\n'; - std::cout << std::format("{:10.3e}", val2) << std::endl; + std::cout << std::format("{:10.3e}", val2) << '\n'; return 0; } diff --git a/examples/integral_conversions.cpp b/examples/integral_conversions.cpp new file mode 100644 index 000000000..32ade06c8 --- /dev/null +++ b/examples/integral_conversions.cpp @@ -0,0 +1,78 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file demonstrates how to convert various types to decimal types and back, +// along with edge case handling + +#include // For type decimal32_t +#include // For type decimal64_t +#include // For decimal support of cmath functions +#include // For decimal support of and +#include // For decimal support of +#include +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; // Type decimal32_t + using boost::decimal::decimal64_t; // Type decimal64_t + + // Non-finite values construct std::numeric_limits::max() + constexpr decimal64_t decimal_qnan {std::numeric_limits::quiet_NaN()}; + const std::uint32_t int_from_nan {static_cast(decimal_qnan)}; + + // Note here that we must use boost::decimal::isnan for decimal types, + // as it is illegal to overload std::isnan + if (boost::decimal::isnan(decimal_qnan) && int_from_nan == std::numeric_limits::max()) + { + std::cout << "Decimal QNAN converts to Integer Max\n"; + } + + // Same thing happens with decimal infinities since integers don't have an infinity + constexpr decimal32_t decimal_inf {std::numeric_limits::infinity()}; + const std::uint64_t int_from_inf {static_cast(decimal_inf)}; + + // Same as the above but with INF instead of NAN + if (boost::decimal::isinf(decimal_inf) && int_from_inf == std::numeric_limits::max()) + { + std::cout << "Decimal INF converts to Integer Max\n"; + } + + // For finite values the construction of the resulting integer matches the behavior + // you are familiar with from binary floating point to integer conversions. + // Namely, the result will only have the integer component of the decimal + + // Construct the decimal64_t version of pi using our pre-computed constants from + constexpr decimal64_t decimal_pi {boost::decimal::numbers::pi_v}; + const std::uint32_t int_from_pi {static_cast(decimal_pi)}; + + std::cout << std::setprecision(std::numeric_limits::digits10) + << " decimal64_t pi: " << decimal_pi << '\n' + << "std::uint32_t pi: " << int_from_pi << "\n\n"; + + // Constructing a decimal value from an integer is lossless until + // the number of digits in the integer exceeds the precision of the decimal type + + std::cout << "Conversions will be lossless\n" + << " decimal64_t digits10: " << std::numeric_limits::digits10 << "\n" + << "std::uint32_t digits10: " << std::numeric_limits::digits10 << "\n"; + + constexpr decimal64_t decimal_from_u32_max {std::numeric_limits::max()}; + std::cout << " std::uint32_t max: " << std::numeric_limits::max() << "\n" + << "decimal64_t from max: " << decimal_from_u32_max << "\n\n"; + + // In the construction of lossy values the rounding will be handled according to + // the current global rounding mode. + + std::cout << "Conversions will be lossy\n" + << " decimal32_t digits10: " << std::numeric_limits::digits10 << "\n" + << "std::uint64_t digits10: " << std::numeric_limits::digits10 << "\n"; + + constexpr decimal32_t decimal_from_u64_max {std::numeric_limits::max()}; + std::cout << " std::uint64_t max: " << std::numeric_limits::max() << "\n" + << "decimal32_t from max: " << decimal_from_u64_max << '\n'; + + return 0; +} diff --git a/examples/literals.cpp b/examples/literals.cpp index 603820a0b..b8990d064 100644 --- a/examples/literals.cpp +++ b/examples/literals.cpp @@ -1,32 +1,72 @@ // Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This examples demonstrates decimal floating point literals, +// as well as numeric constants made available by the library -#include -#include +#include // For type decimal32_t +#include // For type decimal64_t +#include // For the decimal (user defined) literals +#include // For provided numeric constants +#include // For support to and +#include +#include +#include +#include -using namespace boost::decimal::literals; - -template -bool float_equal(T lhs, T rhs) +int main() { - using std::fabs; - return fabs(lhs - rhs) < std::numeric_limits::epsilon(); // numeric_limits is overloaded for all decimal types -} + using namespace boost::decimal::literals; // Much like the std namespace, literals are separate form the lib + using boost::decimal::decimal32_t; // Type decimal32_t + using boost::decimal::decimal64_t; // Type decimal64_t + // Defaulted numeric constants are available with type decimal64_t, + // much like std::numbers::pi defaults to double + constexpr auto default_pi {boost::decimal::numbers::pi}; + using default_type = std::remove_cv_t; + static_assert(std::is_same::value, "Defaulted value has type decimal64_t"); -int main() -{ - using namespace boost::decimal; + // You can also specify the type explicitly as these are template constants + constexpr decimal32_t decimal32_pi {boost::decimal::numbers::pi_v}; - BOOST_DECIMAL_ATTRIBUTE_UNUSED const auto pi_32 {"3.141592653589793238"_DF}; - BOOST_DECIMAL_ATTRIBUTE_UNUSED const auto pi_64 {"3.141592653589793238"_DD}; + // We can use std::setprecision from to see the real difference between the two values + // numeric_limits is also specialized for each type + std::cout << std::setprecision(std::numeric_limits::digits10) + << "32-bit Pi: " << decimal32_pi << '\n'; - assert(float_equal(pi_32, static_cast(pi_64))); // Explicit conversion between decimal types - assert(float_equal(pi_32, boost::decimal::numbers::pi_v)); // Constants available in numbers namespace - assert(float_equal(pi_64, numbers::pi)); // Default constant type is decimal64_t + std::cout << std::setprecision(std::numeric_limits::digits10) + << "64-bit Pi: " << default_pi << '\n'; - return 0; -} + // All of our types also offer user defined literals: + // _df or _DF for decimal32_t + // _dd or _DD for decimal64_t + // _dl or _DL for decimal128_t + // For fast types add an f to the end of each (e.g. _dff = decimal_fast32_t or _DLF decimal_fast128_t) + // + // Since we have specified the type using the literal it is safe to use auto for the type + // + // We construct both from the first 40 digits of pi + // The constructor will parse this and then round to the proper precision automatically + + constexpr auto literal32_pi {"3.141592653589793238462643383279502884197"_DF}; + constexpr auto literal64_pi {"3.141592653589793238462643383279502884197"_DD}; + + std::cout << std::setprecision(std::numeric_limits::digits10) + << "32-bit UDL Pi: " << literal32_pi << '\n'; + // Unlike built-in binary floating point, floating equal is acceptable with decimal floating point + // Float equal will automatically address cohorts as per IEEE 754 if required (not shown in this example) + if (literal32_pi == decimal32_pi) + { + std::cout << "Rounded UDL has the same value as the 32-bit constant" << '\n'; + } + std::cout << std::setprecision(std::numeric_limits::digits10) + << "64-bit UDL Pi: " << literal64_pi << '\n'; + + if (literal64_pi == default_pi) + { + std::cout << "Rounded UDL has the same value as the 64-bit constant" << '\n'; + } +} diff --git a/examples/moving_average.cpp b/examples/moving_average.cpp deleted file mode 100644 index 594069fa6..000000000 --- a/examples/moving_average.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2025 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#include "where_file.hpp" -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::decimal; - -struct daily_data -{ - std::string date; - decimal64_t open; - decimal64_t high; - decimal64_t low; - decimal64_t close; - decimal64_t volume; -}; - -// Function to split a CSV line into daily_data -auto parse_csv_line(const std::string& line) -> daily_data -{ - std::stringstream ss(line); - std::string token; - daily_data data; - - // Parse each column - std::getline(ss, data.date, ','); - std::getline(ss, token, ','); - from_chars(token.c_str(), token.c_str() + token.size(), data.open); - - std::getline(ss, token, ','); - from_chars(token.c_str(), token.c_str() + token.size(), data.high); - - std::getline(ss, token, ','); - from_chars(token.c_str(), token.c_str() + token.size(), data.low); - - std::getline(ss, token, ','); - from_chars(token.c_str(), token.c_str() + token.size(), data.close); - - std::getline(ss, token, ','); - from_chars(token.c_str(), token.c_str() + token.size(), data.volume); - - return data; -} - -int main() -{ - std::vector stock_data; - const int window_size = 30; - - // Open and read the CSV file - std::ifstream file(where_file("AAPL.csv")); - std::string line; - - // Skip header line - std::getline(file, line); - - // Read data - while (std::getline(file, line)) - { - stock_data.push_back(parse_csv_line(line)); - } - - // Calculate and print 30-day moving averages - std::cout << "Date,30-Day Moving Average\n"; - - size_t loop_count = 0; // Trivial counter to ensure this ran in the CI - for (size_t i = window_size - 1; i < stock_data.size(); ++i) - { - decimal64_t sum(0); - - // Calculate sum for the window - for (size_t j = 0; j < window_size; ++j) - { - sum += stock_data[i - j].close; - } - - // Calculate average - decimal64_t moving_avg = sum / decimal64_t(window_size); - - // Print result - std::cout << stock_data[i].date << "," - << std::fixed << std::setprecision(2) << moving_avg << "\n"; - - ++loop_count; - } - - return loop_count == 0U; -} diff --git a/examples/numerical_parsing.cpp b/examples/numerical_parsing.cpp new file mode 100644 index 000000000..7842856c6 --- /dev/null +++ b/examples/numerical_parsing.cpp @@ -0,0 +1,106 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file briefly demonstrates the difference in results when parsing monetary values between float and decimal32_t + +#include "where_file.hpp" +#include // For type decimal32_t +#include // For support to +#include // For decimal support to +#include +#include +#include +#include +#include +#include +#include +#include + +using boost::decimal::decimal32_t; + +template +T parse_opening_price(const std::string& line); + +template <> +float parse_opening_price(const std::string& line) +{ + const auto result {std::stof(line)}; + return result; +} + +template <> +decimal32_t parse_opening_price(const std::string& line) +{ + decimal32_t result; + const auto r = from_chars(line, result); + + // If we have a parse failure throw std::invalid_argument if the environment supports it, + // using std::invalid_argument which is the same thing thrown by std::stof in the float case + // + // If we are in a no throw environment returning a qNaN will poison our results as well + if (!r) + { + // LCOV_EXCL_START + result = std::numeric_limits::quiet_NaN(); + BOOST_DECIMAL_THROW_EXCEPTION(std::invalid_argument("Parsing has failed")); + // LCOV_EXCL_STOP + } + + return result; +} + +template +T parse_csv_line(const std::string& line) +{ + std::stringstream ss(line); + std::string token; + std::string date; + + std::getline(ss, date, ','); + std::getline(ss, token, ','); + + return parse_opening_price(token); +} + +int main() +{ + // We have a CSV file containing one years worth of daily stock data for AAPL + // Here we will show the differences that arise (however small) + // between parsing with float and decimal32_t + + // Open and read the CSV file + std::ifstream file(boost::decimal::where_file("AAPL.csv")); + std::string line; + + // Skip header line + std::getline(file, line); + + std::vector decimal_opening_prices; + std::vector float_opening_prices; + + // Parse each line once into decimal32_t and once into a float + while (std::getline(file, line)) + { + decimal_opening_prices.emplace_back(parse_csv_line(line)); + float_opening_prices.emplace_back(parse_csv_line(line)); + } + + // Use std::accumulate to get the sum of all the pricing information in the array + // This will be used to compare the total value parsed + const auto decimal_sum {std::accumulate(decimal_opening_prices.begin(), + decimal_opening_prices.end(), decimal32_t{0})}; + + const auto float_sum {std::accumulate(float_opening_prices.begin(), + float_opening_prices.end(), float{0})}; + + // This is the reference value that was found using the sum command of the CSV + // inside Microsoft Excel + const std::string ms_excel_result {"52151.99"}; + + std::cout << std::setprecision(std::numeric_limits::digits10 + 1) + << "Number of data points: " << decimal_opening_prices.size() << '\n' + << " Sum from MS Excel: " << ms_excel_result << '\n' + << "Sum using decimal32_t: " << decimal_sum << '\n' + << " Sum using float: " << float_sum << std::endl; +} diff --git a/examples/print.cpp b/examples/print.cpp index e46e6dff0..65dd66e42 100644 --- a/examples/print.cpp +++ b/examples/print.cpp @@ -16,8 +16,6 @@ #if defined(BOOST_DECIMAL_HAS_FORMAT_SUPPORT) && defined(BOOST_DECIMAL_HAS_PRINT_SUPPORT) -#include - int main() { constexpr boost::decimal::decimal64_t val1 {314, -2}; diff --git a/examples/promotion.cpp b/examples/promotion.cpp new file mode 100644 index 000000000..1a64c1c2e --- /dev/null +++ b/examples/promotion.cpp @@ -0,0 +1,76 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This file briefly demonstrates the results of mixed decimal comparisons and arithmetic + +#include // For the type decimal32_t +#include // For the type decimal64_t +#include // For decimal type support to +#include +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; + using boost::decimal::decimal64_t; + using boost::decimal::decimal128_t; + + // First construct two values that we will perform arithmetic with + const decimal32_t a {"5.2"}; + const decimal64_t b {"3.9"}; + + std::cout << "decimal32_t value (a): " << a << '\n' + << "decimal64_t value (b): " << b << '\n'; + + // Mixed decimal comparisons are allowed by default + if (a > b) + { + std::cout << "a is greater than b" << '\n'; + } + + // Even comparison of unrepresentable values is fine + // For example decimal32_t can't represent decimal64_t max value + constexpr decimal64_t dec64_max {std::numeric_limits::max()}; + if (a < dec64_max) + { + std::cout << a << " is less than " << dec64_max << '\n'; + } + + // Danger awaits if you decide to do this yourself instead of letting the system do it for you, + // since in this example the two should compare equal but overflowing decimal32_t makes infinity + if (static_cast(dec64_max) < dec64_max) + { + std::cout << dec64_max << " is less than " << static_cast(dec64_max) << '\n'; + } + + // With mixed operations like +, -, *, / we promote to the higher precision type + // Example: decimal32_t + decimal64_t -> decimal64_t + + // We use auto here for two reasons + // 1) To demonstrate that it's safe + // 2) To show the promotion with the conditional logic that follows + const auto c {a + b}; + using c_type = std::remove_cv_t; // We used const auto so the result is const decimal64_t + + static_assert(std::is_same::value, "decimal32_t + decimal64_t is supposed to yield decimal64_t"); + std::cout << "The result of a + b is a decimal64_t: " << c << '\n'; + + // Now we can look at similar promotion that occurs when an operation is performed between + // a decimal type and an integer + // + // Similar to the above when we have mixed operations like +, -, *, / we always promote to the decimal type + // Example: decimal64_t * int -> decimal64_t + + const auto d {2 * c}; + using d_type = std::remove_cv_t; + static_assert(std::is_same::value, "decimal64_t * integer is supposed to yield decimal64_t"); + std::cout << "The result of 2 * c is a decimal64_t: " << d << '\n'; + + // The full suite of comparison operators between decimal types and integers + if (d > 5) + { + std::cout << d << " is greater than 5" << '\n'; + } +} diff --git a/examples/rounding_mode.cpp b/examples/rounding_mode.cpp index 63b79b937..f41c0788a 100644 --- a/examples/rounding_mode.cpp +++ b/examples/rounding_mode.cpp @@ -1,18 +1,87 @@ -// Copyright 2024 Matt Borland +// Copyright 2024 - 2025 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This example demonstrates how to set and get the global rounding mode +// as well as the effects on numerical results -#include -#include +#include // For type decimal32_t +#include // For decimal literals +#include // For access to the rounding mode functions +#include // Decimal support to +#include + +void print_rounding_mode(const boost::decimal::rounding_mode current_mode) +{ + // All 5 rounding modes are defined by the enum rounding_mode + using boost::decimal::rounding_mode; + + switch (current_mode) + { + case rounding_mode::fe_dec_downward: + std::cout << "fe_dec_downward\n"; + break; + case rounding_mode::fe_dec_to_nearest: + std::cout << "fe_dec_to_nearest\n"; + break; + case rounding_mode::fe_dec_to_nearest_from_zero: + std::cout << "fe_dec_to_nearest_from_zero\n"; + break; + case rounding_mode::fe_dec_toward_zero: + std::cout << "fe_dec_toward_zero\n"; + break; + case rounding_mode::fe_dec_upward: + std::cout << "fe_dec_upward\n"; + break; + } +} int main() { - BOOST_DECIMAL_ATTRIBUTE_UNUSED auto default_rounding_mode = boost::decimal::fegetround(); // Default is fe_dec_to_nearest_from_zero + // The rounding mode can only be changed at run-time if the compiler supports + // 1. C++20 std::is_constant_evaluated() + // 2. Intrinsics that do the same + // If neither of the above are defined the library defines BOOST_DECIMAL_NO_CONSTEVAL_DETECTION - BOOST_DECIMAL_ATTRIBUTE_UNUSED auto new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_to_nearest); + // The current rounding mode can be queried with boost::decimal::fegetround + const boost::decimal::rounding_mode default_rounding_mode = boost::decimal::fegetround(); + std::cout << "The default rounding mode is: "; + print_rounding_mode(default_rounding_mode); - assert(default_rounding_mode != new_rounding_mode); + // To set a new rounding mode use boost::decimal::fesetround + // fesetround returns current mode after updating the global state + // + // If your compiler set defines BOOST_DECIMAL_NO_CONSTEVAL_DETECTION the global state can not be updated, + // so this can be a useful check to make sure that state is what you expect it to be + auto new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_upward); + std::cout << "The current rounding mode is: "; + print_rounding_mode(new_rounding_mode); - return 0; -} + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + using namespace boost::decimal::literals; + using boost::decimal::decimal32_t; + + const decimal32_t lhs {"5e+50"_DF}; + const decimal32_t rhs {"4e+40"_DF}; + std::cout << "lhs equals: " << lhs << '\n' + << "rhs equals: " << rhs << '\n'; + + // With upward rounding the result will be "5.000001e+50"_DF + // Even though the difference in order of magnitude is greater than the precision of the type, + // any addition in this mode will result in at least a one ULP difference + const decimal32_t upward_res {lhs + rhs}; + std::cout << " Sum with upward rounding: " << upward_res << '\n'; + + + new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_downward); + std::cout << "The current rounding mode is: "; + print_rounding_mode(new_rounding_mode); + + // Similar to above in the downward rounding mode any subtraction will result in at least a one ULP difference + const decimal32_t downward_res {lhs - rhs}; + std::cout << "Sum with downward rounding: " << downward_res << '\n'; + + #endif // BOOST_DECIMAL_NO_CONSTEVAL_DETECTION +} diff --git a/examples/rounding_mode_compile_time.cpp b/examples/rounding_mode_compile_time.cpp new file mode 100644 index 000000000..0ae0a5843 --- /dev/null +++ b/examples/rounding_mode_compile_time.cpp @@ -0,0 +1,63 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// To define a global compile-time rounding mode +// you must define the macro before inclusion of *ANY* decimal header +#define BOOST_DECIMAL_FE_DEC_DOWNWARD + +#include // For type decimal32_t +#include // For decimal literals +#include // For decimal support +#include // For rounding mode access +#include + +void print_rounding_mode(const boost::decimal::rounding_mode current_mode) +{ + // All 5 rounding modes are defined by the enum rounding_mode + using boost::decimal::rounding_mode; + + switch (current_mode) + { + case rounding_mode::fe_dec_downward: + std::cout << "fe_dec_downward\n"; + break; + case rounding_mode::fe_dec_to_nearest: + std::cout << "fe_dec_to_nearest\n"; + break; + case rounding_mode::fe_dec_to_nearest_from_zero: + std::cout << "fe_dec_to_nearest_from_zero\n"; + break; + case rounding_mode::fe_dec_toward_zero: + std::cout << "fe_dec_toward_zero\n"; + break; + case rounding_mode::fe_dec_upward: + std::cout << "fe_dec_upward\n"; + break; + } +} + +int main() +{ + using namespace boost::decimal::literals; + using boost::decimal::decimal32_t; + + // This uses one of the same examples from our runtime rounding mode example + // Now we can see the effects on the generation of constants, + // since we can static_assert the result + + constexpr decimal32_t lhs {"5e+50"_DF}; + constexpr decimal32_t rhs {"4e+40"_DF}; + constexpr decimal32_t downward_res {lhs - rhs}; + static_assert(downward_res == "4.999999e+50"_DF, "Incorrectly rounded result"); + + std::cout << "The default rounding mode is: "; + print_rounding_mode(boost::decimal::rounding_mode::fe_dec_default); + + // Here we can see that the rounding mode has been set to something besides default + // without having had to call fesetround + // + // This works with all compilers unlike changing the rounding mode at run-time + std::cout << "The current rounding mode is: "; + print_rounding_mode(boost::decimal::fegetround()); +} diff --git a/examples/statistics.cpp b/examples/statistics.cpp index 9f66af21e..92d9f7f62 100644 --- a/examples/statistics.cpp +++ b/examples/statistics.cpp @@ -1,9 +1,17 @@ // Copyright 2025 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// +// This example demonstrates how to perform statistics using boost.math + +// Needed for operations with boost math +#define BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS #include "where_file.hpp" -#include +#include // For type decimal64_t +#include // For from_chars +#include // Decimal support to and +#include // For sqrt of decimal types #include #include #include @@ -12,6 +20,7 @@ #include // Warning suppression for boost.math +// Boost.decimal is tested with -Werror -Wall -Wextra and a few other additional flags #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wfloat-equal" @@ -32,8 +41,10 @@ # pragma GCC diagnostic pop #endif -using namespace boost::decimal; +using boost::decimal::decimal64_t; +// This struct holds all the information that is provided +// for a single trading day struct daily_data { std::string date; @@ -44,7 +55,6 @@ struct daily_data decimal64_t volume; }; -// Function to split a CSV line into daily_data auto parse_csv_line(const std::string& line) -> daily_data { std::stringstream ss(line); @@ -73,10 +83,13 @@ auto parse_csv_line(const std::string& line) -> daily_data int main() { + // The first few lines of this file are similar to the previous example + // in that we parse a single year of AAPL stock data before we can do anything useful with + std::vector stock_data; // Open and read the CSV file - std::ifstream file(where_file("AAPL.csv")); + std::ifstream file(boost::decimal::where_file("AAPL.csv")); std::string line; // Skip header line @@ -95,23 +108,23 @@ int main() closing_prices.emplace_back(day.close); } - const auto mean_closing_price = boost::math::statistics::mean(closing_prices); - const auto median_closing_price = boost::math::statistics::median(closing_prices); - const auto variance_closing_price = boost::math::statistics::variance(closing_prices); - const auto std_dev_closing_price = sqrt(variance_closing_price); + // Here we use Boost.Math's statistics facilities + // As shown at the top of the file you will need to define BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS, + // and suppress a few warnings to make this build cleanly + const decimal64_t mean_closing_price = boost::math::statistics::mean(closing_prices); + const decimal64_t median_closing_price = boost::math::statistics::median(closing_prices); + const decimal64_t variance_closing_price = boost::math::statistics::variance(closing_prices); + const decimal64_t std_dev_closing_price = boost::decimal::sqrt(variance_closing_price); // 2-Sigma Bollinger Bands - const auto upper_band = mean_closing_price + 2 * std_dev_closing_price; - const auto lower_band = mean_closing_price - 2 * std_dev_closing_price; + // These are of a single point in time rather than making a plot over time for simplicity + const decimal64_t upper_band = mean_closing_price + 2 * std_dev_closing_price; + const decimal64_t lower_band = mean_closing_price - 2 * std_dev_closing_price; std::cout << std::fixed << std::setprecision(2) - << " Mean Closing Price: " << mean_closing_price << '\n' - << " Standard Deviation: " << std_dev_closing_price << '\n' - << "Upper Bollinger Band: " << upper_band << '\n' - << "Lower Bollinger Band: " << lower_band << std::endl; - - // Mean = 207.21 - // Median = 214.27 - return mean_closing_price > median_closing_price; + << " Mean Closing Price: $" << mean_closing_price << '\n' + << "Median Closing Price: $" << median_closing_price << '\n' + << " Standard Deviation: $" << std_dev_closing_price << '\n' + << "Upper Bollinger Band: $" << upper_band << '\n' + << "Lower Bollinger Band: $" << lower_band << std::endl; } - diff --git a/examples/to_from_file.cpp b/examples/to_from_file.cpp new file mode 100644 index 000000000..3ab1dc745 --- /dev/null +++ b/examples/to_from_file.cpp @@ -0,0 +1,103 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This example shows how to write and read decimal values to file efficiently + +#include // For type decimal32_t +#include // For to and from BID encoded bits functions +#include // For decimal type support to +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + using boost::decimal::decimal32_t; // The type decimal32_t + + // First we need to generate some values that we will use for further usage + // This constructs a decimal32_t from random significand and exponent within the domain of decimal32_t + std::mt19937_64 rng {42}; + std::uniform_int_distribution significand_dist {-9'999'999, 9'999'999}; + std::uniform_int_distribution exp_dist {-50, 50}; + + std::array values; + for (auto& v : values) + { + v = decimal32_t{significand_dist(rng), exp_dist(rng)}; + } + + // Now that we have our random decimal32_ts we will write them to file + // using their bitwise representations with the to_bid function + // + // This allows us to losslessly and rapidly recover them from file + // It is more efficient than writing the string to file with to_chars, + // and then recovering via the string constructor or from_chars + + std::ofstream file("example_values.txt"); + if (!file.is_open()) + { + std::cerr << "Failed to open file for writing" << std::endl; + return 1; + } + + for (const auto& value : values) + { + std::uint32_t bid_value {boost::decimal::to_bid(value)}; + + std::cout << " Current value: " << std::dec << value << '\n' + << "Value as bytes: " << std::hex << bid_value << "\n\n"; + + file.write(reinterpret_cast(&bid_value), sizeof(bid_value)); + } + file.close(); + + // Now that we have written all the values to file we will read them in, + // and then convert them back them to the decimal values using from_bid + std::ifstream read_file("example_values.txt", std::ios::binary); + if (!read_file.is_open()) + { + std::cerr << "Failed to open file for reading" << std::endl; + return 1; + } + + std::array recovered_values; + for (auto& value : recovered_values) + { + std::uint32_t bid_value; + read_file.read(reinterpret_cast(&bid_value), sizeof(bid_value)); + value = boost::decimal::from_bid(bid_value); + } + + read_file.close(); + if (std::remove("example_values.txt")) + { + std::cerr << "Failed to remove file" << std::endl; + } + + // Verify that we recovered the same values + bool success {true}; + for (std::size_t i {}; i < values.size(); ++i) + { + if (values[i] != recovered_values[i]) + { + success = false; + break; + } + } + + if (success) + { + std::cout << "Successfully recovered all values from file" << std::endl; + } + else + { + std::cout << "Warning: Some values did not match after recovery" << std::endl; + } + + return 0; +} diff --git a/examples/where_file.hpp b/examples/where_file.hpp index 60ab551a1..e3effa8fc 100644 --- a/examples/where_file.hpp +++ b/examples/where_file.hpp @@ -13,7 +13,7 @@ namespace boost { namespace decimal { -auto where_file(const std::string& test_vectors_filename) -> std::string +inline auto where_file(const std::string& test_vectors_filename) -> std::string { // Try to open the file in each of the known relative paths // in order to find out where it is located. diff --git a/extra/decimal_printer_gdb.py b/extra/decimal_printer_gdb.py new file mode 100644 index 000000000..751816945 --- /dev/null +++ b/extra/decimal_printer_gdb.py @@ -0,0 +1,202 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +import sys +import os +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +from detail.decode_ieee_type import decode_decimal32 +from detail.decode_ieee_type import decode_decimal64 +from detail.decode_ieee_type import decode_decimal128 +from detail.decode_fast_type import decode_decimal_fast32 +from detail.decode_fast_type import decode_decimal_fast64 +from detail.decode_fast_type import decode_decimal_fast128 + +import gdb +import gdb.printing + +class Decimal32Printer: + """Pretty printer for decimal32_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = int(self.val['bits_']) + return decode_decimal32(bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class Decimal64Printer: + """Pretty printer for decimal64_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = int(self.val['bits_']) + return decode_decimal64(bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class Decimal128Printer: + """Pretty printer for decimal128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bits = self.val['bits_'] + bits_high = int(bits['high']) + bits_low = int(bits['low']) + combined_bits = (bits_high << 64) | bits_low + return decode_decimal128(combined_bits) + except Exception as e: + return f"" + + def children(self): + yield ('bits_', self.val['bits_']) + + +class DecimalFast32Printer: + """Pretty printer for decimal_fast32_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = int(self.val['significand_']) + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + return decode_decimal_fast32(significand, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +class DecimalFast64Printer: + """Pretty printer for decimal_fast64_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = int(self.val['significand_']) + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + return decode_decimal_fast64(significand, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +class DecimalFast128Printer: + """Pretty printer for decimal_fast128_t type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + significand = self.val['significand_'] + bits_high = int(significand['high']) + bits_low = int(significand['low']) + combined_bits = (bits_high << 64) | bits_low + + exp = int(self.val['exponent_']) + sign = int(self.val['sign_']) + + return decode_decimal_fast128(combined_bits, exp, sign) + except Exception as e: + return f"" + + def children(self): + yield ('significand_', self.val['significand_']) + yield ('exponent_', self.val['exponent_']) + yield ('sign_', self.val['sign_']) + + +class U256Printer: + """Pretty printer for u256 internal type""" + + def __init__(self, val): + self.val = val + + def to_string(self): + try: + bytes = self.val['bytes'] + byte0 = int(bytes[3]) & 0xFFFFFFFFFFFFFFFF + byte1 = int(bytes[2]) & 0xFFFFFFFFFFFFFFFF + byte2 = int(bytes[1]) & 0xFFFFFFFFFFFFFFFF + byte3 = int(bytes[0]) & 0xFFFFFFFFFFFFFFFF + + value = (byte0 << 192) | (byte1 << 128) | (byte2 << 64) | byte3 + return f"{value:,}" + except Exception as e: + return f"" + + + +def build_pretty_printer(): + """Build and return the pretty printer collection""" + pp = gdb.printing.RegexpCollectionPrettyPrinter("boost_decimal") + + # IEEE types + pp.add_printer('decimal32_t', + r'^(const )?(boost::decimal::)?decimal32_t( &| \*)?$', + Decimal32Printer) + pp.add_printer('decimal64_t', + r'^(const )?(boost::decimal::)?decimal64_t( &| \*)?$', + Decimal64Printer) + pp.add_printer('decimal128_t', + r'^(const )?(boost::decimal::)?decimal128_t( &| \*)?$', + Decimal128Printer) + + # Fast types + pp.add_printer('decimal_fast32_t', + r'^(const )?(boost::decimal::)?decimal_fast32_t( &| \*)?$', + DecimalFast32Printer) + pp.add_printer('decimal_fast64_t', + r'^(const )?(boost::decimal::)?decimal_fast64_t( &| \*)?$', + DecimalFast64Printer) + pp.add_printer('decimal_fast128_t', + r'^(const )?(boost::decimal::)?decimal_fast128_t( &| \*)?$', + DecimalFast128Printer) + + # Debug internal types + pp.add_printer('u256', + r'^(const )?(boost::decimal::detail::)?u256( &| \*)?$', + U256Printer) + + return pp + + +def register_printers(objfile=None): + gdb.printing.register_pretty_printer(objfile, build_pretty_printer()) + + +# Auto-register when the module is loaded +register_printers() +print("Boost.Decimal pretty printers loaded successfully") diff --git a/extra/decimal_printer_lldb.py b/extra/decimal_printer_lldb.py new file mode 100644 index 000000000..0748a308c --- /dev/null +++ b/extra/decimal_printer_lldb.py @@ -0,0 +1,281 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +from detail.decode_ieee_type import decode_decimal32 +from detail.decode_ieee_type import decode_decimal64 +from detail.decode_ieee_type import decode_decimal128 +from detail.decode_fast_type import decode_decimal_fast32 +from detail.decode_fast_type import decode_decimal_fast64 +from detail.decode_fast_type import decode_decimal_fast128 + +import lldb + +def decimal32_summary(valobj, internal_dict): + """ + Custom summary for decimal32_t type + Displays in scientific notation with cohort preservation + """ + + try: + val = valobj.GetNonSyntheticValue() + bits = val.GetChildMemberWithName("bits_").GetValueAsUnsigned() + return decode_decimal32(bits) + + except Exception as e: + return f"" + +def decimal64_summary(valobj, internal_dict): + """ + Custom summary for decimal64_t type + Displays in scientific notation with cohort preservation + """ + + try: + val = valobj.GetNonSyntheticValue() + bits = val.GetChildMemberWithName("bits_").GetValueAsUnsigned() + return decode_decimal64(bits) + + except Exception as e: + return f"" + +def decimal128_summary(valobj, internal_dict): + """ + Custom summary for decimal128_t type + Displays in scientific notation with cohort preservation + """ + + try: + val = valobj.GetNonSyntheticValue() + bits = val.GetChildMemberWithName("bits_") + bits_high = bits.GetChildMemberWithName("high").GetValueAsUnsigned() + bits_low = bits.GetChildMemberWithName("low").GetValueAsUnsigned() + combined_bits = (bits_high << 64) | bits_low + return decode_decimal128(combined_bits) + + except Exception as e: + return f"" + +def decimal_fast32_summary(valobj, internal_dict): + """ + Custom summary for decimal_fast32_t type + Displays in scientific notation + """ + + try: + val = valobj.GetNonSyntheticValue() + significand = val.GetChildMemberWithName("significand_").GetValueAsUnsigned() + exp = val.GetChildMemberWithName("exponent_").GetValueAsUnsigned() + sign = val.GetChildMemberWithName("sign_").GetValueAsUnsigned() + return decode_decimal_fast32(significand, exp, sign) + + except Exception as e: + return f"" + +def decimal_fast64_summary(valobj, internal_dict): + """ + Custom summary for decimal_fast64_t type + Displays in scientific notation + """ + + try: + val = valobj.GetNonSyntheticValue() + significand = val.GetChildMemberWithName("significand_").GetValueAsUnsigned() + exp = val.GetChildMemberWithName("exponent_").GetValueAsUnsigned() + sign = val.GetChildMemberWithName("sign_").GetValueAsUnsigned() + return decode_decimal_fast64(significand, exp, sign) + + except Exception as e: + return f"" +def decimal_fast128_summary(valobj, internal_dict): + """ + Custom summary for decimal_fast128_t type + Displays in scientific notation + """ + + try: + val = valobj.GetNonSyntheticValue() + + significand = val.GetChildMemberWithName("significand_") + bits_high = significand.GetChildMemberWithName("high").GetValueAsUnsigned() + bits_low = significand.GetChildMemberWithName("low").GetValueAsUnsigned() + combined_bits = (bits_high << 64) | bits_low + + exp = val.GetChildMemberWithName("exponent_").GetValueAsUnsigned() + sign = val.GetChildMemberWithName("sign_").GetValueAsUnsigned() + + return decode_decimal_fast128(combined_bits, exp, sign) + + except Exception as e: + return f"" + +def u256_summary(valobj, internal_dict): + """ + Custom summary for u256 detail type + Displays in decimal notation + """ + + try: + val = valobj.GetNonSyntheticValue() + + bytes = val.GetChildMemberWithName("bytes") + b0 = bytes.GetChildAtIndex(0).GetValueAsUnsigned() + b1 = bytes.GetChildAtIndex(1).GetValueAsUnsigned() + b2 = bytes.GetChildAtIndex(2).GetValueAsUnsigned() + b3 = bytes.GetChildAtIndex(3).GetValueAsUnsigned() + + value = (b3 << 192) | (b2 << 128) | (b1 << 64) | b0 + return f"{value:,}" + except Exception as e: + return f"" + +def __lldb_init_module(debugger, internal_dict): + decimal32_pattern = r"^(const )?(boost::decimal::decimal32_t|(\w+::)*decimal32_t)( &| \*)?$" + decimal64_pattern = r"^(const )?(boost::decimal::decimal64_t|(\w+::)*decimal64_t)( &| \*)?$" + decimal128_pattern = r"^(const )?(boost::decimal::decimal128_t|(\w+::)*decimal128_t)( &| \*)?$" + + decimal_fast32_pattern = r"^(const )?(boost::decimal::decimal_fast32_t|(\w+::)*decimal_fast32_t)( &| \*)?$" + decimal_fast64_pattern = r"^(const )?(boost::decimal::decimal_fast64_t|(\w+::)*decimal_fast64_t)( &| \*)?$" + decimal_fast128_pattern = r"^(const )?(boost::decimal::decimal_fast128_t|(\w+::)*decimal_fast128_t)( &| \*)?$" + + u256_pattern = r"^(const )?(boost::decimal::detail::u256|(\w+::)*u256)( &| \*)?$" + + debugger.HandleCommand( + f'type summary add -x "{decimal32_pattern}" -e -F decimal_printer_lldb.decimal32_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal32_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' + ) + + print("decimal32_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{decimal64_pattern}" -e -F decimal_printer_lldb.decimal64_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal64_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' + ) + + print("decimal64_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{decimal128_pattern}" -e -F decimal_printer_lldb.decimal128_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal128_pattern}" -l decimal_printer_lldb.DecimalSyntheticProvider' + ) + + print("decimal128_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{decimal_fast32_pattern}" -e -F decimal_printer_lldb.decimal_fast32_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal_fast32_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' + ) + + print("decimal_fast32_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{decimal_fast64_pattern}" -e -F decimal_printer_lldb.decimal_fast64_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal_fast64_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' + ) + + print("decimal_fast64_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{decimal_fast128_pattern}" -e -F decimal_printer_lldb.decimal_fast128_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{decimal_fast128_pattern}" -l decimal_printer_lldb.DecimalFastSyntheticProvider' + ) + + print("decimal_fast128_t printer loaded successfully") + + debugger.HandleCommand( + f'type summary add -x "{u256_pattern}" -e -F decimal_printer_lldb.u256_summary' + ) + debugger.HandleCommand( + f'type synthetic add -x "{u256_pattern}" -l decimal_printer_lldb.u256SyntheticProvider' + ) + +class DecimalSyntheticProvider: + def __init__(self, valobj, internal_dict): + self.valobj = valobj + + def num_children(self): + return 1 + + def get_child_index(self, name): + if name == "bits_": + return 0 + return -1 + + def get_child_at_index(self, index): + if index == 0: + return self.valobj.GetChildMemberWithName("bits_") + return None + + def update(self): + pass + + def has_children(self): + return True + +class DecimalFastSyntheticProvider: + def __init__(self, valobj, internal_dict): + self.valobj = valobj + + def num_children(self): + return 3 + + def get_child_index(self, name): + if name == "significand_": + return 0 + elif name == "exponent_": + return 1 + elif name == "sign_": + return 2 + else: + return -1 + + def get_child_at_index(self, index): + if index == 0: + return self.valobj.GetChildMemberWithName("significand_") + elif index == 1: + return self.valobj.GetChildMemberWithName("exponent_") + elif index == 2: + return self.valobj.GetChildMemberWithName("sign_") + else: + return None + + def update(self): + pass + + def has_children(self): + return True + +class u256SyntheticProvider: + def __init__(self, valobj, internal_dict): + self.valobj = valobj + + def num_children(self): + return 1 + + def get_child_index(self, name): + if name == "bytes": + return 0 + return -1 + + def get_child_at_index(self, index): + if index == 0: + return self.valobj.GetChildMemberWithName("bytes") + return None + + def update(self): + pass + + def has_children(self): + return True diff --git a/extra/detail/decode_fast_type.py b/extra/detail/decode_fast_type.py new file mode 100644 index 000000000..c6205a4a5 --- /dev/null +++ b/extra/detail/decode_fast_type.py @@ -0,0 +1,95 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +import sys +import os +sys.path.insert(0, os.path.dirname(__file__)) + +from generate_string import generate_string + +def decode_decimal_fast32(significand, exp, sign): + + # See values of non-finite masks in decimal_fast32_t.hpp + if significand >= 536870912: + isnan = False + + if significand == 536870912: + result = "-INF" if sign else "INF" + elif significand >= 3758096384: + result = "-SNAN" if sign else "SNAN" + significand ^= 3758096384 + isnan = True + elif significand >= 1610612736: + result = "-QNAN" if sign else "QNAN" + significand ^= 1610612736 + isnan = True + else: + raise ValueError("Unknown Finite Value") + + if isnan and significand > 0: + result += '(' + str(significand) + ')' + + else: + exp -= 101 # Bias value + result = generate_string(significand, exp, sign) + + return result + +def decode_decimal_fast64(significand, exp, sign): + + # See values of non-finite masks in decimal_fast32_t.hpp + if significand >= 2305843009213693952: + isnan = False + + if significand == 2305843009213693952: + result = "-INF" if sign else "INF" + elif significand >= 16140901064495857664: + result = "-SNAN" if sign else "SNAN" + significand ^= 16140901064495857664 + isnan = True + elif significand >= 6917529027641081856: + result = "-QNAN" if sign else "QNAN" + significand ^= 6917529027641081856 + isnan = True + else: + raise ValueError("Unknown Finite Value") + + if isnan and significand > 0: + result += '(' + str(significand) + ')' + + else: + exp -= 398 # Bias value + result = generate_string(significand, exp, sign) + + return result + +def decode_decimal_fast128(significand, exp, sign): + + high_bits = significand >> 64 + + # See values of non-finite masks in decimal_fast32_t.hpp + if high_bits >= 2305843009213693952: + isnan = False + + if high_bits == 2305843009213693952: + result = "-INF" if sign else "INF" + elif high_bits >= 16140901064495857664: + result = "-SNAN" if sign else "SNAN" + significand ^= (16140901064495857664 << 64) + isnan = True + elif high_bits >= 6917529027641081856: + result = "-QNAN" if sign else "QNAN" + significand ^= (6917529027641081856 << 64) + isnan = True + else: + raise ValueError("Unknown Finite Value") + + if isnan and significand > 0: + result += '(' + str(significand) + ')' + + else: + exp -= 6176 # Bias value + result = generate_string(significand, exp, sign) + + return result diff --git a/extra/detail/decode_ieee_type.py b/extra/detail/decode_ieee_type.py new file mode 100644 index 000000000..e871dda7b --- /dev/null +++ b/extra/detail/decode_ieee_type.py @@ -0,0 +1,129 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +import sys +import os +sys.path.insert(0, os.path.dirname(__file__)) + +from generate_string import generate_string + +def decode_decimal32(bits): + sign = bits & 2147483648 != 0 + isnan = False + + if bits & 2013265920 == 2013265920: + + if bits & 2113929216 == 2113929216: + result = "-SNAN" if sign else "SNAN" + isnan = True + elif bits & 2080374784 == 2080374784: + result = "-QNAN" if sign else "QNAN" + isnan = True + elif bits & 2080374784 == 2013265920: + result = "-INF" if sign else "INF" + else: + raise ValueError("Unknown Finite Value") + + if isnan: + payload = bits & 8388607 + if payload > 0: + result += '(' + str(payload) + ')' + + else: + # See decimal32_t::to_components() + d32_comb_11_mask = 1610612736 + if bits & d32_comb_11_mask == d32_comb_11_mask: + implied_bit = 8388608 + significand = implied_bit | (bits & 2097151) + exp = (bits & 534773760) >> 21 + else: + significand = bits & 8388607 + exp = (bits & 2139095040) >> 23 + + exp -= 101 # Bias Value + + result = generate_string(significand, exp, sign) + + return result + +def decode_decimal64(bits): + sign = bits & 9223372036854775808 != 0 + isnan = False + + if bits & 8646911284551352320 == 8646911284551352320: + + if bits & 9079256848778919936 == 9079256848778919936: + result = "-SNAN" if sign else "SNAN" + isnan = True + elif bits & 8935141660703064064 == 8935141660703064064: + result = "-QNAN" if sign else "QNAN" + isnan = True + elif bits & 8935141660703064064 == 8646911284551352320: + result = "-INF" if sign else "INF" + else: + raise ValueError("Unknown Finite Value") + + if isnan: + payload = bits & 9007199254740991 + if payload > 0: + result += '(' + str(payload) + ')' + + else: + # See decimal64_t::to_components() + if bits & 6917529027641081856 == 6917529027641081856: + implied_bit = 9007199254740992 + significand = implied_bit | (bits & 2251799813685247) + exp = (bits & 2303591209400008704) >> 51 + else: + significand = bits & 9007199254740991 + exp = (bits & 9214364837600034816) >> 53 + + exp -= 398 # Bias Value + + result = generate_string(significand, exp, sign) + + return result + +def decode_decimal128(bits): + + bits_high = bits >> 64 + d128_not_11_significand_mask = (562949953421311 << 64) | 18446744073709551615 + d128_11_significand_mask = (140737488355327 << 64) | 18446744073709551615 + + sign = bits_high & 9223372036854775808 != 0 + isnan = False + + if bits_high & 8646911284551352320 == 8646911284551352320: + + if bits_high & 9079256848778919936 == 9079256848778919936: + result = "-SNAN" if sign else "SNAN" + isnan = True + elif bits_high & 8935141660703064064 == 8935141660703064064: + result = "-QNAN" if sign else "QNAN" + isnan = True + elif bits_high & 8935141660703064064 == 8646911284551352320: + result = "-INF" if sign else "INF" + else: + raise ValueError("Unknown Finite Value") + + if isnan: + payload = bits & d128_not_11_significand_mask + if payload > 0: + result += '(' + str(payload) + ')' + + else: + # See decimal128_t::to_components() + if bits_high & 6917529027641081856 == 6917529027641081856: + implied_bit = 562949953421312 << 64 + significand = implied_bit | (bits & d128_11_significand_mask) + exp = (bits_high & 2305702271725338624) >> 47 + else: + significand = bits & d128_not_11_significand_mask + exp = (bits_high & 9222809086901354496) >> 49 + + exp -= 6176 # Bias Value + + result = generate_string(significand, exp, sign) + + return result diff --git a/extra/detail/generate_string.py b/extra/detail/generate_string.py new file mode 100644 index 000000000..c530237a4 --- /dev/null +++ b/extra/detail/generate_string.py @@ -0,0 +1,21 @@ +# Copyright 2025 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +def generate_string(significand, exp, sign): + if significand == 0: + result = "0e+00" + else: + sig_str = str(significand) + n_digits = len(sig_str) + + if n_digits == 1: + normalized_str = sig_str + total_exp = exp + else: + normalized_str = sig_str[0] + '.' + sig_str[1:] + total_exp = exp + n_digits - 1 + + result = f"{'-' if sign else ''}{normalized_str}e{total_exp:+03d}" + + return result diff --git a/fuzzing/fuzz_string_constructors.cpp b/fuzzing/fuzz_string_constructors.cpp new file mode 100644 index 000000000..5cfd94177 --- /dev/null +++ b/fuzzing/fuzz_string_constructors.cpp @@ -0,0 +1,37 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size) +{ + try + { + auto c_data = reinterpret_cast(data); + const std::string c_data_str {c_data, size}; // Guarantee null termination since we can't pass the size argument + + const boost::decimal::decimal32_t d32_val {c_data_str}; + const boost::decimal::decimal64_t d64_val {c_data_str}; + const boost::decimal::decimal128_t d128_val {c_data_str}; + + const boost::decimal::decimal_fast32_t df32_val {c_data_str}; + const boost::decimal::decimal_fast64_t df64_val {c_data_str}; + const boost::decimal::decimal_fast128_t df128_val {c_data_str}; + + static_cast(d32_val); + static_cast(d64_val); + static_cast(d128_val); + + static_cast(df32_val); + static_cast(df64_val); + } + catch(...) + { + } + + return 0; +} diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/011df998ef737e7eec0a59dcb7840d57182b8038 b/fuzzing/seedcorpus/fuzz_from_chars_float/011df998ef737e7eec0a59dcb7840d57182b8038 new file mode 100644 index 000000000..b26cd1a63 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/011df998ef737e7eec0a59dcb7840d57182b8038 @@ -0,0 +1 @@ +844 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/020a7af44170c4ed0e4e3d1f578d6f0fe7623d2e b/fuzzing/seedcorpus/fuzz_from_chars_float/020a7af44170c4ed0e4e3d1f578d6f0fe7623d2e new file mode 100644 index 000000000..b031df15a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/020a7af44170c4ed0e4e3d1f578d6f0fe7623d2e @@ -0,0 +1 @@ +.72AAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/02216b9eee161f937f717fab448d845d308149e3 b/fuzzing/seedcorpus/fuzz_from_chars_float/02216b9eee161f937f717fab448d845d308149e3 new file mode 100644 index 000000000..083343479 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/02216b9eee161f937f717fab448d845d308149e3 @@ -0,0 +1 @@ +-80927333333333333333333333333333333AAA.AAAAA833333333333333333333332333333333333333333333333333A3330000003339607008678161066A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/02740d73c1a50ae618f99a050d2f484a953c64b0 b/fuzzing/seedcorpus/fuzz_from_chars_float/02740d73c1a50ae618f99a050d2f484a953c64b0 new file mode 100644 index 000000000..0bd5e3e3a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/02740d73c1a50ae618f99a050d2f484a953c64b0 @@ -0,0 +1 @@ +61859bfffffffffffffffffffffffffffffffffffffffffffffffffffffff \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/028fb75e0c7120f36b6cb69e04328011e0a96d19 b/fuzzing/seedcorpus/fuzz_from_chars_float/028fb75e0c7120f36b6cb69e04328011e0a96d19 new file mode 100644 index 000000000..679b0b114 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/028fb75e0c7120f36b6cb69e04328011e0a96d19 @@ -0,0 +1 @@ +-0.52AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0476a2dcf0699c325b7708af28a1d128a3ff5faa b/fuzzing/seedcorpus/fuzz_from_chars_float/0476a2dcf0699c325b7708af28a1d128a3ff5faa new file mode 100644 index 000000000..4e69cc306 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0476a2dcf0699c325b7708af28a1d128a3ff5faa @@ -0,0 +1 @@ +4e0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/04bb12fdc214a84f1b01d4f9ff60b54e8b8936f9 b/fuzzing/seedcorpus/fuzz_from_chars_float/04bb12fdc214a84f1b01d4f9ff60b54e8b8936f9 new file mode 100644 index 000000000..ba06f402d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/04bb12fdc214a84f1b01d4f9ff60b54e8b8936f9 @@ -0,0 +1 @@ +AAA2AAA7 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0642cbef16c3f13702c7692a870cd783b6212273 b/fuzzing/seedcorpus/fuzz_from_chars_float/0642cbef16c3f13702c7692a870cd783b6212273 new file mode 100644 index 000000000..09f1bdbb9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0642cbef16c3f13702c7692a870cd783b6212273 @@ -0,0 +1 @@ +-8092733333333333333333333333333331355e3333> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/06770b045708289c220e187f4f87120cad7d1fb3 b/fuzzing/seedcorpus/fuzz_from_chars_float/06770b045708289c220e187f4f87120cad7d1fb3 new file mode 100644 index 000000000..8aae829ec --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/06770b045708289c220e187f4f87120cad7d1fb3 @@ -0,0 +1,39 @@ +-0.7 +9e-265 +85e-37 +623e+10251086569.8071456 +-5332617826=3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-9653912497.382019 +94997225114.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.8071456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-9653912497.382019 +94997225114.9545956 +5288460984.511721 +46072506 +-4.4599414413418414e+20 +-7.939542985204633e+20 +-7.3428836122343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/07347c8c8d9c697d517fc0f51ba74e8cb2a26b68 b/fuzzing/seedcorpus/fuzz_from_chars_float/07347c8c8d9c697d517fc0f51ba74e8cb2a26b68 new file mode 100644 index 000000000..ae68cce97 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/07347c8c8d9c697d517fc0f51ba74e8cb2a26b68 @@ -0,0 +1 @@ +-4e829273333333332333333333300972713AAAAAA.AAAAAAAAAA333333333333333333333333333333333333333333333333333333333333333333333333333333AAAAAA.AAAAAAAAAA3333333333333333333333333333333333333333333333333333333333333333. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0958c05358d9844784adff2700e86bb3da6a7f85 b/fuzzing/seedcorpus/fuzz_from_chars_float/0958c05358d9844784adff2700e86bb3da6a7f85 new file mode 100644 index 000000000..4ecf65297 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0958c05358d9844784adff2700e86bb3da6a7f85 @@ -0,0 +1 @@ +8E380P665 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/09a9fb78c1b14fa5d7a369b78a0b6c3abb3a6a8a b/fuzzing/seedcorpus/fuzz_from_chars_float/09a9fb78c1b14fa5d7a369b78a0b6c3abb3a6a8a new file mode 100644 index 000000000..623973f8b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/09a9fb78c1b14fa5d7a369b78a0b6c3abb3a6a8a @@ -0,0 +1 @@ +.1 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/09d26cc58533b8374909e4cdec4c1dbad2945f6e b/fuzzing/seedcorpus/fuzz_from_chars_float/09d26cc58533b8374909e4cdec4c1dbad2945f6e new file mode 100644 index 000000000..42c7a8249 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/09d26cc58533b8374909e4cdec4c1dbad2945f6e @@ -0,0 +1 @@ +5P15 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0a58a73628ba317d9c878eec823da6a1014a8772 b/fuzzing/seedcorpus/fuzz_from_chars_float/0a58a73628ba317d9c878eec823da6a1014a8772 new file mode 100644 index 000000000..21ebcafde --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0a58a73628ba317d9c878eec823da6a1014a8772 @@ -0,0 +1 @@ +.541 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0bc7749a1ea7eecfcf3b3f493c1cf2e08e53946d b/fuzzing/seedcorpus/fuzz_from_chars_float/0bc7749a1ea7eecfcf3b3f493c1cf2e08e53946d new file mode 100644 index 000000000..32930df6e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0bc7749a1ea7eecfcf3b3f493c1cf2e08e53946d @@ -0,0 +1 @@ +Na \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0c94d7e5928e42aaab87f1c45fc030ce2c128885 b/fuzzing/seedcorpus/fuzz_from_chars_float/0c94d7e5928e42aaab87f1c45fc030ce2c128885 new file mode 100644 index 000000000..01bc372ed --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0c94d7e5928e42aaab87f1c45fc030ce2c128885 @@ -0,0 +1 @@ +-80927333333333333333333333333323333333333333333333333333333333333333373333333333333333333333333333/33 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0c9c4d2c611061bda0b981621f76e98e44a70f05 b/fuzzing/seedcorpus/fuzz_from_chars_float/0c9c4d2c611061bda0b981621f76e98e44a70f05 new file mode 100644 index 000000000..42a1ae2d6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0c9c4d2c611061bda0b981621f76e98e44a70f05 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0cc7b86de526f5b96116d9fde191abccebb398f7 b/fuzzing/seedcorpus/fuzz_from_chars_float/0cc7b86de526f5b96116d9fde191abccebb398f7 new file mode 100644 index 000000000..e221e8e89 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0cc7b86de526f5b96116d9fde191abccebb398f7 @@ -0,0 +1 @@ +13e8264 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0d0de19af0deebc700b2a9216444492719b70b40 b/fuzzing/seedcorpus/fuzz_from_chars_float/0d0de19af0deebc700b2a9216444492719b70b40 new file mode 100644 index 000000000..19db0bb72 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0d0de19af0deebc700b2a9216444492719b70b40 @@ -0,0 +1 @@ +.E5P2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0d72e671b0dc4c79954050de7c63ef4061663e3e b/fuzzing/seedcorpus/fuzz_from_chars_float/0d72e671b0dc4c79954050de7c63ef4061663e3e new file mode 100644 index 000000000..ec18e77df --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0d72e671b0dc4c79954050de7c63ef4061663e3e @@ -0,0 +1 @@ +-0.52AAAAAAAAAAAAAAAAAAAAAAAAAAAA5A0278 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0e00da0716e03b58ce1356f6572161a339cab37a b/fuzzing/seedcorpus/fuzz_from_chars_float/0e00da0716e03b58ce1356f6572161a339cab37a new file mode 100644 index 000000000..b7f0b5455 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0e00da0716e03b58ce1356f6572161a339cab37a @@ -0,0 +1 @@ +-80927333333333333333333333333331355e33333 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0e1c050401ca225b524cb160956f6fb341146548 b/fuzzing/seedcorpus/fuzz_from_chars_float/0e1c050401ca225b524cb160956f6fb341146548 new file mode 100644 index 000000000..96e2fcd9c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0e1c050401ca225b524cb160956f6fb341146548 @@ -0,0 +1 @@ +92119 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0e903e3c8f40bcd02c408880cb70cb050d274449 b/fuzzing/seedcorpus/fuzz_from_chars_float/0e903e3c8f40bcd02c408880cb70cb050d274449 new file mode 100644 index 000000000..5219bdac7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0e903e3c8f40bcd02c408880cb70cb050d274449 @@ -0,0 +1 @@ +4e83 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0ebf6d720ff54ec22ced5202ca6f30eb53814071 b/fuzzing/seedcorpus/fuzz_from_chars_float/0ebf6d720ff54ec22ced5202ca6f30eb53814071 new file mode 100644 index 000000000..a649b88e5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0ebf6d720ff54ec22ced5202ca6f30eb53814071 @@ -0,0 +1 @@ +2135520e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0ec9faa75ff05fa3280c06e3e0d64582aa27ee24 b/fuzzing/seedcorpus/fuzz_from_chars_float/0ec9faa75ff05fa3280c06e3e0d64582aa27ee24 new file mode 100644 index 000000000..367d04644 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0ec9faa75ff05fa3280c06e3e0d64582aa27ee24 @@ -0,0 +1 @@ +8093A2365923595 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0f3b1661a007a3892e98de51dfd4cf5ff38f566c b/fuzzing/seedcorpus/fuzz_from_chars_float/0f3b1661a007a3892e98de51dfd4cf5ff38f566c new file mode 100644 index 000000000..4b755999d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0f3b1661a007a3892e98de51dfd4cf5ff38f566c @@ -0,0 +1 @@ +-8279203659236579952 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0f64ab2d4c290d7fd51f755ce63bc2b466ae090d b/fuzzing/seedcorpus/fuzz_from_chars_float/0f64ab2d4c290d7fd51f755ce63bc2b466ae090d new file mode 100644 index 000000000..d99bcfceb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0f64ab2d4c290d7fd51f755ce63bc2b466ae090d @@ -0,0 +1 @@ +-825970035996.9272365923365927225970035965923365237925639569272365923659E236.0965223729365992365923659E23.36.99236. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/0fcfeed7f58b0f5b53464da397e162e3fb76db56 b/fuzzing/seedcorpus/fuzz_from_chars_float/0fcfeed7f58b0f5b53464da397e162e3fb76db56 new file mode 100644 index 000000000..c4e0c33dc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/0fcfeed7f58b0f5b53464da397e162e3fb76db56 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAA3333333333333333331354e33.3 33 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/115677925842c861cfd52b76fee0c76288d7defe b/fuzzing/seedcorpus/fuzz_from_chars_float/115677925842c861cfd52b76fee0c76288d7defe new file mode 100644 index 000000000..150d20d24 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/115677925842c861cfd52b76fee0c76288d7defe @@ -0,0 +1 @@ +.21p551e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1182300ee632ff286b3ba0a53e749e27a08eecde b/fuzzing/seedcorpus/fuzz_from_chars_float/1182300ee632ff286b3ba0a53e749e27a08eecde new file mode 100644 index 000000000..4ae6a850f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1182300ee632ff286b3ba0a53e749e27a08eecde @@ -0,0 +1 @@ +AP266620A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/11e4d0f8596d19d88d04b7dba9139635b021307e b/fuzzing/seedcorpus/fuzz_from_chars_float/11e4d0f8596d19d88d04b7dba9139635b021307e new file mode 100644 index 000000000..a1cb54a75 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/11e4d0f8596d19d88d04b7dba9139635b021307e @@ -0,0 +1 @@ +-809273333333333333333333333333333333333333333333333333333 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/11f6ad8ec52a2984abaafd7c3b516503785c2072 b/fuzzing/seedcorpus/fuzz_from_chars_float/11f6ad8ec52a2984abaafd7c3b516503785c2072 new file mode 100644 index 000000000..c1b0730e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/11f6ad8ec52a2984abaafd7c3b516503785c2072 @@ -0,0 +1 @@ +x \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/120696fa395d99bfbc8bec4647af71143abc14d2 b/fuzzing/seedcorpus/fuzz_from_chars_float/120696fa395d99bfbc8bec4647af71143abc14d2 new file mode 100644 index 000000000..d0349ed8a Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/120696fa395d99bfbc8bec4647af71143abc14d2 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/13fa5a2c3f18f8ed9f2c2fd7cef9d830eb284e08 b/fuzzing/seedcorpus/fuzz_from_chars_float/13fa5a2c3f18f8ed9f2c2fd7cef9d830eb284e08 new file mode 100644 index 000000000..4a7aa17bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/13fa5a2c3f18f8ed9f2c2fd7cef9d830eb284e08 @@ -0,0 +1 @@ +856562062308e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/14108120f8192a5cf880818d88386a7c880fb29f b/fuzzing/seedcorpus/fuzz_from_chars_float/14108120f8192a5cf880818d88386a7c880fb29f new file mode 100644 index 000000000..f1dc65fd0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/14108120f8192a5cf880818d88386a7c880fb29f @@ -0,0 +1 @@ +42e8381P6657 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/14536f215725134440e132984d26c2afdaef092f b/fuzzing/seedcorpus/fuzz_from_chars_float/14536f215725134440e132984d26c2afdaef092f new file mode 100644 index 000000000..5ff11dc15 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/14536f215725134440e132984d26c2afdaef092f @@ -0,0 +1 @@ +8080927230631A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/14d10c9592e616de765e4c6c585ff6cfccfb5905 b/fuzzing/seedcorpus/fuzz_from_chars_float/14d10c9592e616de765e4c6c585ff6cfccfb5905 new file mode 100644 index 000000000..cca2dd0f6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/14d10c9592e616de765e4c6c585ff6cfccfb5905 @@ -0,0 +1 @@ +inF \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/14e3281751e317e567fdbed0382019b2ec22c43b b/fuzzing/seedcorpus/fuzz_from_chars_float/14e3281751e317e567fdbed0382019b2ec22c43b new file mode 100644 index 000000000..7b562ede7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/14e3281751e317e567fdbed0382019b2ec22c43b @@ -0,0 +1 @@ +-228759236506592923.6. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1597a6bce605269814792e9f998af57d7d2b246a b/fuzzing/seedcorpus/fuzz_from_chars_float/1597a6bce605269814792e9f998af57d7d2b246a new file mode 100644 index 000000000..f6cba840c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1597a6bce605269814792e9f998af57d7d2b246a @@ -0,0 +1 @@ +.E6P2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/15fc74062699b3fabf3fe28214f5cea0b7175d13 b/fuzzing/seedcorpus/fuzz_from_chars_float/15fc74062699b3fabf3fe28214f5cea0b7175d13 new file mode 100644 index 000000000..4e6d920e3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/15fc74062699b3fabf3fe28214f5cea0b7175d13 @@ -0,0 +1,171 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-635732+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-96875494525.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835517.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8+363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/16f97e0dd4d1e6595dfa24e299f1260577c3f205 b/fuzzing/seedcorpus/fuzz_from_chars_float/16f97e0dd4d1e6595dfa24e299f1260577c3f205 new file mode 100644 index 000000000..788b32314 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/16f97e0dd4d1e6595dfa24e299f1260577c3f205 @@ -0,0 +1 @@ +8P26661& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/172e078ba82f70a0408e0afeef6d77bb12a59913 b/fuzzing/seedcorpus/fuzz_from_chars_float/172e078ba82f70a0408e0afeef6d77bb12a59913 new file mode 100644 index 000000000..12cf0f072 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/172e078ba82f70a0408e0afeef6d77bb12a59913 @@ -0,0 +1,43 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.8071456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-9653912497.382019 +94997225114.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20 +-4.4599414413418414e+20 +-7.939542985204633e+20 +-7.3428836122343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1808513dc16ac83dfbb79bc3a4fc8520f0bba58f b/fuzzing/seedcorpus/fuzz_from_chars_float/1808513dc16ac83dfbb79bc3a4fc8520f0bba58f new file mode 100644 index 000000000..878068661 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1808513dc16ac83dfbb79bc3a4fc8520f0bba58f @@ -0,0 +1 @@ +-.33400000044000000B0.4406P085 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1858fb0ce22a128c958fa744b3bf0dcf522231b7 b/fuzzing/seedcorpus/fuzz_from_chars_float/1858fb0ce22a128c958fa744b3bf0dcf522231b7 new file mode 100644 index 000000000..af37f707e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1858fb0ce22a128c958fa744b3bf0dcf522231b7 @@ -0,0 +1,2 @@ +-80927333333333333333333333333333333333333333333333333333333333333333333333333333685 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/186eebde227b17dea0937b5af8b8cd90aba1c497 b/fuzzing/seedcorpus/fuzz_from_chars_float/186eebde227b17dea0937b5af8b8cd90aba1c497 new file mode 100644 index 000000000..370a9ce18 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/186eebde227b17dea0937b5af8b8cd90aba1c497 @@ -0,0 +1 @@ +iA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/19b1928d58a2030d08023f3d7054516dbc186f20 b/fuzzing/seedcorpus/fuzz_from_chars_float/19b1928d58a2030d08023f3d7054516dbc186f20 new file mode 100644 index 000000000..c60214470 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/19b1928d58a2030d08023f3d7054516dbc186f20 @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1a89cb145687cd0419aa03179b2171d9b0a29592 b/fuzzing/seedcorpus/fuzz_from_chars_float/1a89cb145687cd0419aa03179b2171d9b0a29592 new file mode 100644 index 000000000..39ff7f3fe --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1a89cb145687cd0419aa03179b2171d9b0a29592 @@ -0,0 +1 @@ +-22222222222222222180e8381P6656 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1aea15dc8fe20e23a4b4f81966d89126855fe36f b/fuzzing/seedcorpus/fuzz_from_chars_float/1aea15dc8fe20e23a4b4f81966d89126855fe36f new file mode 100644 index 000000000..27ba809fd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1aea15dc8fe20e23a4b4f81966d89126855fe36f @@ -0,0 +1 @@ +3.001291940006561404244f32 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1b245f691f7adc64955d565ba62971838b175955 b/fuzzing/seedcorpus/fuzz_from_chars_float/1b245f691f7adc64955d565ba62971838b175955 new file mode 100644 index 000000000..215e87ab5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1b245f691f7adc64955d565ba62971838b175955 @@ -0,0 +1 @@ +.A8? \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1b2acd37ddcd0375efb785172d95ba75b845a1e3 b/fuzzing/seedcorpus/fuzz_from_chars_float/1b2acd37ddcd0375efb785172d95ba75b845a1e3 new file mode 100644 index 000000000..e4ee6b7f0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1b2acd37ddcd0375efb785172d95ba75b845a1e3 @@ -0,0 +1,977 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452 +-6989049626.595518 +-4656828161.473779 +9763680224.51627 +9751951081.686802 +-337738879.7371044 +-3218308721.9295416 +5316866140.38973 +253140072.20806503 +-67015884.19111252 +-4145941047.9776325 +9982650191.863255 +-4805195750.912774 +2007631436.0563717 +-1336980163.13908 +3876768555.2980576 +6369274349.731985 +714573945.7687016 +8217335015.851101 +-7220020049.135553 +-1375882154.3342018 +-7965288568.390052 +-4972087297.866529 +-9617862443.628145 +4847618299.542833 +-8064903300.436237 +4916757135.607399 +515751419.4691963 +9215353924.090961 +-364913989.2347889 +-3507329283.0497313 +1317810244.4926357 +-7295868652.742394 +6876470676.15094 +-2438584710.5560446 +7832150646.9747505 +8400914366.011929 +1239217006.5196457 +6751063909.677446 +-8090155725.787666 +-791010118.7786922 +-5761208048.211159 +-2168171518.217272 +157362439.9876709 +-9381050662.044998 +8463512975.957085 +-8942516901.275276 +3082320494.2169495 +1724377540.4461613 +7891183680.86731 +2768052907.1448727 +9622664872.800652 +1364929177.6346016 +2438745344.650511 +-8880072185.722937 +-6613261965.832544 +8413085097.502716 +4088601626.3673477 +6574025563.215904 +-4496754459.192869 +-2814059126.8972635 +4825485746.352711 +464568475.3084049 +-4498633535.888028 +-7225560661.85226 +-3221258349.00179 +5420486017.349937 +4323332602.043682 +-3964379910.549527 +-8222017305.183034 +-4650765900.672444 +-2191806433.5125217 +-2721890544.328933 +5717273607.065279 +-28422478.223329544 +4212720813.701809 +5311208464.502592 +3225483549.0651913 +-9788638244.599714 +-3077024169.4503174 +7411855396.694576 +-9054016057.921425 +6534847129.909836 +-8143145194.103385 +9188388528.00267 +5250026150.321932 +-8975805075.502327 +969935862.4870129 +-8707655672.63136 +5467137200.623861 +-5780239257.465727 +-3409155374.6815004 +-4095011398.0845385 +7253745994.176674 +-7161651473.528198 +-7849491793.200878 +4828368247.266005 +8914484950.901321 +-9115356835.02289 +-8225833870.461037 +-2539903677.6078243 +4294051454.55299 +-1853640047.8603191 +-1112420684.1528187 +4810742993.5433235 +4053102452.6137695 +3592594405.398941 +-7926418595.777629 +2145393045.0870895 +-5739192900.8195915 +-4408654069.571105 +-4371124148.663783 +7743510829.925953 +-1261382088.5091038 +2581814671.28006 +-7039298048.791871 +-8076767027.845224 +4329518147.451557 +1161621381.1248627 +1208250030.101286 +-6534218378.205525 +5114456196.548088 +4088022020.578598 +8992977247.728653 +-5097582856.498999 +9886148343.725456 +9912642453.119267 +3719453860.4919453 +7078570223.815897 +624118266.2463989 +863886173.3964558 +-1932314022.626196 +-4949766274.704357 +1728676263.0908527 +3655675109.9528294 +677889306.7410755 +-4604582434.624218 +6852562064.798929 +-5073083424.205593 +-1310860351.7890434 +9076521028.02076 +-6795320982.856365 +-815720359.5432167 +3469105793.853657 +369526499.6803398 +-8116569459.547374 +-2185814709.778287 +-3041629136.8767996 +-5346460950.374048 +2620956357.0461655 +-7377613242.535397 +1533795868.133503 +-4375472275.006776 +4044440867.6627426 +9503935866.642864 +-173165501.02918053 +3204021627.0289707 +-9106488941.48659 +4640411716.87112 +-3855456670.21 +1806278957.86557 +-7719725766.293733 +4870997554.669283 +-2645372770.749628 +1412833844.6981277 +3235738635.1283627 +-5467691529.236322 +8423135631.25145 +4366804024.218529 +7475317508.951164 +-6729951259.834599 +-3042731230.1005173 +-8052832339.079965 +-9910878365.52365 +-1406785809.4684315 +1325159253.5445614 +5899318569.084028 +-7335586270.0054455 +2722923617.737646 +1965337620.4644394 +6687202389.800978 +4625471957.369957 +-1627665340.1117573 +-8705574779.906586 +-4020333220.7047033 +-168217295.5267563 +1353090961.899828 +-5673224931.216288 +-8840443040.525124 +-7842962545.884165 +-1635234877.4911537 +-5086175166.746623 +-5190316401.77241 +6885977762.7181015 +66706795327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452 +-6989049626.595518 +-4656828161.473779 +9763680224.51627 +9751951081.686802 +-337738879.7371044 +-3218308721.9295416 +5316866140.38973 +253140072.20806503 +-67015884.19111252 +-4145941047.9776325 +9982650191.863255 +-4805195750.912774 +2007631436.0563717 +-1336980163.13908 +3876768555.2980576 +6369274349.731985 +714573945.7687016 +8217335015.851101 +-7220020049.135553 +-1375882154.3342018 +-7965288568.390052 +-4972087297.866529 +-9617862443.628145 +4847618299.542833 +-8064903300.436237 +4916757135.607399 +515751419.4691963 +9215353924.090961 +-364913989.2347889 +-3507329283.0497313 +1317810244.4926357 +-7295868652.742394 +6876470676.15094 +-2438584710.5560446 +7832150646.9747505 +8400914366.011929 +1239217006.5196457 +6751063909.677446 +-8090155725.787666 +-791010118.7786922 +-5761208048.211159 +-2168171518.217272 +157362439.9876709 +-9381050662.044998 +8463512975.957085 +-8942516901.275276 +3082320494.2169495 +1724377540.4461613 +7891183680.86731 +2768052907.1448727 +9622664872.800652 +1364929177.6346016 +2438745344.650511 +-8880072185.722937 +-6613261965.832544 +8413085097.502716 +4088601626.3673477 +6574025563.215904 +-4496754459.192869 +-2814059126.8972635 +4825485746.352711 +464568475.3084049 +-4498633535.888028 +-7225560661.85226 +-3221258349.00179 +5420486017.349937 +4323332602.043682 +-3964379910.549527 +-8222017305.183034 +-4650765900.672444 +-2191806433.5125217 +-2721890544.328933 +5717273607.065279 +-28422478.223329544 +4212720813.701809 +5311208464.502592 +3225483549.0651913 +-9788638244.599714 +-3077024169.4503174 +7411855396.694576 +-9054016057.921425 +6534847129.909836 +-8143145194.103385 +9188388528.00267 +5250026150.321932 +-8975805075.502327 +969935862.4870129 +-8707655672.63136 +5467137200.623861 +-5780239257.465727 +-3409155374.6815004 +-4095011398.0845385 +7253745994.176674 +-7161651473.528198 +-7849491793.200878 +4828368247.266005 +8914484950.901321 +-9115356835.02289 +-8225833870.461037 +-2539903677.6078243 +4294051454.55299 +-1853640047.8603191 +-1112420684.1528187 +4810742993.5433235 +4053102452.6137695 +3592594405.398941 +-7926418595.777629 +2145393045.0870895 +-5739192900.8195915 +-4408654069.571105 +-4371124148.663783 +7743512089.925953 +-1261382088.5091038 +2581814671.28006 +-7039298048.791871 +-8076767027.845224 +4329518147.451557 +1161621381.1248627 +1208250030.101286 +-6534218378.205525 +5114456196.548088 +4088022020.578598 +8992977247.728653 +-5097582856.498999 +9886148343.725456 +9912642453.119267 +3719453860.4919453 +7078570223.815897 +624118266.2463989 +863886173.3964558 +-1932314022.626196 +-4949766274.704357 +1728676263.0908527 +3655675109.9528294 +677889306.7410755 +-4604582434.624218 +6852562064.798929 +-5073083424.205593 +-1310860351.7890434 +9076521028.02076 +-6795320982.856365 +-815720359.5432167 +3469105793.853657 +369526499.6803398 +-8116569459.547374 +-2185814709.778287 +-3041629136.8767996 +-5346460950.374048 +2620956357.0461655 +-7377613242.535397 +1533795868.133503 +-4375472275.006776 +4044440867.6627426 +9503935866.642864 +-173165501.02918053 +3204021627.0289707 +-9106488941.48659 +4640411716.87112 +-3855456670.21 +1806278957.86557 +-7719725766.293733 +4870997554.669283 +-2645372770.749628 +1412833844.6981277 +3235738635.1283627 +-5467691529.236322 +8423135631.25145 +4366804024.218529 +7475317508.951164 +-6729951259.834599 +-3042731230.1005173 +-8052832339.079965 +-9910878365.52365 +-1406785809.4684315 +1325159253.5445614 +5899318569.084028 +-7335586270.0054455 +2722923617.737646 +1965337620.4644394 +6687202389.800978 +4625471957.369957 +-1627665340.1117573 +-8705574779.906586 +-4020333220.7047033 +-168217295.5267563 +1353090961.899828 +-5673224931.216288 +-8840443040.525124 +-7842962545.884165 +-1635234877.4911537 +-5086175166.746623 +-5190316401.77241 +6885977762.7181015 +6670679088.13579 +9377637707.2052 +4740081906.320965 +-9855927038.85421 +-393083365.2558689 +1930287943.1776905 +-2593616140.4156933 +6973281423.628536 +-1785710158.250329 +-143515758.43083954 +-9165566885.262552 +-3271947075.442127 +1866146881.2823467 +9922318687.247532 +2105889374.9543476 +1412191145.1990738 +4899253184.97513 +-4963639159.271849 +8618179390.053493 +-4270177979.582361 +6055692117.72047 +323727457.89961624 +-1997101808.7895699 +5636742008.106144 +4691147693.264648 +-1339528188.4935036 +-5129832360.937038 +-7851471851.588366 +5036450555.008472 +-2531325190.1094837 +-4269349462.4435883 +-9714134709.103092 +-1759752342.380949 +-2786309738.9712315 +8482952443.393608 +-1767831217.3464785 +-9591336055.176716 +6235445085.696083 +-4558818055.646798 +-4746793816.840109 +-4656884038.338767 +8283627521.822033 +7271616925.880337 +-4975594184.59415 +5719936545.010145 +3926786838.1136494 +-1573054519.4802885 +-5528363043.595613 +-8159000612.363343 +-3072957148.7078047 +3079220817.911688 +-8458471846.61787 +-9222562952.799414 +-1587906788.0184402 +2845544102.5235634 +7892509404.137733 +-8394088799.434449 +-8871970975.653664 +6878128182.769302 +-2977407410.038788 +-6725749678.392197 +9254656545.983723 +6289186404.1730995 +5128165261.277636 +-5241260072.736095 +6917249801.302614 +-756<111942.267646 +-6857866820.515381 +8962461589.683685 +-5729987652.684038 +1471350203.0483437 +-9729367141.66414 +2395854137.699234 +7749640698.397217 +-2110788646.8097095 +-2186817857.724968 +-9.12434048525892e+20 +-2.487370407039252e+20 +7.059778770319386e+20 +-1.1474292187493714e+20 +7.543787358849793e+20 +4.613801268236794e+20 +-9.335581580814339e+20 +-4.957887898426344e+298 +-9.055478281801209e+20 +-5.970115306346393e+20 +9.305909352849319e+20 +2.803715496169754e+20 +-7.615729522564583e+20 +4.805477501654648e+20 +5.795519629478846e+20 +-9.21243319444016e+20 +-4.609469937594853e+20 +-6.1930802244211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1bc1ffad0fa11e6b5590fa3f9506dc36c9c71bf1 b/fuzzing/seedcorpus/fuzz_from_chars_float/1bc1ffad0fa11e6b5590fa3f9506dc36c9c71bf1 new file mode 100644 index 000000000..37b825c3a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1bc1ffad0fa11e6b5590fa3f9506dc36c9c71bf1 @@ -0,0 +1 @@ +4e8380P2660: \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1cbbd7d768f77d4d3f24de43238979aa9fa1cd2f b/fuzzing/seedcorpus/fuzz_from_chars_float/1cbbd7d768f77d4d3f24de43238979aa9fa1cd2f new file mode 100644 index 000000000..d8995ac66 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1cbbd7d768f77d4d3f24de43238979aa9fa1cd2f @@ -0,0 +1 @@ +AAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1f55421bb314b6a2a019299780f2b53d07f8f887 b/fuzzing/seedcorpus/fuzz_from_chars_float/1f55421bb314b6a2a019299780f2b53d07f8f887 new file mode 100644 index 000000000..1292d4b61 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1f55421bb314b6a2a019299780f2b53d07f8f887 @@ -0,0 +1 @@ +4308e44 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1f6b54d22e88447189a74aeebe169baae592e62e b/fuzzing/seedcorpus/fuzz_from_chars_float/1f6b54d22e88447189a74aeebe169baae592e62e new file mode 100644 index 000000000..199b5c888 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/1f6b54d22e88447189a74aeebe169baae592e62e differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/1fed6b573b21bf30b5ee8f4311a171c74de7792f b/fuzzing/seedcorpus/fuzz_from_chars_float/1fed6b573b21bf30b5ee8f4311a171c74de7792f new file mode 100644 index 000000000..7fb0288f1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/1fed6b573b21bf30b5ee8f4311a171c74de7792f @@ -0,0 +1 @@ +.522 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2020921019d005e1944060f8b168cbae43174afb b/fuzzing/seedcorpus/fuzz_from_chars_float/2020921019d005e1944060f8b168cbae43174afb new file mode 100644 index 000000000..c0e0143d3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2020921019d005e1944060f8b168cbae43174afb @@ -0,0 +1 @@ +.3343000000000000010.p65 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/202e8e6e0e57467d059e02eda7a5ef3f48edbe37 b/fuzzing/seedcorpus/fuzz_from_chars_float/202e8e6e0e57467d059e02eda7a5ef3f48edbe37 new file mode 100644 index 000000000..a0371cf5a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/202e8e6e0e57467d059e02eda7a5ef3f48edbe37 @@ -0,0 +1,355 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-51668852.28231794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544310.056734-5528363043.595613 +-8159000612.363343 +-3072957148.7078047 +3079220817.911688 +-8458471846.61787 +-9222562952.799414 +-1587906788.0184402 +2845544102.5235634 +7892509404.137733 +-8394088799.434449 +-8871970975.653664 +6878128182.769302 +-2977407410.038788 +-6725749678.392197 +9254656545.983723 +6289186404.1730995 +5128165261.277636 +-5241260072.736095 +6917249801.302614 +-756<111942.267646 +-6857866820.515381 +8962461589.683685 +-5729987652.684038 +1471350203.0483437 +-9729367141.66414 +2395854137.699234 +7749640698.397217 +-2110788646.8097095 +-2186817857.724968 +-9.12434048525892e+20 +-2.487370407039252e+20 +7.059778770319386e+20 +-1.1474292187493714e+20 +7.543787358849793e+20 +4.613801268236794e+20 +-9.335581580814339e+20 +-4.957887898426344e+298 +-9.055478281801209e+20 +-5.970115306346393e+20 +9.305909352849319e+20 +2.803715496169754e+20 +-7.615729522564583e+20 +4.805477501654648e+20 +5.795519629478846e+20 +-9.21243319444016e+20 +-4.609469937594853e+20 +-6.1930802244211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.07936687484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2106fee948ed2b025a72a6b76be6cdd863167b92 b/fuzzing/seedcorpus/fuzz_from_chars_float/2106fee948ed2b025a72a6b76be6cdd863167b92 new file mode 100644 index 000000000..f0ff2631a Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/2106fee948ed2b025a72a6b76be6cdd863167b92 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/216b06a2a21bd24df39e4c8d7bc82c76f720d5b2 b/fuzzing/seedcorpus/fuzz_from_chars_float/216b06a2a21bd24df39e4c8d7bc82c76f720d5b2 new file mode 100644 index 000000000..d89baff6f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/216b06a2a21bd24df39e4c8d7bc82c76f720d5b2 @@ -0,0 +1 @@ +80923909092 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/21ee7ea2e27372f8d4e27ed8b4ccb166e288fe54 b/fuzzing/seedcorpus/fuzz_from_chars_float/21ee7ea2e27372f8d4e27ed8b4ccb166e288fe54 new file mode 100644 index 000000000..5b9a92ad3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/21ee7ea2e27372f8d4e27ed8b4ccb166e288fe54 @@ -0,0 +1 @@ +8e4e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/238d464127332ef0601da9be356004009f3d17dc b/fuzzing/seedcorpus/fuzz_from_chars_float/238d464127332ef0601da9be356004009f3d17dc new file mode 100644 index 000000000..adf31de0a Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/238d464127332ef0601da9be356004009f3d17dc differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/24eaac588bbb6cabff7a31048be218fbd9b21d47 b/fuzzing/seedcorpus/fuzz_from_chars_float/24eaac588bbb6cabff7a31048be218fbd9b21d47 new file mode 100644 index 000000000..d13393cc9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/24eaac588bbb6cabff7a31048be218fbd9b21d47 @@ -0,0 +1 @@ +8P6 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2577a8af5f73879427bafbc06f12a994add80999 b/fuzzing/seedcorpus/fuzz_from_chars_float/2577a8af5f73879427bafbc06f12a994add80999 new file mode 100644 index 000000000..4ad2c3a71 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2577a8af5f73879427bafbc06f12a994add80999 @@ -0,0 +1 @@ +618295897381036182 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/25e61f3f5862a1725ba0a3c9bb59656a5af9f159 b/fuzzing/seedcorpus/fuzz_from_chars_float/25e61f3f5862a1725ba0a3c9bb59656a5af9f159 new file mode 100644 index 000000000..dd8181aad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/25e61f3f5862a1725ba0a3c9bb59656a5af9f159 @@ -0,0 +1 @@ +-892723659236599236.09272365923659272365 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2614666033b921d010216f39380d907b9e6f85ff b/fuzzing/seedcorpus/fuzz_from_chars_float/2614666033b921d010216f39380d907b9e6f85ff new file mode 100644 index 000000000..4580a3425 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2614666033b921d010216f39380d907b9e6f85ff @@ -0,0 +1 @@ +-1333333366A062 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2621346941e9a63dbfb2cde8c1972ff07411d709 b/fuzzing/seedcorpus/fuzz_from_chars_float/2621346941e9a63dbfb2cde8c1972ff07411d709 new file mode 100644 index 000000000..d1395c546 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2621346941e9a63dbfb2cde8c1972ff07411d709 @@ -0,0 +1 @@ +8E3111 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/265ffc4a1dcabff197d7089b93539bc118d39eda b/fuzzing/seedcorpus/fuzz_from_chars_float/265ffc4a1dcabff197d7089b93539bc118d39eda new file mode 100644 index 000000000..68dcbbccd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/265ffc4a1dcabff197d7089b93539bc118d39eda @@ -0,0 +1 @@ +.eP \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/26945bd3dd5226f1769507d6e9f948806107a760 b/fuzzing/seedcorpus/fuzz_from_chars_float/26945bd3dd5226f1769507d6e9f948806107a760 new file mode 100644 index 000000000..4d1878ab1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/26945bd3dd5226f1769507d6e9f948806107a760 @@ -0,0 +1 @@ +5P301440 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/27538e0ba54666afd8ed97383c3a3350d9f72c01 b/fuzzing/seedcorpus/fuzz_from_chars_float/27538e0ba54666afd8ed97383c3a3350d9f72c01 new file mode 100644 index 000000000..96975c9e5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/27538e0ba54666afd8ed97383c3a3350d9f72c01 @@ -0,0 +1 @@ +-333333333333333333333333A333333 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/289bae5f69037a6a81103d16a516e5d1762dd607 b/fuzzing/seedcorpus/fuzz_from_chars_float/289bae5f69037a6a81103d16a516e5d1762dd607 new file mode 100644 index 000000000..c54a40ba8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/289bae5f69037a6a81103d16a516e5d1762dd607 @@ -0,0 +1 @@ +-809272672635923692672AAAAAACCCCC \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/28af28c95a25b5ce7d2216b4738fa486c6bc154c b/fuzzing/seedcorpus/fuzz_from_chars_float/28af28c95a25b5ce7d2216b4738fa486c6bc154c new file mode 100644 index 000000000..e6c949c37 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/28af28c95a25b5ce7d2216b4738fa486c6bc154c @@ -0,0 +1 @@ +36593236659738360922.35.99..36.9936. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/28b8e77e9dd9bac231e64e232c624134fd3b1ea7 b/fuzzing/seedcorpus/fuzz_from_chars_float/28b8e77e9dd9bac231e64e232c624134fd3b1ea7 new file mode 100644 index 000000000..25d5f7e3b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/28b8e77e9dd9bac231e64e232c624134fd3b1ea7 @@ -0,0 +1 @@ +-3300129194004245f6 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2a4b52ebf2151550a9aa6c49f053e16705147a7d b/fuzzing/seedcorpus/fuzz_from_chars_float/2a4b52ebf2151550a9aa6c49f053e16705147a7d new file mode 100644 index 000000000..deafa3a30 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2a4b52ebf2151550a9aa6c49f053e16705147a7d @@ -0,0 +1,2 @@ +-3A903733333000006612421877182778912AAAA. +6 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2b2998556e26622b7e5ed08db1cad9767071df48 b/fuzzing/seedcorpus/fuzz_from_chars_float/2b2998556e26622b7e5ed08db1cad9767071df48 new file mode 100644 index 000000000..fcdde9bfb Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/2b2998556e26622b7e5ed08db1cad9767071df48 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2b54163cc1af019f6661720a4160efcb497ba94e b/fuzzing/seedcorpus/fuzz_from_chars_float/2b54163cc1af019f6661720a4160efcb497ba94e new file mode 100644 index 000000000..1c28a31a0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2b54163cc1af019f6661720a4160efcb497ba94e @@ -0,0 +1 @@ +-98673333336666685e662p888 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2c061e185e00f2bf1405d8ca46426a47bf66f602 b/fuzzing/seedcorpus/fuzz_from_chars_float/2c061e185e00f2bf1405d8ca46426a47bf66f602 new file mode 100644 index 000000000..2e885ef9b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2c061e185e00f2bf1405d8ca46426a47bf66f602 @@ -0,0 +1 @@ +-333333333330000000000000000001379044. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2c41ff1725f495246489e046ee2e47f044171df7 b/fuzzing/seedcorpus/fuzz_from_chars_float/2c41ff1725f495246489e046ee2e47f044171df7 new file mode 100644 index 000000000..966f23917 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2c41ff1725f495246489e046ee2e47f044171df7 @@ -0,0 +1 @@ +2P266620A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2ca839beea391a5a5851b299ac4a6d138ccb7d3f b/fuzzing/seedcorpus/fuzz_from_chars_float/2ca839beea391a5a5851b299ac4a6d138ccb7d3f new file mode 100644 index 000000000..401949515 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2ca839beea391a5a5851b299ac4a6d138ccb7d3f @@ -0,0 +1 @@ +-333333333333333333333f23 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2d2929e0f1bca99d9652924ce73b7969d33ff429 b/fuzzing/seedcorpus/fuzz_from_chars_float/2d2929e0f1bca99d9652924ce73b7969d33ff429 new file mode 100644 index 000000000..79926dd58 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2d2929e0f1bca99d9652924ce73b7969d33ff429 @@ -0,0 +1 @@ +AAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2d94d2f7aebe52b9b510a342a501276befe35c71 b/fuzzing/seedcorpus/fuzz_from_chars_float/2d94d2f7aebe52b9b510a342a501276befe35c71 new file mode 100644 index 000000000..ffb81db0e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2d94d2f7aebe52b9b510a342a501276befe35c71 @@ -0,0 +1 @@ +-856281031010310 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2dab75dd8d6b9b74532d9cc703449dcd971c750a b/fuzzing/seedcorpus/fuzz_from_chars_float/2dab75dd8d6b9b74532d9cc703449dcd971c750a new file mode 100644 index 000000000..fb0ff36da --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2dab75dd8d6b9b74532d9cc703449dcd971c750a @@ -0,0 +1,2 @@ +-809273333333333333333333333333333333333333333333300000000000000000000000000000000003333333333000000273366.9>>:9`69,-5 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2dd5aeebdf2952ecca9efae7bf5dde59bdfcc366 b/fuzzing/seedcorpus/fuzz_from_chars_float/2dd5aeebdf2952ecca9efae7bf5dde59bdfcc366 new file mode 100644 index 000000000..da396d899 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2dd5aeebdf2952ecca9efae7bf5dde59bdfcc366 @@ -0,0 +1,499 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452 +-6989049626.595518 +-4656828161.473779 +9763680224.51627 +9751951081.686802 +-337738879.7371044 +-3218308721.9295416 +5316866140.38973 +253140072.20806503 +-67015884.19111252 +-4145941047.9776325 +9982650191.863255 +-4805195750.912774 +2007631436.0563717 +-1336980163.13908 +3876768555.2980576 +6369274349.731985 +714573945.7687016 +8217335015.851101 +-7220020049.135553 +-1375882154.3342018 +-7965288568.390052 +-4972087297.866529 +-9617862443.628145 +4847618299.542833 +-8064903300.436237 +4916757135.607399 +515751419.4691963 +9215353924.090961 +-364913989.2347889 +-3507329283.0497313 +1317810244.4926357 +-7295868652.742394 +6876470676.15094 +-2438584710.5560446 +7832150646.9747505 +8400914366.011929 +1239217006.5196457 +6751063909.677446 +-8090155725.787666 +-791010118.7786922 +-5761208048.211159 +-2168171518.217272 +157362439.9876709 +-9381050662.044998 +8463512975.957085 +-8942516901.275276 +3082320494.2169495 +1724377540.4461613 +7891183680.86731 +2768052907.1448727 +9622664872.800652 +1364929177.6346016 +2438745344.650511 +-8880072185.722937 +-6616488941.48659 +4640411716.87112 +-3855456670.21 +1806278957.86557 +-7719725766.293733 +4870997554.669283 +-2645372770.749628 +1412833844.6981277 +3235738635.1283627 +-5467691529.236322 +8423135631.25145 +4366804024.218529 +7475317508.951164 +-6729951259.834599 +-3042731230.1005173 +-8052832339.079965 +-9910878365.52365 +-1406785809.4684315 +1325159253.5445614 +5899318569.084028 +-7335586270.0054455 +2722923617.737646 +1965337620.4644394 +6687202389.800978 +4625471957.369957 +-1627665340.1117573 +-8705574779.906586 +-4020333220.7047033 +-168217295.5267563 +1353090961.899828 +-5673224931.216288 +-8840443040.525124 +-7842962545.884165 +-1635234877.4911537 +-5086175166.746623 +-5190316401.77241 +6885977762.7181015 +6670679088.13579 +9377637707.2052 +4740081906.320965 +-9855927038.85421 +-393083365.2558689 +1930287943.1776905 +-2593616140.4156933 +6973281423.628536 +-1785710158.250329 +-143515758.43083954 +-9165566885.262552 +-3271947075.442127 +1866146881.2823467 +9922318687.247532 +2105889374.9543476 +1412191145.1990738 +4899253184.97513 +-4963639159.271849 +8618179390.053493 +-4270177979.582361 +6055692117.72047 +323727457.89961624 +-1997101808.7895699 +5636742008.106144 +4691147693.264648 +-1339528188.4935036 +-5129832360.937038 +-7851471851.588366 +5036450555.008472 +-2531325190.1094837 +-4269349462.4435883 +-9714134709.103092 +-1759752342.380949 +-2786309738.9712315 +8482952443.393608 +-1767831217.3464785 +-9591336055.176716 +6235445085.696083 +-4558818055.646798 +-4746793816.840109 +-4656884038.338767 +8283627521.822033 +7271616925.880337 +-4975594184.59415 +5719936545.010145 +3926786838.1136494 +-1573054519.4802885 +-5528363043.595613 +-8159000612.363343 +-3072957148.7078047 +3079220817.911688 +-8458471846.61787 +-9222562952.799414 +-1587906788.0184402 +2845544102.5235634 +7892509404.137733 +-8394088799.434449 +-8871970975.653664 +6878128182.769302 +-2977407410.038788 +-6725749678.392197 +9254656545.983723 +6289186404.1730995 +5128165261.277636 +-5241260072.736095 +6917249801.302614 +-756<111942.267646 +-6857866820.515381 +8962461589.683685 +-5729987652.684038 +1471350203.0483437 +-9729367141.66414 +2395854137.699234 +7749640698.397217 +-2110788646.8097095 +-2186817857.724968 +-9.12434048525892e+20 +-2.487370407039252e+20 +7.059778770319386e+20 +-1.1474292187493714e+20 +7.543787358849793e+20 +4.613801268236794e+20 +-9.335581580814339e+20 +-4.957887898426344e+298 +-9.055478281801209e+20 +-5.970115306346393e+20 +9.305909352849319e+20 +2.803715496169754e+20 +-7.615729522564583e+20 +4.805477501654648e+20 +5.795519629478846e+20 +-9.21243319444016e+20 +-4.609469937594853e+20 +-6.1930802244211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.07936687484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2dea92bdc463521959009f50ca85fcb99cfd7765 b/fuzzing/seedcorpus/fuzz_from_chars_float/2dea92bdc463521959009f50ca85fcb99cfd7765 new file mode 100644 index 000000000..dea7f62f2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2dea92bdc463521959009f50ca85fcb99cfd7765 @@ -0,0 +1 @@ +96568869568FFFFFFFFFFFFFFFFFFFFFFFFFFFF6 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2e80729058fa138a67e0236f974f945b67cec264 b/fuzzing/seedcorpus/fuzz_from_chars_float/2e80729058fa138a67e0236f974f945b67cec264 new file mode 100644 index 000000000..410c37ba2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2e80729058fa138a67e0236f974f945b67cec264 @@ -0,0 +1 @@ +.1067757175eAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2e9a0f8c0d7a9b01f1cf033c916cfe3f99d12d07 b/fuzzing/seedcorpus/fuzz_from_chars_float/2e9a0f8c0d7a9b01f1cf033c916cfe3f99d12d07 new file mode 100644 index 000000000..8508dde8d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2e9a0f8c0d7a9b01f1cf033c916cfe3f99d12d07 @@ -0,0 +1 @@ +NAN(i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2f51f9054a369db6078a6af968181d06c0e38ffc b/fuzzing/seedcorpus/fuzz_from_chars_float/2f51f9054a369db6078a6af968181d06c0e38ffc new file mode 100644 index 000000000..2b3ba345c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2f51f9054a369db6078a6af968181d06c0e38ffc @@ -0,0 +1 @@ +AAAAAAAAAAA.AAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2fa28e5709dba3f75539b4d76b6fe87c81039114 b/fuzzing/seedcorpus/fuzz_from_chars_float/2fa28e5709dba3f75539b4d76b6fe87c81039114 new file mode 100644 index 000000000..c1b72881a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2fa28e5709dba3f75539b4d76b6fe87c81039114 @@ -0,0 +1 @@ +-7445198472.027265923659272365926599236309.6.27. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/2ff2333c80106e2efede84723844984d4e39b25b b/fuzzing/seedcorpus/fuzz_from_chars_float/2ff2333c80106e2efede84723844984d4e39b25b new file mode 100644 index 000000000..e2bf4b4ce --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/2ff2333c80106e2efede84723844984d4e39b25b @@ -0,0 +1 @@ +8E00000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/301c8da74810a617a795b08e81326194d4c1b11c b/fuzzing/seedcorpus/fuzz_from_chars_float/301c8da74810a617a795b08e81326194d4c1b11c new file mode 100644 index 000000000..bf2ef4e70 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/301c8da74810a617a795b08e81326194d4c1b11c @@ -0,0 +1 @@ +4e+ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/31ffe3e990365dffdefbb6129dbd0aa1a401c7c5 b/fuzzing/seedcorpus/fuzz_from_chars_float/31ffe3e990365dffdefbb6129dbd0aa1a401c7c5 new file mode 100644 index 000000000..a10d42711 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/31ffe3e990365dffdefbb6129dbd0aa1a401c7c5 @@ -0,0 +1 @@ +5e00 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/328643b761142aa189fea7d9a29edc22274aadc5 b/fuzzing/seedcorpus/fuzz_from_chars_float/328643b761142aa189fea7d9a29edc22274aadc5 new file mode 100644 index 000000000..bb4ad3aaf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/328643b761142aa189fea7d9a29edc22274aadc5 @@ -0,0 +1 @@ +5P2501 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/32b2184d2dbb51ec1f4d43eeb0870b911c1ac92c b/fuzzing/seedcorpus/fuzz_from_chars_float/32b2184d2dbb51ec1f4d43eeb0870b911c1ac92c new file mode 100644 index 000000000..f0d14cb44 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/32b2184d2dbb51ec1f4d43eeb0870b911c1ac92c differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3321de2c458c05f6cb0412caffa7b971ccdaec37 b/fuzzing/seedcorpus/fuzz_from_chars_float/3321de2c458c05f6cb0412caffa7b971ccdaec37 new file mode 100644 index 000000000..4b2c4bc5b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3321de2c458c05f6cb0412caffa7b971ccdaec37 @@ -0,0 +1,2 @@ +-8092733333333333333333333333333333333333333333333333339923AAAAAA.A5 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3369368f6b7330e9593164d592c10b00682c97a8 b/fuzzing/seedcorpus/fuzz_from_chars_float/3369368f6b7330e9593164d592c10b00682c97a8 new file mode 100644 index 000000000..e909e15ee --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3369368f6b7330e9593164d592c10b00682c97a8 @@ -0,0 +1 @@ +-.3243511511554351155543511435115115551e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/36282fac116d9fd6b37cc425310e1a8510f08a53 b/fuzzing/seedcorpus/fuzz_from_chars_float/36282fac116d9fd6b37cc425310e1a8510f08a53 new file mode 100644 index 000000000..d98a9e309 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/36282fac116d9fd6b37cc425310e1a8510f08a53 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/36572b56fa3441db34fbbd7c17241b1ecb408842 b/fuzzing/seedcorpus/fuzz_from_chars_float/36572b56fa3441db34fbbd7c17241b1ecb408842 new file mode 100644 index 000000000..20f3d3165 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/36572b56fa3441db34fbbd7c17241b1ecb408842 @@ -0,0 +1 @@ +.00000000000? \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3915cc2281fb3b2141c96e04a948bd3d3e174558 b/fuzzing/seedcorpus/fuzz_from_chars_float/3915cc2281fb3b2141c96e04a948bd3d3e174558 new file mode 100644 index 000000000..d8f29b0ac --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3915cc2281fb3b2141c96e04a948bd3d3e174558 @@ -0,0 +1 @@ +809272301.9E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/39dfa55283318d31afe5a3ff4a0e3253e2045e43 b/fuzzing/seedcorpus/fuzz_from_chars_float/39dfa55283318d31afe5a3ff4a0e3253e2045e43 new file mode 100644 index 000000000..af2e09a3e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/39dfa55283318d31afe5a3ff4a0e3253e2045e43 @@ -0,0 +1 @@ +0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3a52ce780950d4d969792a2559cd519d7ee8c727 b/fuzzing/seedcorpus/fuzz_from_chars_float/3a52ce780950d4d969792a2559cd519d7ee8c727 new file mode 100644 index 000000000..945c9b46d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3a52ce780950d4d969792a2559cd519d7ee8c727 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 b/fuzzing/seedcorpus/fuzz_from_chars_float/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 new file mode 100644 index 000000000..3cf20d57b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3bf0cf328f6de852a3e719ddf6216240cecb3687 b/fuzzing/seedcorpus/fuzz_from_chars_float/3bf0cf328f6de852a3e719ddf6216240cecb3687 new file mode 100644 index 000000000..02bda52be Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/3bf0cf328f6de852a3e719ddf6216240cecb3687 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3c23c51d92b4a6477246ffb28d7a420f7a7d889d b/fuzzing/seedcorpus/fuzz_from_chars_float/3c23c51d92b4a6477246ffb28d7a420f7a7d889d new file mode 100644 index 000000000..c0d6a7d09 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3c23c51d92b4a6477246ffb28d7a420f7a7d889d @@ -0,0 +1 @@ +56562062020620 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3cc706f4672a743a61efeb5da848bc27c68fdf82 b/fuzzing/seedcorpus/fuzz_from_chars_float/3cc706f4672a743a61efeb5da848bc27c68fdf82 new file mode 100644 index 000000000..b3d04dfe0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3cc706f4672a743a61efeb5da848bc27c68fdf82 @@ -0,0 +1 @@ +cccccccccccccccccccccccccccc \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3d316b2c50a307960a1598e2c88c743901e31fab b/fuzzing/seedcorpus/fuzz_from_chars_float/3d316b2c50a307960a1598e2c88c743901e31fab new file mode 100644 index 000000000..fac23c3e7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3d316b2c50a307960a1598e2c88c743901e31fab @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAAAAAAAD \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3db127ecea788d9ed15955acd1b4f6091ad0fe1e b/fuzzing/seedcorpus/fuzz_from_chars_float/3db127ecea788d9ed15955acd1b4f6091ad0fe1e new file mode 100644 index 000000000..c513df776 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3db127ecea788d9ed15955acd1b4f6091ad0fe1e @@ -0,0 +1,2 @@ +-8092733333333333333333333333333333333333333333333333333AAAAAA.AAAAAAAAAA000000000000000000000000000000000000000000000000000000000006148914691236517204AAAAAA.AAAAA333330168] + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3e4b54fc25255b2ecc05b45578c1dcdc4dbaf908 b/fuzzing/seedcorpus/fuzz_from_chars_float/3e4b54fc25255b2ecc05b45578c1dcdc4dbaf908 new file mode 100644 index 000000000..ae43496bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3e4b54fc25255b2ecc05b45578c1dcdc4dbaf908 @@ -0,0 +1 @@ +-333333333233333333A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3f62dd8e0afc73ad043b169cbf508d39783d14ed b/fuzzing/seedcorpus/fuzz_from_chars_float/3f62dd8e0afc73ad043b169cbf508d39783d14ed new file mode 100644 index 000000000..f10385a07 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3f62dd8e0afc73ad043b169cbf508d39783d14ed @@ -0,0 +1 @@ +-99194000656133.021190991940006561404f2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/3feda0153eee1380b496298450dc5a74324eb8c1 b/fuzzing/seedcorpus/fuzz_from_chars_float/3feda0153eee1380b496298450dc5a74324eb8c1 new file mode 100644 index 000000000..280762b91 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/3feda0153eee1380b496298450dc5a74324eb8c1 @@ -0,0 +1 @@ +NA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/41be845b8e19da10e18a6bd3105793484d22bd53 b/fuzzing/seedcorpus/fuzz_from_chars_float/41be845b8e19da10e18a6bd3105793484d22bd53 new file mode 100644 index 000000000..a091174f3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/41be845b8e19da10e18a6bd3105793484d22bd53 @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/42a1d55281040ba7d502c80234aeedd60ca4fbb9 b/fuzzing/seedcorpus/fuzz_from_chars_float/42a1d55281040ba7d502c80234aeedd60ca4fbb9 new file mode 100644 index 000000000..7f936eafd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/42a1d55281040ba7d502c80234aeedd60ca4fbb9 @@ -0,0 +1 @@ +-4e82380P26656# \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/446ad71a454cb227c265b69a508a9e30acf5f499 b/fuzzing/seedcorpus/fuzz_from_chars_float/446ad71a454cb227c265b69a508a9e30acf5f499 new file mode 100644 index 000000000..22f41da7f Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/446ad71a454cb227c265b69a508a9e30acf5f499 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/45a0dd496da0299fdbad86f3691d608e24f1b3a5 b/fuzzing/seedcorpus/fuzz_from_chars_float/45a0dd496da0299fdbad86f3691d608e24f1b3a5 new file mode 100644 index 000000000..308bf9ac0 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/45a0dd496da0299fdbad86f3691d608e24f1b3a5 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/474eb66fc9b3d71fbb67de60d7189005eb35fae5 b/fuzzing/seedcorpus/fuzz_from_chars_float/474eb66fc9b3d71fbb67de60d7189005eb35fae5 new file mode 100644 index 000000000..2b3d2a87c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/474eb66fc9b3d71fbb67de60d7189005eb35fae5 @@ -0,0 +1 @@ +1P6 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/477922d58615673f602cfed31cc69b7443923d6a b/fuzzing/seedcorpus/fuzz_from_chars_float/477922d58615673f602cfed31cc69b7443923d6a new file mode 100644 index 000000000..da9b87446 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/477922d58615673f602cfed31cc69b7443923d6a @@ -0,0 +1 @@ +-0.52AAAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0278 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/486c3952a30c4c297c5cfb628e88d8bce88968fe b/fuzzing/seedcorpus/fuzz_from_chars_float/486c3952a30c4c297c5cfb628e88d8bce88968fe new file mode 100644 index 000000000..f3b23c06e Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/486c3952a30c4c297c5cfb628e88d8bce88968fe differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4890d63d85db152f4ea00f00aeeee45e8b734010 b/fuzzing/seedcorpus/fuzz_from_chars_float/4890d63d85db152f4ea00f00aeeee45e8b734010 new file mode 100644 index 000000000..0be4b9fe5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4890d63d85db152f4ea00f00aeeee45e8b734010 @@ -0,0 +1 @@ +880923135141092313 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/48944dacdf4cc2f9f66186dc5315902cc154002f b/fuzzing/seedcorpus/fuzz_from_chars_float/48944dacdf4cc2f9f66186dc5315902cc154002f new file mode 100644 index 000000000..7b6427250 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/48944dacdf4cc2f9f66186dc5315902cc154002f @@ -0,0 +1 @@ +8090000090178DDDD2e+ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/49159b07f2d958af3e6eb3a0f7d83f2f3c863e50 b/fuzzing/seedcorpus/fuzz_from_chars_float/49159b07f2d958af3e6eb3a0f7d83f2f3c863e50 new file mode 100644 index 000000000..6a9dd8d98 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/49159b07f2d958af3e6eb3a0f7d83f2f3c863e50 @@ -0,0 +1 @@ +00000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/494fbdfa3dcfb735ef0a5ea57340f01f636a6f9c b/fuzzing/seedcorpus/fuzz_from_chars_float/494fbdfa3dcfb735ef0a5ea57340f01f636a6f9c new file mode 100644 index 000000000..7ab8f8911 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/494fbdfa3dcfb735ef0a5ea57340f01f636a6f9c @@ -0,0 +1 @@ +.E5P2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4a2e9f207860c85a0c9ccea75d21471809f7ddbf b/fuzzing/seedcorpus/fuzz_from_chars_float/4a2e9f207860c85a0c9ccea75d21471809f7ddbf new file mode 100644 index 000000000..fa8312802 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4a2e9f207860c85a0c9ccea75d21471809f7ddbf @@ -0,0 +1 @@ +4e0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4ae2a1638538c14765aaf9115b0d278bb0af65f5 b/fuzzing/seedcorpus/fuzz_from_chars_float/4ae2a1638538c14765aaf9115b0d278bb0af65f5 new file mode 100644 index 000000000..87017f57f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4ae2a1638538c14765aaf9115b0d278bb0af65f5 @@ -0,0 +1 @@ +.P \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4b74f76c16dd154a4d32d102da0347f65fa3e1d7 b/fuzzing/seedcorpus/fuzz_from_chars_float/4b74f76c16dd154a4d32d102da0347f65fa3e1d7 new file mode 100644 index 000000000..4bdcfe020 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4b74f76c16dd154a4d32d102da0347f65fa3e1d7 @@ -0,0 +1 @@ +-89272333333380927233184193333366376 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4c9a8a283f02c8859ff4658007a908ca86082953 b/fuzzing/seedcorpus/fuzz_from_chars_float/4c9a8a283f02c8859ff4658007a908ca86082953 new file mode 100644 index 000000000..74c526a56 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4c9a8a283f02c8859ff4658007a908ca86082953 @@ -0,0 +1 @@ +A. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4d709b4672333735e437a2e5f3e1ea2f9a4f2b0c b/fuzzing/seedcorpus/fuzz_from_chars_float/4d709b4672333735e437a2e5f3e1ea2f9a4f2b0c new file mode 100644 index 000000000..1c23f1fb6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4d709b4672333735e437a2e5f3e1ea2f9a4f2b0c @@ -0,0 +1 @@ +-AAAAAAAEAAAAAAAAAAAAAAAAAAAAAA> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4dc108ce644ebe204a2843062c60b204d8809c43 b/fuzzing/seedcorpus/fuzz_from_chars_float/4dc108ce644ebe204a2843062c60b204d8809c43 new file mode 100644 index 000000000..924552bc4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4dc108ce644ebe204a2843062c60b204d8809c43 @@ -0,0 +1 @@ +88200842810203888 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4dc4576623bbe463cf57958ce10d8e80237a29ec b/fuzzing/seedcorpus/fuzz_from_chars_float/4dc4576623bbe463cf57958ce10d8e80237a29ec new file mode 100644 index 000000000..d0098ad36 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4dc4576623bbe463cf57958ce10d8e80237a29ec @@ -0,0 +1 @@ +3P26A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4e2b083b88d2e4a2bde46a6404ac54d10abb1347 b/fuzzing/seedcorpus/fuzz_from_chars_float/4e2b083b88d2e4a2bde46a6404ac54d10abb1347 new file mode 100644 index 000000000..5f791bb3f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4e2b083b88d2e4a2bde46a6404ac54d10abb1347 @@ -0,0 +1 @@ +5P30440 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4e63576702338f8261655787434bee6c60dbaba9 b/fuzzing/seedcorpus/fuzz_from_chars_float/4e63576702338f8261655787434bee6c60dbaba9 new file mode 100644 index 000000000..589060964 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4e63576702338f8261655787434bee6c60dbaba9 @@ -0,0 +1 @@ +61P91 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4f908bb45b74e6b1bac7c02a8e3bb2a7f6813e9d b/fuzzing/seedcorpus/fuzz_from_chars_float/4f908bb45b74e6b1bac7c02a8e3bb2a7f6813e9d new file mode 100644 index 000000000..4dd7774ea --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4f908bb45b74e6b1bac7c02a8e3bb2a7f6813e9d @@ -0,0 +1 @@ +805P93 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/4fc9bc15943573244144fdf8aaf9d9aa5202c6ce b/fuzzing/seedcorpus/fuzz_from_chars_float/4fc9bc15943573244144fdf8aaf9d9aa5202c6ce new file mode 100644 index 000000000..c38f6e6ab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/4fc9bc15943573244144fdf8aaf9d9aa5202c6ce @@ -0,0 +1,7 @@ +-0.7 +9e-265 +85e-37 +623e+10251086569.8#714>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.8071456 +-5332617826.3962755 +-552968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5049789a76028963bef5e7695a1b43cca13895b5 b/fuzzing/seedcorpus/fuzz_from_chars_float/5049789a76028963bef5e7695a1b43cca13895b5 new file mode 100644 index 000000000..103e08f22 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5049789a76028963bef5e7695a1b43cca13895b5 @@ -0,0 +1 @@ +856562062307e-A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/50b05ced26e2b6ba19e04ee5fe8f51a3c4b153dc b/fuzzing/seedcorpus/fuzz_from_chars_float/50b05ced26e2b6ba19e04ee5fe8f51a3c4b153dc new file mode 100644 index 000000000..4adaec5c3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/50b05ced26e2b6ba19e04ee5fe8f51a3c4b153dc @@ -0,0 +1 @@ +-.44444444444444144444444444444444444 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/50e12053d5ac6e98b8b2847767549f28a3687146 b/fuzzing/seedcorpus/fuzz_from_chars_float/50e12053d5ac6e98b8b2847767549f28a3687146 new file mode 100644 index 000000000..198619549 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/50e12053d5ac6e98b8b2847767549f28a3687146 @@ -0,0 +1,95 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +205054263588366773474331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.73506319914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-96875494525.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.3428836122343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/510806af5f31fa2bc92178ac384f65b2dc60087c b/fuzzing/seedcorpus/fuzz_from_chars_float/510806af5f31fa2bc92178ac384f65b2dc60087c new file mode 100644 index 000000000..9c3423ab7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/510806af5f31fa2bc92178ac384f65b2dc60087c @@ -0,0 +1 @@ +8e-8806 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/511993d3c99719e38a6779073019dacd7178ddb9 b/fuzzing/seedcorpus/fuzz_from_chars_float/511993d3c99719e38a6779073019dacd7178ddb9 new file mode 100644 index 000000000..675f43ab4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/511993d3c99719e38a6779073019dacd7178ddb9 @@ -0,0 +1 @@ +P \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/516b9783fca517eecbd1d064da2d165310b19759 b/fuzzing/seedcorpus/fuzz_from_chars_float/516b9783fca517eecbd1d064da2d165310b19759 new file mode 100644 index 000000000..4f6c4ee9d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/516b9783fca517eecbd1d064da2d165310b19759 @@ -0,0 +1 @@ +p \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/51a0080e839ef685d54046adfe84836ed76e53f3 b/fuzzing/seedcorpus/fuzz_from_chars_float/51a0080e839ef685d54046adfe84836ed76e53f3 new file mode 100644 index 000000000..2f52721c9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/51a0080e839ef685d54046adfe84836ed76e53f3 @@ -0,0 +1 @@ +-80927333333336666668e56668/ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/533800bbf0c2ea1d05e33673914f991de0e64205 b/fuzzing/seedcorpus/fuzz_from_chars_float/533800bbf0c2ea1d05e33673914f991de0e64205 new file mode 100644 index 000000000..c4164bf34 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/533800bbf0c2ea1d05e33673914f991de0e64205 @@ -0,0 +1,2 @@ +-0.4 +>>>>>>>>)>>>>>>>>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5560ed9d5e5f1b5ed42c22f2c4af3f1a7f51b049 b/fuzzing/seedcorpus/fuzz_from_chars_float/5560ed9d5e5f1b5ed42c22f2c4af3f1a7f51b049 new file mode 100644 index 000000000..cbddf3076 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5560ed9d5e5f1b5ed42c22f2c4af3f1a7f51b049 @@ -0,0 +1 @@ +-809273333333333233333333A3333333333335P333133A5 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5564a0e34634692550e94441ed9a34f6fa5310e5 b/fuzzing/seedcorpus/fuzz_from_chars_float/5564a0e34634692550e94441ed9a34f6fa5310e5 new file mode 100644 index 000000000..0d823b8fb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5564a0e34634692550e94441ed9a34f6fa5310e5 @@ -0,0 +1 @@ +3331665266316652665P-6668 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/556eb1aaf4c237443f05bbfc58e9c2549120ad14 b/fuzzing/seedcorpus/fuzz_from_chars_float/556eb1aaf4c237443f05bbfc58e9c2549120ad14 new file mode 100644 index 000000000..4a1c4fe5f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/556eb1aaf4c237443f05bbfc58e9c2549120ad14 @@ -0,0 +1 @@ +4308e44309e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5693bf0bdf483e88705adbe4ed74e95a1a1078bc b/fuzzing/seedcorpus/fuzz_from_chars_float/5693bf0bdf483e88705adbe4ed74e95a1a1078bc new file mode 100644 index 000000000..512fade2b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5693bf0bdf483e88705adbe4ed74e95a1a1078bc @@ -0,0 +1 @@ +3333333133333333A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/580ce6772676d7cd5d08e09e3404741bfe96bd0e b/fuzzing/seedcorpus/fuzz_from_chars_float/580ce6772676d7cd5d08e09e3404741bfe96bd0e new file mode 100644 index 000000000..0ebb9fec1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/580ce6772676d7cd5d08e09e3404741bfe96bd0e @@ -0,0 +1 @@ +-809273333333333333333333333333333333333333333333333AAA000000000000000001103769320 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/58460945fe22c2686f2e69d19ce36bef330179c2 b/fuzzing/seedcorpus/fuzz_from_chars_float/58460945fe22c2686f2e69d19ce36bef330179c2 new file mode 100644 index 000000000..0b43706e3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/58460945fe22c2686f2e69d19ce36bef330179c2 @@ -0,0 +1 @@ +5P+ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5869d13c52e598ceb036c5790ec36799be217515 b/fuzzing/seedcorpus/fuzz_from_chars_float/5869d13c52e598ceb036c5790ec36799be217515 new file mode 100644 index 000000000..418cc11a5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5869d13c52e598ceb036c5790ec36799be217515 @@ -0,0 +1 @@ +-33333333333333333333333f32 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5a360939f0d920cf06e9adfbc11ffd0248c96a74 b/fuzzing/seedcorpus/fuzz_from_chars_float/5a360939f0d920cf06e9adfbc11ffd0248c96a74 new file mode 100644 index 000000000..be33345e9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5a360939f0d920cf06e9adfbc11ffd0248c96a74 @@ -0,0 +1 @@ +4.P \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5a5b0f9b7d3f8fc84c3cef8fd8efaaa6c70d75ab b/fuzzing/seedcorpus/fuzz_from_chars_float/5a5b0f9b7d3f8fc84c3cef8fd8efaaa6c70d75ab new file mode 100644 index 000000000..fc9afb48e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5a5b0f9b7d3f8fc84c3cef8fd8efaaa6c70d75ab @@ -0,0 +1 @@ +59 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5bced33240702698b52df8a14954ff23aab871b3 b/fuzzing/seedcorpus/fuzz_from_chars_float/5bced33240702698b52df8a14954ff23aab871b3 new file mode 100644 index 000000000..23014249c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5bced33240702698b52df8a14954ff23aab871b3 @@ -0,0 +1 @@ +-809272333333333333333339272333333333333.33.31 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5d21b71417c45a6454ee1dfd4bf548cfb3674fee b/fuzzing/seedcorpus/fuzz_from_chars_float/5d21b71417c45a6454ee1dfd4bf548cfb3674fee new file mode 100644 index 000000000..4ddcfe4ef Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/5d21b71417c45a6454ee1dfd4bf548cfb3674fee differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5efc2b73d5242fb8712808f1d75acf1bc4d6502d b/fuzzing/seedcorpus/fuzz_from_chars_float/5efc2b73d5242fb8712808f1d75acf1bc4d6502d new file mode 100644 index 000000000..348d62092 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5efc2b73d5242fb8712808f1d75acf1bc4d6502d @@ -0,0 +1 @@ +-809273333333333666666666664e5023 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5f41ce5ae4c02a0c85767b7cadbec5ca1d2fc019 b/fuzzing/seedcorpus/fuzz_from_chars_float/5f41ce5ae4c02a0c85767b7cadbec5ca1d2fc019 new file mode 100644 index 000000000..eea413efc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5f41ce5ae4c02a0c85767b7cadbec5ca1d2fc019 @@ -0,0 +1,5 @@ +-0.7 +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.8071456 +-5332617826.3962755 +-552968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/5f5d4f6e0458dabaec2721a7d16765ac6d643567 b/fuzzing/seedcorpus/fuzz_from_chars_float/5f5d4f6e0458dabaec2721a7d16765ac6d643567 new file mode 100644 index 000000000..43f030c74 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/5f5d4f6e0458dabaec2721a7d16765ac6d643567 @@ -0,0 +1 @@ +5.7 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/609736b113367a24eb7ce4109de3b6434952facf b/fuzzing/seedcorpus/fuzz_from_chars_float/609736b113367a24eb7ce4109de3b6434952facf new file mode 100644 index 000000000..04d6d8712 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/609736b113367a24eb7ce4109de3b6434952facf @@ -0,0 +1 @@ +3ePe \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/615a33e3f2edb8c9a8c5853493f386e18c2625de b/fuzzing/seedcorpus/fuzz_from_chars_float/615a33e3f2edb8c9a8c5853493f386e18c2625de new file mode 100644 index 000000000..a1ff5af55 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/615a33e3f2edb8c9a8c5853493f386e18c2625de @@ -0,0 +1 @@ +80p92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/621f2ca3518d5c84eeb8eedb93789e086de82167 b/fuzzing/seedcorpus/fuzz_from_chars_float/621f2ca3518d5c84eeb8eedb93789e086de82167 new file mode 100644 index 000000000..ad019c4e1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/621f2ca3518d5c84eeb8eedb93789e086de82167 @@ -0,0 +1 @@ +8093368090000001 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/625ca5cb7bd2dda427e5b75c100509de2635795e b/fuzzing/seedcorpus/fuzz_from_chars_float/625ca5cb7bd2dda427e5b75c100509de2635795e new file mode 100644 index 000000000..6ac148137 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/625ca5cb7bd2dda427e5b75c100509de2635795e @@ -0,0 +1 @@ +5P862 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6499092900eb286691cf6fab9b7a9dfbe6ee3260 b/fuzzing/seedcorpus/fuzz_from_chars_float/6499092900eb286691cf6fab9b7a9dfbe6ee3260 new file mode 100644 index 000000000..b8a0211b5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6499092900eb286691cf6fab9b7a9dfbe6ee3260 @@ -0,0 +1 @@ +3e88408 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/651f8de86a46010cfcd6b55d90603b746b73d69d b/fuzzing/seedcorpus/fuzz_from_chars_float/651f8de86a46010cfcd6b55d90603b746b73d69d new file mode 100644 index 000000000..632c09689 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/651f8de86a46010cfcd6b55d90603b746b73d69d @@ -0,0 +1 @@ +.3001004110401040000.P501100 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/65f73bbea07e68e2bd21a69923d8f66ec47604a3 b/fuzzing/seedcorpus/fuzz_from_chars_float/65f73bbea07e68e2bd21a69923d8f66ec47604a3 new file mode 100644 index 000000000..b996469df --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/65f73bbea07e68e2bd21a69923d8f66ec47604a3 @@ -0,0 +1 @@ +-80927236592365952 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/665acb3e5f2da5d60b130fa358bda3a94140e321 b/fuzzing/seedcorpus/fuzz_from_chars_float/665acb3e5f2da5d60b130fa358bda3a94140e321 new file mode 100644 index 000000000..67e2caba4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/665acb3e5f2da5d60b130fa358bda3a94140e321 @@ -0,0 +1 @@ +85620620 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/671f92218957fd9e98d68c9a551d9d1ed57f2d43 b/fuzzing/seedcorpus/fuzz_from_chars_float/671f92218957fd9e98d68c9a551d9d1ed57f2d43 new file mode 100644 index 000000000..6ee599f2c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/671f92218957fd9e98d68c9a551d9d1ed57f2d43 @@ -0,0 +1 @@ +-801666666666666AAA.AEAAAA3333333333 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/67c29c5999b023cf07248a754ec8ed10b14294e7 b/fuzzing/seedcorpus/fuzz_from_chars_float/67c29c5999b023cf07248a754ec8ed10b14294e7 new file mode 100644 index 000000000..d3d0065d2 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/67c29c5999b023cf07248a754ec8ed10b14294e7 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/685113c55ed242683ab3086f0e2dc22d6458a4d8 b/fuzzing/seedcorpus/fuzz_from_chars_float/685113c55ed242683ab3086f0e2dc22d6458a4d8 new file mode 100644 index 000000000..115c00f0f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/685113c55ed242683ab3086f0e2dc22d6458a4d8 @@ -0,0 +1 @@ +52AAAAAAAAAAAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/685712a18363eadb819a6e0ee12f746f3ba71d91 b/fuzzing/seedcorpus/fuzz_from_chars_float/685712a18363eadb819a6e0ee12f746f3ba71d91 new file mode 100644 index 000000000..9b16bb3be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/685712a18363eadb819a6e0ee12f746f3ba71d91 @@ -0,0 +1 @@ +-AAAACAAAAAAAAAA2AAAAAAAAAAAAAAAAAaAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/68b7dbec81d866a834a39b80f25cb2c7371e12da b/fuzzing/seedcorpus/fuzz_from_chars_float/68b7dbec81d866a834a39b80f25cb2c7371e12da new file mode 100644 index 000000000..e1c3450ef --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/68b7dbec81d866a834a39b80f25cb2c7371e12da @@ -0,0 +1,2 @@ +-892733333333333333333333333333333A3A333AA.AAAAAAA3230833333330333333333332301.989685 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6a162ec680ae712687a9c2618f1a1d929d8f5295 b/fuzzing/seedcorpus/fuzz_from_chars_float/6a162ec680ae712687a9c2618f1a1d929d8f5295 new file mode 100644 index 000000000..3626cd6e3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6a162ec680ae712687a9c2618f1a1d929d8f5295 @@ -0,0 +1 @@ +11250000810555500008162062020608135 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6a35593c1a11ef6a4a889dc8f11510b1ddd20afa b/fuzzing/seedcorpus/fuzz_from_chars_float/6a35593c1a11ef6a4a889dc8f11510b1ddd20afa new file mode 100644 index 000000000..87a7fda00 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6a35593c1a11ef6a4a889dc8f11510b1ddd20afa @@ -0,0 +1 @@ +7P0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6abfd15a3391056e46eb8ebba3502b35515a9387 b/fuzzing/seedcorpus/fuzz_from_chars_float/6abfd15a3391056e46eb8ebba3502b35515a9387 new file mode 100644 index 000000000..493198810 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6abfd15a3391056e46eb8ebba3502b35515a9387 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>> >>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6b435d93ab38d582cac090770ced3bd99aa32b82 b/fuzzing/seedcorpus/fuzz_from_chars_float/6b435d93ab38d582cac090770ced3bd99aa32b82 new file mode 100644 index 000000000..756a6225d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6b435d93ab38d582cac090770ced3bd99aa32b82 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAA3333333333A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6c4ef913e502315b00b6d486dfe334b31986363f b/fuzzing/seedcorpus/fuzz_from_chars_float/6c4ef913e502315b00b6d486dfe334b31986363f new file mode 100644 index 000000000..765de7092 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6c4ef913e502315b00b6d486dfe334b31986363f @@ -0,0 +1 @@ +80927135514190415 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6d6b27b81ad60c50aaa15a112e346ade4169b7f0 b/fuzzing/seedcorpus/fuzz_from_chars_float/6d6b27b81ad60c50aaa15a112e346ade4169b7f0 new file mode 100644 index 000000000..fb7a12d8a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6d6b27b81ad60c50aaa15a112e346ade4169b7f0 @@ -0,0 +1 @@ +3P-500336 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6dcd4ce23d88e2ee9568ba546c007c63d9131c1b b/fuzzing/seedcorpus/fuzz_from_chars_float/6dcd4ce23d88e2ee9568ba546c007c63d9131c1b new file mode 100644 index 000000000..8c7e5a667 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6dcd4ce23d88e2ee9568ba546c007c63d9131c1b @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6e8a50c6879b20185e61891119bea0a543e79181 b/fuzzing/seedcorpus/fuzz_from_chars_float/6e8a50c6879b20185e61891119bea0a543e79181 new file mode 100644 index 000000000..9bff6a45e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6e8a50c6879b20185e61891119bea0a543e79181 @@ -0,0 +1 @@ +000222222222222222222222222222222222222223.......................................................>...... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6ed79d5585b903d779485d751ce9c32edda1d110 b/fuzzing/seedcorpus/fuzz_from_chars_float/6ed79d5585b903d779485d751ce9c32edda1d110 new file mode 100644 index 000000000..68509ee2a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6ed79d5585b903d779485d751ce9c32edda1d110 @@ -0,0 +1 @@ +-80900000017876066794902738262P33338 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6edc6604c23f2de43665e570d0feae43c476cd70 b/fuzzing/seedcorpus/fuzz_from_chars_float/6edc6604c23f2de43665e570d0feae43c476cd70 new file mode 100644 index 000000000..6ebc96fbf Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/6edc6604c23f2de43665e570d0feae43c476cd70 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6fbc0533eb27c30ebf9e6fd595b94a7495361545 b/fuzzing/seedcorpus/fuzz_from_chars_float/6fbc0533eb27c30ebf9e6fd595b94a7495361545 new file mode 100644 index 000000000..c6e2f1b1d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6fbc0533eb27c30ebf9e6fd595b94a7495361545 @@ -0,0 +1 @@ +-111110000000990153299e8222 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/6fca55ca3c828a46bfe96a10e69f572b61ce540c b/fuzzing/seedcorpus/fuzz_from_chars_float/6fca55ca3c828a46bfe96a10e69f572b61ce540c new file mode 100644 index 000000000..586886e56 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/6fca55ca3c828a46bfe96a10e69f572b61ce540c @@ -0,0 +1 @@ +IN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/70b6585d94d3f70fdac94f00a434032b52794be1 b/fuzzing/seedcorpus/fuzz_from_chars_float/70b6585d94d3f70fdac94f00a434032b52794be1 new file mode 100644 index 000000000..9fbe1b1c4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/70b6585d94d3f70fdac94f00a434032b52794be1 @@ -0,0 +1 @@ +9999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/71477ad34f78f9173cfd012564b54c345a5aaf15 b/fuzzing/seedcorpus/fuzz_from_chars_float/71477ad34f78f9173cfd012564b54c345a5aaf15 new file mode 100644 index 000000000..329201205 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/71477ad34f78f9173cfd012564b54c345a5aaf15 @@ -0,0 +1 @@ +-AAAAAAAAAAA.AAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/714c267b00c905e3306e25ee38c2b764bbcb5a28 b/fuzzing/seedcorpus/fuzz_from_chars_float/714c267b00c905e3306e25ee38c2b764bbcb5a28 new file mode 100644 index 000000000..82fa42a3d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/714c267b00c905e3306e25ee38c2b764bbcb5a28 @@ -0,0 +1 @@ +80927273623A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/71dc91722190631ad0e41846cbb45ee21e8b96d4 b/fuzzing/seedcorpus/fuzz_from_chars_float/71dc91722190631ad0e41846cbb45ee21e8b96d4 new file mode 100644 index 000000000..564d25762 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/71dc91722190631ad0e41846cbb45ee21e8b96d4 @@ -0,0 +1 @@ +4e843 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/721f69b49a205da3c01f1467f8ab38933bd5d6a4 b/fuzzing/seedcorpus/fuzz_from_chars_float/721f69b49a205da3c01f1467f8ab38933bd5d6a4 new file mode 100644 index 000000000..0707bf723 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/721f69b49a205da3c01f1467f8ab38933bd5d6a4 @@ -0,0 +1 @@ +8E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/733f38c3e43f1da8c315bbe81cc0804756e0ed2c b/fuzzing/seedcorpus/fuzz_from_chars_float/733f38c3e43f1da8c315bbe81cc0804756e0ed2c new file mode 100644 index 000000000..b7baad0ab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/733f38c3e43f1da8c315bbe81cc0804756e0ed2c @@ -0,0 +1 @@ +-8092733333333333333................. diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/742d6b624665e7c7d1cc7afbb1d324a99f14889e b/fuzzing/seedcorpus/fuzz_from_chars_float/742d6b624665e7c7d1cc7afbb1d324a99f14889e new file mode 100644 index 000000000..dbf6510a8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/742d6b624665e7c7d1cc7afbb1d324a99f14889e @@ -0,0 +1 @@ +8e96 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/74fa38aa9d22f84243d274020cf88d122f344cde b/fuzzing/seedcorpus/fuzz_from_chars_float/74fa38aa9d22f84243d274020cf88d122f344cde new file mode 100644 index 000000000..9ce1343ca Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/74fa38aa9d22f84243d274020cf88d122f344cde differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/75650f7922fba3f08f15b40d89099e5767324e28 b/fuzzing/seedcorpus/fuzz_from_chars_float/75650f7922fba3f08f15b40d89099e5767324e28 new file mode 100644 index 000000000..fae02ed9d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/75650f7922fba3f08f15b40d89099e5767324e28 @@ -0,0 +1 @@ +NAN(E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/762a51fd905259c09355fea198e33da38cff6ef7 b/fuzzing/seedcorpus/fuzz_from_chars_float/762a51fd905259c09355fea198e33da38cff6ef7 new file mode 100644 index 000000000..c9e8802c8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/762a51fd905259c09355fea198e33da38cff6ef7 @@ -0,0 +1 @@ +809272365973 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/76ba3fb2820ef69d08db56c9aa1ca26b95fe864a b/fuzzing/seedcorpus/fuzz_from_chars_float/76ba3fb2820ef69d08db56c9aa1ca26b95fe864a new file mode 100644 index 000000000..fb37e4552 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/76ba3fb2820ef69d08db56c9aa1ca26b95fe864a @@ -0,0 +1 @@ +21e350p551 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/778523f924ec4549ae24a634f04c330f8819da07 b/fuzzing/seedcorpus/fuzz_from_chars_float/778523f924ec4549ae24a634f04c330f8819da07 new file mode 100644 index 000000000..cee0a1282 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/778523f924ec4549ae24a634f04c330f8819da07 @@ -0,0 +1,28 @@ +-0.7 +9e-265 +85e-37 +623e+10251086569.8071456 +-5332617826=3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-9653912497.382019 +94997225114.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.8071456 +-5332617826.3962755 +-552968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/788afec8d4391b700488fd2cd5ae623de364c9d0 b/fuzzing/seedcorpus/fuzz_from_chars_float/788afec8d4391b700488fd2cd5ae623de364c9d0 new file mode 100644 index 000000000..ba354e925 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/788afec8d4391b700488fd2cd5ae623de364c9d0 @@ -0,0 +1 @@ +8956878AAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7938a67daa2cdf4091d133e8be8266124cc7151a b/fuzzing/seedcorpus/fuzz_from_chars_float/7938a67daa2cdf4091d133e8be8266124cc7151a new file mode 100644 index 000000000..c7cd1a507 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7938a67daa2cdf4091d133e8be8266124cc7151a @@ -0,0 +1 @@ +89^ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7ab9e9a0a3d66451debde80d42f536963d865396 b/fuzzing/seedcorpus/fuzz_from_chars_float/7ab9e9a0a3d66451debde80d42f536963d865396 new file mode 100644 index 000000000..efe58a684 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7ab9e9a0a3d66451debde80d42f536963d865396 @@ -0,0 +1 @@ +1e8483 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7ae6918e80dbdee7f84f12004ab67019b23636dc b/fuzzing/seedcorpus/fuzz_from_chars_float/7ae6918e80dbdee7f84f12004ab67019b23636dc new file mode 100644 index 000000000..c9bebd82b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7ae6918e80dbdee7f84f12004ab67019b23636dc @@ -0,0 +1 @@ +4A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7c4d33785daa5c2370201ffa236b427aa37c9996 b/fuzzing/seedcorpus/fuzz_from_chars_float/7c4d33785daa5c2370201ffa236b427aa37c9996 new file mode 100644 index 000000000..00b15c0a3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7c4d33785daa5c2370201ffa236b427aa37c9996 @@ -0,0 +1 @@ +& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7ef8aa6a336b4a7122031d713f383ffbbe5fac93 b/fuzzing/seedcorpus/fuzz_from_chars_float/7ef8aa6a336b4a7122031d713f383ffbbe5fac93 new file mode 100644 index 000000000..cd571f464 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7ef8aa6a336b4a7122031d713f383ffbbe5fac93 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7f6abc748a46d75876b859cb3914093bbb914b46 b/fuzzing/seedcorpus/fuzz_from_chars_float/7f6abc748a46d75876b859cb3914093bbb914b46 new file mode 100644 index 000000000..d6d88545e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7f6abc748a46d75876b859cb3914093bbb914b46 @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAA810AAP \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7f92f2f402661a00c3ebe9a289fe1b013e4a53b3 b/fuzzing/seedcorpus/fuzz_from_chars_float/7f92f2f402661a00c3ebe9a289fe1b013e4a53b3 new file mode 100644 index 000000000..299f6cd70 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7f92f2f402661a00c3ebe9a289fe1b013e4a53b3 @@ -0,0 +1 @@ +-00000000000J \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/7fa430e46d9b4a7c38391545fe6203ee862c74fb b/fuzzing/seedcorpus/fuzz_from_chars_float/7fa430e46d9b4a7c38391545fe6203ee862c74fb new file mode 100644 index 000000000..f2436f59b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/7fa430e46d9b4a7c38391545fe6203ee862c74fb @@ -0,0 +1 @@ +7E-3 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/81657ee0dd500c523685eade4de2e959a0e9cc8a b/fuzzing/seedcorpus/fuzz_from_chars_float/81657ee0dd500c523685eade4de2e959a0e9cc8a new file mode 100644 index 000000000..a64fc1e04 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/81657ee0dd500c523685eade4de2e959a0e9cc8a @@ -0,0 +1 @@ +-80927333333AAAAAAAAAA.AAAAAA333333333333333333333333333333333333-8+ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/81c60e095088f80a5ae9276c977a2114790f8e82 b/fuzzing/seedcorpus/fuzz_from_chars_float/81c60e095088f80a5ae9276c977a2114790f8e82 new file mode 100644 index 000000000..a9bc489b6 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/81c60e095088f80a5ae9276c977a2114790f8e82 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/81ed06f83e3cfcfa5e42e1c4ae1c77f20a325335 b/fuzzing/seedcorpus/fuzz_from_chars_float/81ed06f83e3cfcfa5e42e1c4ae1c77f20a325335 new file mode 100644 index 000000000..6aba0683c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/81ed06f83e3cfcfa5e42e1c4ae1c77f20a325335 @@ -0,0 +1 @@ +AP666 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/82dae6945628219242e0ef5b0b90269178620377 b/fuzzing/seedcorpus/fuzz_from_chars_float/82dae6945628219242e0ef5b0b90269178620377 new file mode 100644 index 000000000..45a3f7509 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/82dae6945628219242e0ef5b0b90269178620377 @@ -0,0 +1 @@ +80927333333333333333333333333333333AAA.AAAAAA33333333333333333333330000000000000030000000060000] diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/82f4f71da5357c9df8fd44b6f3994a8e366588a1 b/fuzzing/seedcorpus/fuzz_from_chars_float/82f4f71da5357c9df8fd44b6f3994a8e366588a1 new file mode 100644 index 000000000..72b2548ab Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/82f4f71da5357c9df8fd44b6f3994a8e366588a1 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/831694d1ec1c0dcc79c3c8514e15a3018dc800a1 b/fuzzing/seedcorpus/fuzz_from_chars_float/831694d1ec1c0dcc79c3c8514e15a3018dc800a1 new file mode 100644 index 000000000..730efc96a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/831694d1ec1c0dcc79c3c8514e15a3018dc800a1 @@ -0,0 +1 @@ +-80927333333333333333333333333333333AAA.AAAAAA33333333333333A33333333333333333333333333333333333A3333333333333333333333333333A33333333333333333333333333333A3333333333335 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/84ae30c44d6426c2e842a3df6e608688665b4bd9 b/fuzzing/seedcorpus/fuzz_from_chars_float/84ae30c44d6426c2e842a3df6e608688665b4bd9 new file mode 100644 index 000000000..234c1c091 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/84ae30c44d6426c2e842a3df6e608688665b4bd9 @@ -0,0 +1 @@ +8P560 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8544c528fde104908467348a76570a4c7a94475e b/fuzzing/seedcorpus/fuzz_from_chars_float/8544c528fde104908467348a76570a4c7a94475e new file mode 100644 index 000000000..f2e38cce3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8544c528fde104908467348a76570a4c7a94475e @@ -0,0 +1 @@ +80927230318419 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/85e53271e14006f0265921d02d4d736cdc580b0b b/fuzzing/seedcorpus/fuzz_from_chars_float/85e53271e14006f0265921d02d4d736cdc580b0b new file mode 100644 index 000000000..ce542efaa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/85e53271e14006f0265921d02d4d736cdc580b0b @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/86e32e4263ed3baeabcaf1461f295270dd14ee4a b/fuzzing/seedcorpus/fuzz_from_chars_float/86e32e4263ed3baeabcaf1461f295270dd14ee4a new file mode 100644 index 000000000..9dab087b2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/86e32e4263ed3baeabcaf1461f295270dd14ee4a @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7AA 02> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/896471348ba613b126ee4a9ec89364164d1a5336 b/fuzzing/seedcorpus/fuzz_from_chars_float/896471348ba613b126ee4a9ec89364164d1a5336 new file mode 100644 index 000000000..4ca353d30 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/896471348ba613b126ee4a9ec89364164d1a5336 @@ -0,0 +1 @@ +.427503102eAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/89e12b7118b2e5b0609715cd385754c130c8bdfb b/fuzzing/seedcorpus/fuzz_from_chars_float/89e12b7118b2e5b0609715cd385754c130c8bdfb new file mode 100644 index 000000000..73319cd85 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/89e12b7118b2e5b0609715cd385754c130c8bdfb @@ -0,0 +1 @@ +NAN(s \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8b915b051e58d691ef802b823f29f83c208630a8 b/fuzzing/seedcorpus/fuzz_from_chars_float/8b915b051e58d691ef802b823f29f83c208630a8 new file mode 100644 index 000000000..88ba3e4a8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8b915b051e58d691ef802b823f29f83c208630a8 @@ -0,0 +1 @@ +-80927300000003E000 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8dc8671f5410de9a659163f22fb9daa55639ab2c b/fuzzing/seedcorpus/fuzz_from_chars_float/8dc8671f5410de9a659163f22fb9daa55639ab2c new file mode 100644 index 000000000..db8d9c85d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8dc8671f5410de9a659163f22fb9daa55639ab2c @@ -0,0 +1 @@ +865683 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8eba81f4291d932500839472fca118a93b94343b b/fuzzing/seedcorpus/fuzz_from_chars_float/8eba81f4291d932500839472fca118a93b94343b new file mode 100644 index 000000000..f857ca7d0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8eba81f4291d932500839472fca118a93b94343b @@ -0,0 +1 @@ +8e344080 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8f883d9561b9257a4312c77d87529a41d4870593 b/fuzzing/seedcorpus/fuzz_from_chars_float/8f883d9561b9257a4312c77d87529a41d4870593 new file mode 100644 index 000000000..aaefc0b74 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8f883d9561b9257a4312c77d87529a41d4870593 @@ -0,0 +1,2 @@ +-80927333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333AAAAAA.AAAAAAAAAA333333333333333335 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/8fa26c9a55706764f98e70c2bf05cbfe89b235cb b/fuzzing/seedcorpus/fuzz_from_chars_float/8fa26c9a55706764f98e70c2bf05cbfe89b235cb new file mode 100644 index 000000000..59eeb2269 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/8fa26c9a55706764f98e70c2bf05cbfe89b235cb @@ -0,0 +1 @@ +.e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/902b09a4955c58161a4adea32b5b3b8754f1c3ff b/fuzzing/seedcorpus/fuzz_from_chars_float/902b09a4955c58161a4adea32b5b3b8754f1c3ff new file mode 100644 index 000000000..1f10efd8f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/902b09a4955c58161a4adea32b5b3b8754f1c3ff @@ -0,0 +1 @@ +AP20133A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/907942e9895f73613292555c297e26560baba236 b/fuzzing/seedcorpus/fuzz_from_chars_float/907942e9895f73613292555c297e26560baba236 new file mode 100644 index 000000000..f6ac6f6e5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/907942e9895f73613292555c297e26560baba236 @@ -0,0 +1,3 @@ +-0.7 +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>52968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9108c1fc03ff53527f9d9de94d9c151e697e154d b/fuzzing/seedcorpus/fuzz_from_chars_float/9108c1fc03ff53527f9d9de94d9c151e697e154d new file mode 100644 index 000000000..a68f4454d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9108c1fc03ff53527f9d9de94d9c151e697e154d @@ -0,0 +1 @@ +AAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9115549dfe3bc13242447cfbb561ce5ec8ac7f82 b/fuzzing/seedcorpus/fuzz_from_chars_float/9115549dfe3bc13242447cfbb561ce5ec8ac7f82 new file mode 100644 index 000000000..2a5c553be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9115549dfe3bc13242447cfbb561ce5ec8ac7f82 @@ -0,0 +1 @@ +.E-809673 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/912c51f09275724d63cfd19ab64a3ab18ee4961a b/fuzzing/seedcorpus/fuzz_from_chars_float/912c51f09275724d63cfd19ab64a3ab18ee4961a new file mode 100644 index 000000000..bee7403e1 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/912c51f09275724d63cfd19ab64a3ab18ee4961a differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/916f22abedc89a8c1940267551570de709b17e62 b/fuzzing/seedcorpus/fuzz_from_chars_float/916f22abedc89a8c1940267551570de709b17e62 new file mode 100644 index 000000000..090b94059 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/916f22abedc89a8c1940267551570de709b17e62 @@ -0,0 +1 @@ +AEAAAAAAAAAbA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9207e5d8390947970421e4aa220e13570c0888f8 b/fuzzing/seedcorpus/fuzz_from_chars_float/9207e5d8390947970421e4aa220e13570c0888f8 new file mode 100644 index 000000000..0c60f2987 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9207e5d8390947970421e4aa220e13570c0888f8 @@ -0,0 +1 @@ +NAN(S \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/935f25522a6ba6c3d28c62c372878c790b5476cf b/fuzzing/seedcorpus/fuzz_from_chars_float/935f25522a6ba6c3d28c62c372878c790b5476cf new file mode 100644 index 000000000..ad8d2e240 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/935f25522a6ba6c3d28c62c372878c790b5476cf @@ -0,0 +1 @@ +99999999999999999999999999996999999380P2665694> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/937179be0da46f96b36325edf9ac4ab7d3d22058 b/fuzzing/seedcorpus/fuzz_from_chars_float/937179be0da46f96b36325edf9ac4ab7d3d22058 new file mode 100644 index 000000000..82e5533b1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/937179be0da46f96b36325edf9ac4ab7d3d22058 @@ -0,0 +1 @@ +2e340340 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/94cead5cb5147b73eb72063f0d77b500208f7feb b/fuzzing/seedcorpus/fuzz_from_chars_float/94cead5cb5147b73eb72063f0d77b500208f7feb new file mode 100644 index 000000000..a7841c884 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/94cead5cb5147b73eb72063f0d77b500208f7feb @@ -0,0 +1 @@ +8092723659236599236. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9564b71220ce109d5ead6fba4d9c0f50ce395c48 b/fuzzing/seedcorpus/fuzz_from_chars_float/9564b71220ce109d5ead6fba4d9c0f50ce395c48 new file mode 100644 index 000000000..4f2686cef --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9564b71220ce109d5ead6fba4d9c0f50ce395c48 @@ -0,0 +1 @@ +-3865972365923930.996.09225.996.09235..0922.33A.AAA332.36.993003. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/959257cc33fd136f7ba7fe6a7e218cdd2837998a b/fuzzing/seedcorpus/fuzz_from_chars_float/959257cc33fd136f7ba7fe6a7e218cdd2837998a new file mode 100644 index 000000000..77167ea0f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/959257cc33fd136f7ba7fe6a7e218cdd2837998a @@ -0,0 +1 @@ +-888888888888888888888888888884444444444 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9599485ce362c35d763cceb6409d9bc8809903e8 b/fuzzing/seedcorpus/fuzz_from_chars_float/9599485ce362c35d763cceb6409d9bc8809903e8 new file mode 100644 index 000000000..d015413e2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9599485ce362c35d763cceb6409d9bc8809903e8 @@ -0,0 +1 @@ +80922365922365923 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/96e388a6c525d6bc1480dc18f367a8a21d9558d8 b/fuzzing/seedcorpus/fuzz_from_chars_float/96e388a6c525d6bc1480dc18f367a8a21d9558d8 new file mode 100644 index 000000000..18c5be6f0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/96e388a6c525d6bc1480dc18f367a8a21d9558d8 @@ -0,0 +1 @@ +-81333333e333332.3333.s \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/974d07959845cef7a8fbe96263dcb9c084436967 b/fuzzing/seedcorpus/fuzz_from_chars_float/974d07959845cef7a8fbe96263dcb9c084436967 new file mode 100644 index 000000000..b1e67c449 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/974d07959845cef7a8fbe96263dcb9c084436967 @@ -0,0 +1 @@ +200063838474459722 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9754374c6d742f0b2a757d90017e458126cf44de b/fuzzing/seedcorpus/fuzz_from_chars_float/9754374c6d742f0b2a757d90017e458126cf44de new file mode 100644 index 000000000..d094bb58a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9754374c6d742f0b2a757d90017e458126cf44de @@ -0,0 +1 @@ +225e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/992a62018b557b9479d1c519b7c8c0c6692bc4e9 b/fuzzing/seedcorpus/fuzz_from_chars_float/992a62018b557b9479d1c519b7c8c0c6692bc4e9 new file mode 100644 index 000000000..74515541f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/992a62018b557b9479d1c519b7c8c0c6692bc4e9 @@ -0,0 +1 @@ +A) \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/993f5552e5f6e434f503daf38d5592c00c5d36fe b/fuzzing/seedcorpus/fuzz_from_chars_float/993f5552e5f6e434f503daf38d5592c00c5d36fe new file mode 100644 index 000000000..12d1ad074 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/993f5552e5f6e434f503daf38d5592c00c5d36fe @@ -0,0 +1 @@ +5.656200e381 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/999a96e8194dd62ee7f3782bbd2e357536f07dcd b/fuzzing/seedcorpus/fuzz_from_chars_float/999a96e8194dd62ee7f3782bbd2e357536f07dcd new file mode 100644 index 000000000..cd8f4bfb4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/999a96e8194dd62ee7f3782bbd2e357536f07dcd @@ -0,0 +1,26 @@ +-0.7 +9e-265 +85e-37 +623e+10251086569.8071456 +-5332617826=3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-9653912497.382019 +94997225194194.5556 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548226.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +.686867 +2709272301.989956 +4251086569.8071456 +-5332617826.3962755 +-552968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/999b921a227fc929b45ffedf22ff2fea1fe215f7 b/fuzzing/seedcorpus/fuzz_from_chars_float/999b921a227fc929b45ffedf22ff2fea1fe215f7 new file mode 100644 index 000000000..1d992170a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/999b921a227fc929b45ffedf22ff2fea1fe215f7 @@ -0,0 +1 @@ +3.00121940906561404244f3 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/99f84e401f471de4fc3f3e57d97d566accdc7088 b/fuzzing/seedcorpus/fuzz_from_chars_float/99f84e401f471de4fc3f3e57d97d566accdc7088 new file mode 100644 index 000000000..72ecfd2ae --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/99f84e401f471de4fc3f3e57d97d566accdc7088 @@ -0,0 +1 @@ +8565620000A222222222222222222202350033.2.3.......................................................>.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9a8fedd43a5380a14bf3d826c5cb828e6f1d079e b/fuzzing/seedcorpus/fuzz_from_chars_float/9a8fedd43a5380a14bf3d826c5cb828e6f1d079e new file mode 100644 index 000000000..3e34aed6b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9a8fedd43a5380a14bf3d826c5cb828e6f1d079e @@ -0,0 +1 @@ +NAn \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9bde9722059e9e09bf3e32fc7d95d39a96ebf11f b/fuzzing/seedcorpus/fuzz_from_chars_float/9bde9722059e9e09bf3e32fc7d95d39a96ebf11f new file mode 100644 index 000000000..0d59798ea --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9bde9722059e9e09bf3e32fc7d95d39a96ebf11f @@ -0,0 +1 @@ +.0001 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9d23af5527ba486f99c8fe850836c29271c81a51 b/fuzzing/seedcorpus/fuzz_from_chars_float/9d23af5527ba486f99c8fe850836c29271c81a51 new file mode 100644 index 000000000..55cf894c2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9d23af5527ba486f99c8fe850836c29271c81a51 @@ -0,0 +1 @@ +-81000000920178DDDDD+ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9d53fd1b4491f30b05d9c5a87e7cea825b579796 b/fuzzing/seedcorpus/fuzz_from_chars_float/9d53fd1b4491f30b05d9c5a87e7cea825b579796 new file mode 100644 index 000000000..983e1f5c5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9d53fd1b4491f30b05d9c5a87e7cea825b579796 @@ -0,0 +1 @@ +NAN% \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9d849f5d38b1476595c1a60b834723743a6c581e b/fuzzing/seedcorpus/fuzz_from_chars_float/9d849f5d38b1476595c1a60b834723743a6c581e new file mode 100644 index 000000000..f864efd49 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9d849f5d38b1476595c1a60b834723743a6c581e @@ -0,0 +1,2 @@ +-0.4 +>>>>>>>>>>1>>>>>>>>>>>>>>>>>>>>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9e0af5d47a0ee297a5595e88bf0c8706f0b278e1 b/fuzzing/seedcorpus/fuzz_from_chars_float/9e0af5d47a0ee297a5595e88bf0c8706f0b278e1 new file mode 100644 index 000000000..2b41bf489 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9e0af5d47a0ee297a5595e88bf0c8706f0b278e1 @@ -0,0 +1 @@ +.334351155435115551a \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/9f1bcd7c9d10c9e8e43df72c03d485a8db1582bf b/fuzzing/seedcorpus/fuzz_from_chars_float/9f1bcd7c9d10c9e8e43df72c03d485a8db1582bf new file mode 100644 index 000000000..d62497a36 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/9f1bcd7c9d10c9e8e43df72c03d485a8db1582bf @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a09c8f3200f5698454137def0de59d7bd1ed554e b/fuzzing/seedcorpus/fuzz_from_chars_float/a09c8f3200f5698454137def0de59d7bd1ed554e new file mode 100644 index 000000000..f219ce9ca --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a09c8f3200f5698454137def0de59d7bd1ed554e @@ -0,0 +1 @@ +-AAACAAAAACAAAAAAA.AA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a0de4f6b74d075f150f606c0ccc1c2f92e5f5072 b/fuzzing/seedcorpus/fuzz_from_chars_float/a0de4f6b74d075f150f606c0ccc1c2f92e5f5072 new file mode 100644 index 000000000..c22ee4433 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a0de4f6b74d075f150f606c0ccc1c2f92e5f5072 @@ -0,0 +1 @@ +-AAAAAA3AAAAEAAA8E7E> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a33798865cd720f48b92ce176cc2c0cea09a4481 b/fuzzing/seedcorpus/fuzz_from_chars_float/a33798865cd720f48b92ce176cc2c0cea09a4481 new file mode 100644 index 000000000..312c00edd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a33798865cd720f48b92ce176cc2c0cea09a4481 @@ -0,0 +1 @@ +809271355141904B \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a349088978b5eb92a57e61be5cf82dbb4774e1a9 b/fuzzing/seedcorpus/fuzz_from_chars_float/a349088978b5eb92a57e61be5cf82dbb4774e1a9 new file mode 100644 index 000000000..7a7f86d15 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a349088978b5eb92a57e61be5cf82dbb4774e1a9 @@ -0,0 +1 @@ +.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 b/fuzzing/seedcorpus/fuzz_from_chars_float/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 new file mode 100644 index 000000000..7b9d05c74 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 @@ -0,0 +1 @@ +.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a41344ad50c258c65473b734b6470454ff060b28 b/fuzzing/seedcorpus/fuzz_from_chars_float/a41344ad50c258c65473b734b6470454ff060b28 new file mode 100644 index 000000000..4e359517b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a41344ad50c258c65473b734b6470454ff060b28 @@ -0,0 +1 @@ +-80927333333333363366333335 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a454ac5d276ed12a9b40a6ac4a567a714b2234d3 b/fuzzing/seedcorpus/fuzz_from_chars_float/a454ac5d276ed12a9b40a6ac4a567a714b2234d3 new file mode 100644 index 000000000..94db1426f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a454ac5d276ed12a9b40a6ac4a567a714b2234d3 @@ -0,0 +1 @@ +98200842810203888 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a4fce295027af31d38ca3cdf2d8a8da2d7c72e8c b/fuzzing/seedcorpus/fuzz_from_chars_float/a4fce295027af31d38ca3cdf2d8a8da2d7c72e8c new file mode 100644 index 000000000..6f8d62648 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a4fce295027af31d38ca3cdf2d8a8da2d7c72e8c @@ -0,0 +1,192 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-96875494525.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835517.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8+363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a6d34b65bced3e9a0beb59f8f2dd19f537bc149b b/fuzzing/seedcorpus/fuzz_from_chars_float/a6d34b65bced3e9a0beb59f8f2dd19f537bc149b new file mode 100644 index 000000000..bd8cef3b0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a6d34b65bced3e9a0beb59f8f2dd19f537bc149b @@ -0,0 +1 @@ +-AAAAA8AAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a7edbfa9dfd4be11ea5809fc196caf2ab794a510 b/fuzzing/seedcorpus/fuzz_from_chars_float/a7edbfa9dfd4be11ea5809fc196caf2ab794a510 new file mode 100644 index 000000000..c37e52def --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a7edbfa9dfd4be11ea5809fc196caf2ab794a510 @@ -0,0 +1 @@ +33352673e89673202.96.0P-08 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c b/fuzzing/seedcorpus/fuzz_from_chars_float/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c new file mode 100644 index 000000000..9b26e9b10 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c @@ -0,0 +1 @@ ++ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/aa3dfef42e0c22b5d2e5e3638c1b61b47bbb10da b/fuzzing/seedcorpus/fuzz_from_chars_float/aa3dfef42e0c22b5d2e5e3638c1b61b47bbb10da new file mode 100644 index 000000000..a28aa9a0f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/aa3dfef42e0c22b5d2e5e3638c1b61b47bbb10da @@ -0,0 +1 @@ +inf \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/aa65f46322c321f5f559fb751635ac2bed28042e b/fuzzing/seedcorpus/fuzz_from_chars_float/aa65f46322c321f5f559fb751635ac2bed28042e new file mode 100644 index 000000000..9bdb55ad8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/aa65f46322c321f5f559fb751635ac2bed28042e @@ -0,0 +1 @@ +809000000178DDDDDDD \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/aad060eefe284feafef2d9168723d6eff61f74d1 b/fuzzing/seedcorpus/fuzz_from_chars_float/aad060eefe284feafef2d9168723d6eff61f74d1 new file mode 100644 index 000000000..97a031a91 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/aad060eefe284feafef2d9168723d6eff61f74d1 @@ -0,0 +1 @@ +5P-500 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ab17f7cfb21242bec2d60ea9a8bafc1fde6bc777 b/fuzzing/seedcorpus/fuzz_from_chars_float/ab17f7cfb21242bec2d60ea9a8bafc1fde6bc777 new file mode 100644 index 000000000..a2e65473a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ab17f7cfb21242bec2d60ea9a8bafc1fde6bc777 @@ -0,0 +1 @@ +-729023233337393316P6669 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ab6e6ee9218605d05bc7c99977938462c500bd04 b/fuzzing/seedcorpus/fuzz_from_chars_float/ab6e6ee9218605d05bc7c99977938462c500bd04 new file mode 100644 index 000000000..7284a8a23 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ab6e6ee9218605d05bc7c99977938462c500bd04 @@ -0,0 +1 @@ +7P0 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ac235da738f22d8f3c70ff857333a3186d7de005 b/fuzzing/seedcorpus/fuzz_from_chars_float/ac235da738f22d8f3c70ff857333a3186d7de005 new file mode 100644 index 000000000..a6b43121e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ac235da738f22d8f3c70ff857333a3186d7de005 @@ -0,0 +1 @@ +92A23AA6A2A5A87A7 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/acf96c2596f87440bef8e4a0bb14944246f4b765 b/fuzzing/seedcorpus/fuzz_from_chars_float/acf96c2596f87440bef8e4a0bb14944246f4b765 new file mode 100644 index 000000000..8245b898b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/acf96c2596f87440bef8e4a0bb14944246f4b765 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/acfef08bc8fec8699863973e2ace2db585dc6418 b/fuzzing/seedcorpus/fuzz_from_chars_float/acfef08bc8fec8699863973e2ace2db585dc6418 new file mode 100644 index 000000000..63f4a3632 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/acfef08bc8fec8699863973e2ace2db585dc6418 @@ -0,0 +1 @@ +8965688 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ad9d5513327195fc3e285bfae098ab4360e383f9 b/fuzzing/seedcorpus/fuzz_from_chars_float/ad9d5513327195fc3e285bfae098ab4360e383f9 new file mode 100644 index 000000000..7ad8ddbc5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ad9d5513327195fc3e285bfae098ab4360e383f9 @@ -0,0 +1 @@ +00e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ae01f2268cd02122607f79fd57f59c37fd80e6bf b/fuzzing/seedcorpus/fuzz_from_chars_float/ae01f2268cd02122607f79fd57f59c37fd80e6bf new file mode 100644 index 000000000..d76a7e078 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ae01f2268cd02122607f79fd57f59c37fd80e6bf @@ -0,0 +1 @@ +e0376923659092.99963. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ae654a7a502cb150c07b3395af75d68e0d6e690a b/fuzzing/seedcorpus/fuzz_from_chars_float/ae654a7a502cb150c07b3395af75d68e0d6e690a new file mode 100644 index 000000000..8f4d2043f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ae654a7a502cb150c07b3395af75d68e0d6e690a @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AA0An> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/aed9e17f828d0a91215e3ff339c0f20d8a082a3e b/fuzzing/seedcorpus/fuzz_from_chars_float/aed9e17f828d0a91215e3ff339c0f20d8a082a3e new file mode 100644 index 000000000..2a37d69c9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/aed9e17f828d0a91215e3ff339c0f20d8a082a3e @@ -0,0 +1 @@ +NAN( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/aef36502d67b0520654deb764dd055a7e905cfdd b/fuzzing/seedcorpus/fuzz_from_chars_float/aef36502d67b0520654deb764dd055a7e905cfdd new file mode 100644 index 000000000..cdc9dea5c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/aef36502d67b0520654deb764dd055a7e905cfdd @@ -0,0 +1 @@ +In \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b080d2fff0092f4543b391a5bcab2f699c12dc72 b/fuzzing/seedcorpus/fuzz_from_chars_float/b080d2fff0092f4543b391a5bcab2f699c12dc72 new file mode 100644 index 000000000..db85f981b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b080d2fff0092f4543b391a5bcab2f699c12dc72 @@ -0,0 +1 @@ +.3000104110401040000.41P51100 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b18e18a666ca09e5863cbdb7908cb0259c817f0f b/fuzzing/seedcorpus/fuzz_from_chars_float/b18e18a666ca09e5863cbdb7908cb0259c817f0f new file mode 100644 index 000000000..1513180a6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b18e18a666ca09e5863cbdb7908cb0259c817f0f @@ -0,0 +1 @@ +8E65P24A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b2525f113ee659a6ba80ef6a4691213cb5b24dfb b/fuzzing/seedcorpus/fuzz_from_chars_float/b2525f113ee659a6ba80ef6a4691213cb5b24dfb new file mode 100644 index 000000000..d8ebd4ee1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b2525f113ee659a6ba80ef6a4691213cb5b24dfb @@ -0,0 +1,117 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +205054263588366773474331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.73506319914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-96875494525.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8+363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b29c0faac5c708f379754f8f54a2a8e2170fdd18 b/fuzzing/seedcorpus/fuzz_from_chars_float/b29c0faac5c708f379754f8f54a2a8e2170fdd18 new file mode 100644 index 000000000..9687fc478 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b29c0faac5c708f379754f8f54a2a8e2170fdd18 @@ -0,0 +1 @@ +-53333383333333333333338333323333333320 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b50e36896663257112add25ee1976c5ad78f2066 b/fuzzing/seedcorpus/fuzz_from_chars_float/b50e36896663257112add25ee1976c5ad78f2066 new file mode 100644 index 000000000..817827725 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b50e36896663257112add25ee1976c5ad78f2066 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b51a60734da64be0e618bacbea2865a8a7dcd669 b/fuzzing/seedcorpus/fuzz_from_chars_float/b51a60734da64be0e618bacbea2865a8a7dcd669 new file mode 100644 index 000000000..2f94675b7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b51a60734da64be0e618bacbea2865a8a7dcd669 @@ -0,0 +1 @@ +N \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b5e3e1c4ef4c6a9c6fbe3f50736ff41ca752c608 b/fuzzing/seedcorpus/fuzz_from_chars_float/b5e3e1c4ef4c6a9c6fbe3f50736ff41ca752c608 new file mode 100644 index 000000000..50a28537b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b5e3e1c4ef4c6a9c6fbe3f50736ff41ca752c608 @@ -0,0 +1 @@ +-8000000000000000000000000000000000000000000000000000000061400000000000000006148914646-596A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b5ef95db5955b5cbc9f9b698ee254702cd24659a b/fuzzing/seedcorpus/fuzz_from_chars_float/b5ef95db5955b5cbc9f9b698ee254702cd24659a new file mode 100644 index 000000000..3ccd78151 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b5ef95db5955b5cbc9f9b698ee254702cd24659a @@ -0,0 +1 @@ +88092A272 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c b/fuzzing/seedcorpus/fuzz_from_chars_float/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c new file mode 100644 index 000000000..c22708346 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b6edd83bdcce8cc7693c1b59b0e8b183761402be b/fuzzing/seedcorpus/fuzz_from_chars_float/b6edd83bdcce8cc7693c1b59b0e8b183761402be new file mode 100644 index 000000000..93b59750f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b6edd83bdcce8cc7693c1b59b0e8b183761402be @@ -0,0 +1 @@ +-22222111111111111111112322222344454e82381P6656# \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b7c78db99c1ed041185b2c047ee52bd5983b5512 b/fuzzing/seedcorpus/fuzz_from_chars_float/b7c78db99c1ed041185b2c047ee52bd5983b5512 new file mode 100644 index 000000000..e05826fff Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/b7c78db99c1ed041185b2c047ee52bd5983b5512 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/b870f0d1b48a0ab9841d22726d1b99669b859a85 b/fuzzing/seedcorpus/fuzz_from_chars_float/b870f0d1b48a0ab9841d22726d1b99669b859a85 new file mode 100644 index 000000000..d12537c37 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/b870f0d1b48a0ab9841d22726d1b99669b859a85 @@ -0,0 +1 @@ +40e3848e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bad07d6328e697f1fcc0247e1e77c05e5a0b1b33 b/fuzzing/seedcorpus/fuzz_from_chars_float/bad07d6328e697f1fcc0247e1e77c05e5a0b1b33 new file mode 100644 index 000000000..06f65b4c4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/bad07d6328e697f1fcc0247e1e77c05e5a0b1b33 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.AAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bb12e2f7410d049debb978f5773ddeca5d9acce2 b/fuzzing/seedcorpus/fuzz_from_chars_float/bb12e2f7410d049debb978f5773ddeca5d9acce2 new file mode 100644 index 000000000..484dee61d Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/bb12e2f7410d049debb978f5773ddeca5d9acce2 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bbda8400a73a7caa0758fe706c6f43f0c11115c0 b/fuzzing/seedcorpus/fuzz_from_chars_float/bbda8400a73a7caa0758fe706c6f43f0c11115c0 new file mode 100644 index 000000000..39e15742c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/bbda8400a73a7caa0758fe706c6f43f0c11115c0 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bc95d60153038813bc7024abb8a68fd1e98eca43 b/fuzzing/seedcorpus/fuzz_from_chars_float/bc95d60153038813bc7024abb8a68fd1e98eca43 new file mode 100644 index 000000000..b20491855 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/bc95d60153038813bc7024abb8a68fd1e98eca43 @@ -0,0 +1,2 @@ +-8733333333333333733333373333333333331355e585 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bca129cd42a855700b1007828883d6af7d924103 b/fuzzing/seedcorpus/fuzz_from_chars_float/bca129cd42a855700b1007828883d6af7d924103 new file mode 100644 index 000000000..9413b63aa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/bca129cd42a855700b1007828883d6af7d924103 @@ -0,0 +1 @@ +5P- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/bdcfcc8bbc36bf188186e03ee61ff02c3485edee b/fuzzing/seedcorpus/fuzz_from_chars_float/bdcfcc8bbc36bf188186e03ee61ff02c3485edee new file mode 100644 index 000000000..eeba48459 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/bdcfcc8bbc36bf188186e03ee61ff02c3485edee @@ -0,0 +1 @@ +3A2AC \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c0b591642c8f440550323b82cd910b92a222b8e7 b/fuzzing/seedcorpus/fuzz_from_chars_float/c0b591642c8f440550323b82cd910b92a222b8e7 new file mode 100644 index 000000000..69c0eadf3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c0b591642c8f440550323b82cd910b92a222b8e7 @@ -0,0 +1 @@ +AAAAAAAAAA9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c11c3669da70f72a6dab34be3893ae8bda884c42 b/fuzzing/seedcorpus/fuzz_from_chars_float/c11c3669da70f72a6dab34be3893ae8bda884c42 new file mode 100644 index 000000000..a9c875c3b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c11c3669da70f72a6dab34be3893ae8bda884c42 @@ -0,0 +1 @@ +5e502 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c1dfd96eea8cc2b62785275bca38ac261256e278 b/fuzzing/seedcorpus/fuzz_from_chars_float/c1dfd96eea8cc2b62785275bca38ac261256e278 new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c1dfd96eea8cc2b62785275bca38ac261256e278 @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c1f7ba44659c80d404c753e9ea1d6e5c97da745b b/fuzzing/seedcorpus/fuzz_from_chars_float/c1f7ba44659c80d404c753e9ea1d6e5c97da745b new file mode 100644 index 000000000..6e2501c5f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c1f7ba44659c80d404c753e9ea1d6e5c97da745b @@ -0,0 +1 @@ +bdbb \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c3177023e34f57e4e69ce7c9aabc32aed535060b b/fuzzing/seedcorpus/fuzz_from_chars_float/c3177023e34f57e4e69ce7c9aabc32aed535060b new file mode 100644 index 000000000..a2f51efb7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c3177023e34f57e4e69ce7c9aabc32aed535060b @@ -0,0 +1 @@ +0000000000000000000000000000000000000000000iA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c4566f7d7e5c53aeef2d54a9a0452f698fa8052f b/fuzzing/seedcorpus/fuzz_from_chars_float/c4566f7d7e5c53aeef2d54a9a0452f698fa8052f new file mode 100644 index 000000000..a82e32b80 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c4566f7d7e5c53aeef2d54a9a0452f698fa8052f @@ -0,0 +1 @@ +AAA> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c47f9a5b51e401915d265e84f196cc9452c82275 b/fuzzing/seedcorpus/fuzz_from_chars_float/c47f9a5b51e401915d265e84f196cc9452c82275 new file mode 100644 index 000000000..af20c29ae --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c47f9a5b51e401915d265e84f196cc9452c82275 @@ -0,0 +1,138 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +205054263588366773474331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.73506319914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-96875494525.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835517.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8+363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c48260ca782c5fbc46c3b94d201ce2851d8e0215 b/fuzzing/seedcorpus/fuzz_from_chars_float/c48260ca782c5fbc46c3b94d201ce2851d8e0215 new file mode 100644 index 000000000..54bad4ddd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c48260ca782c5fbc46c3b94d201ce2851d8e0215 @@ -0,0 +1 @@ +.00000000000f \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c4aa4c3dd57776541f6f53190e7d5e1053779ace b/fuzzing/seedcorpus/fuzz_from_chars_float/c4aa4c3dd57776541f6f53190e7d5e1053779ace new file mode 100644 index 000000000..1261d9cd0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c4aa4c3dd57776541f6f53190e7d5e1053779ace @@ -0,0 +1 @@ +A.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c511758e0e3621704715ac307c8b5b23a7dfd0a5 b/fuzzing/seedcorpus/fuzz_from_chars_float/c511758e0e3621704715ac307c8b5b23a7dfd0a5 new file mode 100644 index 000000000..98518d4b5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c511758e0e3621704715ac307c8b5b23a7dfd0a5 @@ -0,0 +1,14 @@ +-0.7 +9e-265 +85e-37 +623e+10251086569.8#71456 +-5332617826=3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120146 +-965391249>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.8071456 +-5332617826.3962755 +-552968551308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c57b38d47aedad77f9bd447a502acf12713298ee b/fuzzing/seedcorpus/fuzz_from_chars_float/c57b38d47aedad77f9bd447a502acf12713298ee new file mode 100644 index 000000000..78faa7973 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c57b38d47aedad77f9bd447a502acf12713298ee @@ -0,0 +1 @@ +8E3279315P6660001 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c58f7bd5253440575ecd815e5adceec30af91790 b/fuzzing/seedcorpus/fuzz_from_chars_float/c58f7bd5253440575ecd815e5adceec30af91790 new file mode 100644 index 000000000..b83de5dab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c58f7bd5253440575ecd815e5adceec30af91790 @@ -0,0 +1 @@ +-825970035996.927236592365927225970035996.9272365923659272365923659E236.0965223729365992365923659E236.096522372936599236.99236. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c5c2cc072dcf881b5bf4cfc65d4a1e3a82a1cbe9 b/fuzzing/seedcorpus/fuzz_from_chars_float/c5c2cc072dcf881b5bf4cfc65d4a1e3a82a1cbe9 new file mode 100644 index 000000000..5e3b31929 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c5c2cc072dcf881b5bf4cfc65d4a1e3a82a1cbe9 @@ -0,0 +1 @@ +802337333333333333163333331666666664 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c61b77674524f1cbf87c0237629ddb934d26e20e b/fuzzing/seedcorpus/fuzz_from_chars_float/c61b77674524f1cbf87c0237629ddb934d26e20e new file mode 100644 index 000000000..27d9fcce3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c61b77674524f1cbf87c0237629ddb934d26e20e @@ -0,0 +1 @@ +IN` \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c63ae6dd4fc9f9dda66970e827d13f7c73fe841c b/fuzzing/seedcorpus/fuzz_from_chars_float/c63ae6dd4fc9f9dda66970e827d13f7c73fe841c new file mode 100644 index 000000000..ef6bce1d1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c63ae6dd4fc9f9dda66970e827d13f7c73fe841c @@ -0,0 +1 @@ +M \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c88cc7235823f7fbf64d57368249d4d0b077b80b b/fuzzing/seedcorpus/fuzz_from_chars_float/c88cc7235823f7fbf64d57368249d4d0b077b80b new file mode 100644 index 000000000..b5158eba5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c88cc7235823f7fbf64d57368249d4d0b077b80b @@ -0,0 +1 @@ +-.3004104110401040001.1P5115e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/c97c8626c6387ad10f970a22d859127343fd2a81 b/fuzzing/seedcorpus/fuzz_from_chars_float/c97c8626c6387ad10f970a22d859127343fd2a81 new file mode 100644 index 000000000..f1fde3ae4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/c97c8626c6387ad10f970a22d859127343fd2a81 @@ -0,0 +1 @@ +-802733333333333333333333333333AAAAAAAAA.AAAAAA000000000000000000000000000000000000000004440000000000000000000000001893444842AQ3327 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ca73ab65568cd125c2d27a22bbd9e863c10b675d b/fuzzing/seedcorpus/fuzz_from_chars_float/ca73ab65568cd125c2d27a22bbd9e863c10b675d new file mode 100644 index 000000000..b4158c40d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ca73ab65568cd125c2d27a22bbd9e863c10b675d @@ -0,0 +1 @@ +I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ca75e66a01a2b5b24f825f569d5ddeead3e50e4d b/fuzzing/seedcorpus/fuzz_from_chars_float/ca75e66a01a2b5b24f825f569d5ddeead3e50e4d new file mode 100644 index 000000000..50f5a8b1b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ca75e66a01a2b5b24f825f569d5ddeead3e50e4d @@ -0,0 +1 @@ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/cbc5193e0c009faf80614a3b5bb42ac27fd29851 b/fuzzing/seedcorpus/fuzz_from_chars_float/cbc5193e0c009faf80614a3b5bb42ac27fd29851 new file mode 100644 index 000000000..38e2c8898 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/cbc5193e0c009faf80614a3b5bb42ac27fd29851 @@ -0,0 +1 @@ +10P370 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/cc7527ecef21cae1abe375499df7c30c8cc68988 b/fuzzing/seedcorpus/fuzz_from_chars_float/cc7527ecef21cae1abe375499df7c30c8cc68988 new file mode 100644 index 000000000..e27b9598b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/cc7527ecef21cae1abe375499df7c30c8cc68988 @@ -0,0 +1 @@ +-809273333333337333333333333333 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ccb6cf2dad896901e7670949e40c527a6aefc7eb b/fuzzing/seedcorpus/fuzz_from_chars_float/ccb6cf2dad896901e7670949e40c527a6aefc7eb new file mode 100644 index 000000000..bdd451845 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ccb6cf2dad896901e7670949e40c527a6aefc7eb @@ -0,0 +1 @@ +5809278098 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ce893674c71f6bdb5e559dbda77173ee68071494 b/fuzzing/seedcorpus/fuzz_from_chars_float/ce893674c71f6bdb5e559dbda77173ee68071494 new file mode 100644 index 000000000..c486c83ca --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ce893674c71f6bdb5e559dbda77173ee68071494 @@ -0,0 +1 @@ +2191P91 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ced4e6f64f7ab9e0be1707df196d01fcbca75867 b/fuzzing/seedcorpus/fuzz_from_chars_float/ced4e6f64f7ab9e0be1707df196d01fcbca75867 new file mode 100644 index 000000000..1d3406c05 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ced4e6f64f7ab9e0be1707df196d01fcbca75867 @@ -0,0 +1 @@ +-.52AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5AA0278 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/cfc105b046dd633333787d2abc11244d4366009e b/fuzzing/seedcorpus/fuzz_from_chars_float/cfc105b046dd633333787d2abc11244d4366009e new file mode 100644 index 000000000..11a75e07d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/cfc105b046dd633333787d2abc11244d4366009e @@ -0,0 +1 @@ +856562000A2222222222222222222111111111111112.62307............................1..00222223.......................................................>.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d09282129be5a7f6521379f7a6a12828d43ec77d b/fuzzing/seedcorpus/fuzz_from_chars_float/d09282129be5a7f6521379f7a6a12828d43ec77d new file mode 100644 index 000000000..bd2324e2b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d09282129be5a7f6521379f7a6a12828d43ec77d @@ -0,0 +1 @@ +-825970035996.9272365923659272365923659E236.096 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d0a267992604ef378939a088a41b6374a87fcdcf b/fuzzing/seedcorpus/fuzz_from_chars_float/d0a267992604ef378939a088a41b6374a87fcdcf new file mode 100644 index 000000000..cc4cf4936 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d0a267992604ef378939a088a41b6374a87fcdcf @@ -0,0 +1 @@ +000222222222222222200000637155515848127943.................................801.....e9.................>.....2. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d218d42b181f6c9301d9e27af5c20ba249a15b37 b/fuzzing/seedcorpus/fuzz_from_chars_float/d218d42b181f6c9301d9e27af5c20ba249a15b37 new file mode 100644 index 000000000..bbc14d82c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d218d42b181f6c9301d9e27af5c20ba249a15b37 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA333333A33333333AA>>! \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d2693433a3e8e3b53492028d482e11c7f6725da3 b/fuzzing/seedcorpus/fuzz_from_chars_float/d2693433a3e8e3b53492028d482e11c7f6725da3 new file mode 100644 index 000000000..64fd183cb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d2693433a3e8e3b53492028d482e11c7f6725da3 @@ -0,0 +1 @@ +8e440 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d28ae1be4babad0e19d80e259ca951027c5b7ed7 b/fuzzing/seedcorpus/fuzz_from_chars_float/d28ae1be4babad0e19d80e259ca951027c5b7ed7 new file mode 100644 index 000000000..27eaab1e5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d28ae1be4babad0e19d80e259ca951027c5b7ed7 @@ -0,0 +1 @@ +5P2606( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d460718821607c728d6cafc42fd5d8567ea8f836 b/fuzzing/seedcorpus/fuzz_from_chars_float/d460718821607c728d6cafc42fd5d8567ea8f836 new file mode 100644 index 000000000..da0b203ee --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d460718821607c728d6cafc42fd5d8567ea8f836 @@ -0,0 +1 @@ +4e8380P6565 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d4d511cc56013c2eab6f009ae7cb1afc89d950f2 b/fuzzing/seedcorpus/fuzz_from_chars_float/d4d511cc56013c2eab6f009ae7cb1afc89d950f2 new file mode 100644 index 000000000..08111df9b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d4d511cc56013c2eab6f009ae7cb1afc89d950f2 @@ -0,0 +1 @@ +-.44454444444444444444444000000000007274............8>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d52cdeabefe2454fad16976d9517982394e5fa6c b/fuzzing/seedcorpus/fuzz_from_chars_float/d52cdeabefe2454fad16976d9517982394e5fa6c new file mode 100644 index 000000000..ecbb13e54 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d52cdeabefe2454fad16976d9517982394e5fa6c @@ -0,0 +1 @@ +300010411040108E5 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d5411442d253a23155167cd3b78eb9d1af9a19b9 b/fuzzing/seedcorpus/fuzz_from_chars_float/d5411442d253a23155167cd3b78eb9d1af9a19b9 new file mode 100644 index 000000000..f01c1be56 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d5411442d253a23155167cd3b78eb9d1af9a19b9 @@ -0,0 +1 @@ +213156e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d55b8302433e40a3ea4facedcbee3c2f7e5ea2fe b/fuzzing/seedcorpus/fuzz_from_chars_float/d55b8302433e40a3ea4facedcbee3c2f7e5ea2fe new file mode 100644 index 000000000..39e3701c2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d55b8302433e40a3ea4facedcbee3c2f7e5ea2fe @@ -0,0 +1 @@ +89658628 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d5889f672a351bfa5040a750a3801b79fb508f73 b/fuzzing/seedcorpus/fuzz_from_chars_float/d5889f672a351bfa5040a750a3801b79fb508f73 new file mode 100644 index 000000000..d19bb69c7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d5889f672a351bfa5040a750a3801b79fb508f73 @@ -0,0 +1 @@ +80927135161AAA diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d5f46dff951a84de93317f111026e553b54515f4 b/fuzzing/seedcorpus/fuzz_from_chars_float/d5f46dff951a84de93317f111026e553b54515f4 new file mode 100644 index 000000000..8689b2ae6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d5f46dff951a84de93317f111026e553b54515f4 @@ -0,0 +1 @@ +000222222222222222222200061293337707602829................................................................................................................11000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d72440063fe6b5b1f622303ce16bd1922113456c b/fuzzing/seedcorpus/fuzz_from_chars_float/d72440063fe6b5b1f622303ce16bd1922113456c new file mode 100644 index 000000000..0be960d5f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d72440063fe6b5b1f622303ce16bd1922113456c @@ -0,0 +1 @@ +.4444444444444444444444000000000007277124592131342A?>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d8064cdf4dea587d99e03b1fb3e80a28d6087090 b/fuzzing/seedcorpus/fuzz_from_chars_float/d8064cdf4dea587d99e03b1fb3e80a28d6087090 new file mode 100644 index 000000000..1b7916833 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d8064cdf4dea587d99e03b1fb3e80a28d6087090 @@ -0,0 +1,2 @@ +-8092733333333333338333333333333333333333333333333333333AAAAAAAAAAAA166623 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d82a19a46f2f7da0f84cb56740a41e0148eda5c1 b/fuzzing/seedcorpus/fuzz_from_chars_float/d82a19a46f2f7da0f84cb56740a41e0148eda5c1 new file mode 100644 index 000000000..42ba7c4ad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d82a19a46f2f7da0f84cb56740a41e0148eda5c1 @@ -0,0 +1 @@ +NAN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d83832a26f8781870a6b35ea93abfbaa80c8cac3 b/fuzzing/seedcorpus/fuzz_from_chars_float/d83832a26f8781870a6b35ea93abfbaa80c8cac3 new file mode 100644 index 000000000..a65ea76a9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d83832a26f8781870a6b35ea93abfbaa80c8cac3 @@ -0,0 +1 @@ +8e6766261 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d9992371a495e107bd48e1580e14ae8de78be512 b/fuzzing/seedcorpus/fuzz_from_chars_float/d9992371a495e107bd48e1580e14ae8de78be512 new file mode 100644 index 000000000..d54ea647d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d9992371a495e107bd48e1580e14ae8de78be512 @@ -0,0 +1 @@ +000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/d9b65d12c124a46b95f1755dd2360342457af251 b/fuzzing/seedcorpus/fuzz_from_chars_float/d9b65d12c124a46b95f1755dd2360342457af251 new file mode 100644 index 000000000..a40797802 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/d9b65d12c124a46b95f1755dd2360342457af251 @@ -0,0 +1 @@ +7P \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dadf9a7f283233d824f70467e36681e5992ef8b6 b/fuzzing/seedcorpus/fuzz_from_chars_float/dadf9a7f283233d824f70467e36681e5992ef8b6 new file mode 100644 index 000000000..366c338a4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dadf9a7f283233d824f70467e36681e5992ef8b6 @@ -0,0 +1 @@ +8E000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/daedd5697c1a0b555f3649c93bf87e015e1b05fb b/fuzzing/seedcorpus/fuzz_from_chars_float/daedd5697c1a0b555f3649c93bf87e015e1b05fb new file mode 100644 index 000000000..ad2f4f1b8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/daedd5697c1a0b555f3649c93bf87e015e1b05fb @@ -0,0 +1,81 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +205054263588366773474331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +561e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.73506319914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221114.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +6729186819880939756e+20 +-4.4599414413418414e+20 +-7.939542985204633e+20 +-7.3428836122343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/db07cd8f7433f10c1bcb80b426962f0cbf21e87f b/fuzzing/seedcorpus/fuzz_from_chars_float/db07cd8f7433f10c1bcb80b426962f0cbf21e87f new file mode 100644 index 000000000..56e1c6f0b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/db07cd8f7433f10c1bcb80b426962f0cbf21e87f @@ -0,0 +1 @@ +-.40644444444444444444444444444444444444444F> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dbca356161b111db23becf0f6068bd3377ed7aa0 b/fuzzing/seedcorpus/fuzz_from_chars_float/dbca356161b111db23becf0f6068bd3377ed7aa0 new file mode 100644 index 000000000..a53602433 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dbca356161b111db23becf0f6068bd3377ed7aa0 @@ -0,0 +1 @@ +8572 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dc467178f8ae07c72f2a3cdeb503d03b1c805758 b/fuzzing/seedcorpus/fuzz_from_chars_float/dc467178f8ae07c72f2a3cdeb503d03b1c805758 new file mode 100644 index 000000000..2f799f25e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dc467178f8ae07c72f2a3cdeb503d03b1c805758 @@ -0,0 +1 @@ +A1, \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dc4ce5e433408417166e9020eae9a8aaea3dce06 b/fuzzing/seedcorpus/fuzz_from_chars_float/dc4ce5e433408417166e9020eae9a8aaea3dce06 new file mode 100644 index 000000000..24772619d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dc4ce5e433408417166e9020eae9a8aaea3dce06 @@ -0,0 +1 @@ +.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dc4d09d6b8508b43c7bbb13ab867c70a55198baa b/fuzzing/seedcorpus/fuzz_from_chars_float/dc4d09d6b8508b43c7bbb13ab867c70a55198baa new file mode 100644 index 000000000..443409555 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dc4d09d6b8508b43c7bbb13ab867c70a55198baa @@ -0,0 +1 @@ +-222222222222222222222222222222180e8381P62186 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dd93739629453b02db5190803624e7f880f7236d b/fuzzing/seedcorpus/fuzz_from_chars_float/dd93739629453b02db5190803624e7f880f7236d new file mode 100644 index 000000000..d6dca0fd6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dd93739629453b02db5190803624e7f880f7236d @@ -0,0 +1 @@ +000222222222222222222222222222222222222223.................................1.....e9..................2. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/dd979bf4aeefeef05b05d9b934f84b29860661a3 b/fuzzing/seedcorpus/fuzz_from_chars_float/dd979bf4aeefeef05b05d9b934f84b29860661a3 new file mode 100644 index 000000000..bfeb03c50 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/dd979bf4aeefeef05b05d9b934f84b29860661a3 @@ -0,0 +1 @@ +-333333133333333336.21 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ddd2bbff3df1dc1cab81052d43f7805ceb9873eb b/fuzzing/seedcorpus/fuzz_from_chars_float/ddd2bbff3df1dc1cab81052d43f7805ceb9873eb new file mode 100644 index 000000000..bb9869c3f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ddd2bbff3df1dc1cab81052d43f7805ceb9873eb @@ -0,0 +1 @@ +80927809270 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/de33efbf7aca73104500451814099264a43e0e4e b/fuzzing/seedcorpus/fuzz_from_chars_float/de33efbf7aca73104500451814099264a43e0e4e new file mode 100644 index 000000000..74955a629 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/de33efbf7aca73104500451814099264a43e0e4e @@ -0,0 +1 @@ +6P-6661 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/de9e708f40edc6b48a8713e339de6905e43a7baa b/fuzzing/seedcorpus/fuzz_from_chars_float/de9e708f40edc6b48a8713e339de6905e43a7baa new file mode 100644 index 000000000..8f63aba2b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/de9e708f40edc6b48a8713e339de6905e43a7baa @@ -0,0 +1 @@ +830A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/df1d167d397f1da0f84cd4ee8e296e927b495aa7 b/fuzzing/seedcorpus/fuzz_from_chars_float/df1d167d397f1da0f84cd4ee8e296e927b495aa7 new file mode 100644 index 000000000..f0a24c895 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/df1d167d397f1da0f84cd4ee8e296e927b495aa7 @@ -0,0 +1 @@ +893e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/df73d7de736d99eeb1e20fce0ab6d7f38047de2d b/fuzzing/seedcorpus/fuzz_from_chars_float/df73d7de736d99eeb1e20fce0ab6d7f38047de2d new file mode 100644 index 000000000..ecca6583d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/df73d7de736d99eeb1e20fce0ab6d7f38047de2d @@ -0,0 +1 @@ +-80927262592365992AAAAAAAAAAAAAA diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e0184adedf913b076626646d3f52c3b49c39ad6d b/fuzzing/seedcorpus/fuzz_from_chars_float/e0184adedf913b076626646d3f52c3b49c39ad6d new file mode 100644 index 000000000..9fb75b8d4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e0184adedf913b076626646d3f52c3b49c39ad6d @@ -0,0 +1 @@ +E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e10349fb7aabbb001bcc79308c11d8a030013d21 b/fuzzing/seedcorpus/fuzz_from_chars_float/e10349fb7aabbb001bcc79308c11d8a030013d21 new file mode 100644 index 000000000..4feb44e27 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e10349fb7aabbb001bcc79308c11d8a030013d21 @@ -0,0 +1 @@ +-896568695688FFFFFFFFFFFFFFFFF diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e132c467fd9578492c0d8a6648f61ce4155253b0 b/fuzzing/seedcorpus/fuzz_from_chars_float/e132c467fd9578492c0d8a6648f61ce4155253b0 new file mode 100644 index 000000000..c30a126c8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e132c467fd9578492c0d8a6648f61ce4155253b0 @@ -0,0 +1 @@ +-AAAAAAAAAAA3659236.952AAAAAAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e1e155f6377e1259790e8a365cda26ef2ddea3d9 b/fuzzing/seedcorpus/fuzz_from_chars_float/e1e155f6377e1259790e8a365cda26ef2ddea3d9 new file mode 100644 index 000000000..fd317e3de --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e1e155f6377e1259790e8a365cda26ef2ddea3d9 @@ -0,0 +1,2 @@ +-0.4 +>>>>>>>>>>1>>>>>>>>>>>>>>>>>>>>>>>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e411791db9b3535116952911ac13e3bca687c558 b/fuzzing/seedcorpus/fuzz_from_chars_float/e411791db9b3535116952911ac13e3bca687c558 new file mode 100644 index 000000000..c6656e28d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e411791db9b3535116952911ac13e3bca687c558 @@ -0,0 +1 @@ +-.3300000000140000000.7P0850 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e48beca9fed7c0109dec30b681f74cb4ab658bec b/fuzzing/seedcorpus/fuzz_from_chars_float/e48beca9fed7c0109dec30b681f74cb4ab658bec new file mode 100644 index 000000000..33c352b69 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e48beca9fed7c0109dec30b681f74cb4ab658bec @@ -0,0 +1 @@ +.p4977283 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e61b1e9e2653335f11fbaf5169ce07280ceb1916 b/fuzzing/seedcorpus/fuzz_from_chars_float/e61b1e9e2653335f11fbaf5169ce07280ceb1916 new file mode 100644 index 000000000..a64800c91 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e61b1e9e2653335f11fbaf5169ce07280ceb1916 @@ -0,0 +1 @@ +-8092233333333333333333333 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e6911c8aa33ed592740fff09b1d602ef2d2d2c2e b/fuzzing/seedcorpus/fuzz_from_chars_float/e6911c8aa33ed592740fff09b1d602ef2d2d2c2e new file mode 100644 index 000000000..b02c65012 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e6911c8aa33ed592740fff09b1d602ef2d2d2c2e @@ -0,0 +1 @@ +8E00000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e6e60bae992f839cef0fe30ab14c445d41cf0fe1 b/fuzzing/seedcorpus/fuzz_from_chars_float/e6e60bae992f839cef0fe30ab14c445d41cf0fe1 new file mode 100644 index 000000000..92cc9bf48 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e6e60bae992f839cef0fe30ab14c445d41cf0fe1 @@ -0,0 +1 @@ +-80127333333333333P3333301 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/e8c1f4b74f35d82d019d4dfc27b0111b33c0baf9 b/fuzzing/seedcorpus/fuzz_from_chars_float/e8c1f4b74f35d82d019d4dfc27b0111b33c0baf9 new file mode 100644 index 000000000..49d17444d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/e8c1f4b74f35d82d019d4dfc27b0111b33c0baf9 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAA4AAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ea17004bf7d0f56a573a1f93a938742c97eaf6ca b/fuzzing/seedcorpus/fuzz_from_chars_float/ea17004bf7d0f56a573a1f93a938742c97eaf6ca new file mode 100644 index 000000000..e70efcdfe --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ea17004bf7d0f56a573a1f93a938742c97eaf6ca @@ -0,0 +1 @@ +8E5P2v \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ea7dd9973108c02849be8150fece4fd143c4c4d8 b/fuzzing/seedcorpus/fuzz_from_chars_float/ea7dd9973108c02849be8150fece4fd143c4c4d8 new file mode 100644 index 000000000..3494c6b46 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ea7dd9973108c02849be8150fece4fd143c4c4d8 @@ -0,0 +1 @@ +5P+0000000000000000000000000000000000000000000A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/eb16ad6e29d505d2271d83d1f7db7783eeb3f99e b/fuzzing/seedcorpus/fuzz_from_chars_float/eb16ad6e29d505d2271d83d1f7db7783eeb3f99e new file mode 100644 index 000000000..a425eb81b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/eb16ad6e29d505d2271d83d1f7db7783eeb3f99e @@ -0,0 +1 @@ +8565620000A22222222205555555555556.62307.......................................................................0092..0022222223............................................................................................... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/eb9c3dfa0f61e5a78aa7de543485985ea5ec76f8 b/fuzzing/seedcorpus/fuzz_from_chars_float/eb9c3dfa0f61e5a78aa7de543485985ea5ec76f8 new file mode 100644 index 000000000..d4e01fb60 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/eb9c3dfa0f61e5a78aa7de543485985ea5ec76f8 @@ -0,0 +1 @@ +.65620200e382 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ec15301d22a52e39146b9f43405284face5c95d8 b/fuzzing/seedcorpus/fuzz_from_chars_float/ec15301d22a52e39146b9f43405284face5c95d8 new file mode 100644 index 000000000..cdf47e360 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/ec15301d22a52e39146b9f43405284face5c95d8 differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ed003421c105a0e49a22be86022ba0afbb3be2b3 b/fuzzing/seedcorpus/fuzz_from_chars_float/ed003421c105a0e49a22be86022ba0afbb3be2b3 new file mode 100644 index 000000000..b0db8db55 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ed003421c105a0e49a22be86022ba0afbb3be2b3 @@ -0,0 +1 @@ +-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.AAfA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/ed73684b26c2e8f73df9b8e2b4728f6bbb9a3b8d b/fuzzing/seedcorpus/fuzz_from_chars_float/ed73684b26c2e8f73df9b8e2b4728f6bbb9a3b8d new file mode 100644 index 000000000..aad4bff54 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/ed73684b26c2e8f73df9b8e2b4728f6bbb9a3b8d @@ -0,0 +1 @@ +801e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/eda17c0d6993edc39be156fcd42aa95da77ac7f0 b/fuzzing/seedcorpus/fuzz_from_chars_float/eda17c0d6993edc39be156fcd42aa95da77ac7f0 new file mode 100644 index 000000000..eb6dd44cd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/eda17c0d6993edc39be156fcd42aa95da77ac7f0 @@ -0,0 +1 @@ +80967263A \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/edef765858787adbc434574ca52f75deb3b5cb73 b/fuzzing/seedcorpus/fuzz_from_chars_float/edef765858787adbc434574ca52f75deb3b5cb73 new file mode 100644 index 000000000..3be127893 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/edef765858787adbc434574ca52f75deb3b5cb73 @@ -0,0 +1 @@ +8.52056008 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f0589f2f4eb321a209cd6ac8b2c74852400aa443 b/fuzzing/seedcorpus/fuzz_from_chars_float/f0589f2f4eb321a209cd6ac8b2c74852400aa443 new file mode 100644 index 000000000..4594203f9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f0589f2f4eb321a209cd6ac8b2c74852400aa443 @@ -0,0 +1 @@ +8E109275P966600 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f0fc7920801d30cd5655c9758e1ba99181c4122f b/fuzzing/seedcorpus/fuzz_from_chars_float/f0fc7920801d30cd5655c9758e1ba99181c4122f new file mode 100644 index 000000000..5b6466993 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f0fc7920801d30cd5655c9758e1ba99181c4122f @@ -0,0 +1 @@ +AAAAAAAAAAA.AAAAAAaAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f1c38192c47a7917738df3592defdec7b20df54a b/fuzzing/seedcorpus/fuzz_from_chars_float/f1c38192c47a7917738df3592defdec7b20df54a new file mode 100644 index 000000000..6f8d06217 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/f1c38192c47a7917738df3592defdec7b20df54a differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f1cb7507ad17857a097963b63effd5690a7a1766 b/fuzzing/seedcorpus/fuzz_from_chars_float/f1cb7507ad17857a097963b63effd5690a7a1766 new file mode 100644 index 000000000..06ef69744 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f1cb7507ad17857a097963b63effd5690a7a1766 @@ -0,0 +1 @@ +0002222222222222222222222222222222222222222222222222222222222222222222222222A222222222222222222222222222000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f1f509ecead04ccb7ab2257383260612125471e3 b/fuzzing/seedcorpus/fuzz_from_chars_float/f1f509ecead04ccb7ab2257383260612125471e3 new file mode 100644 index 000000000..785e1017f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f1f509ecead04ccb7ab2257383260612125471e3 @@ -0,0 +1 @@ +5e-443 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f260e217af2121d620bf8baf0771f3f81f3a6170 b/fuzzing/seedcorpus/fuzz_from_chars_float/f260e217af2121d620bf8baf0771f3f81f3a6170 new file mode 100644 index 000000000..493008e6b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f260e217af2121d620bf8baf0771f3f81f3a6170 @@ -0,0 +1 @@ +99999999999999999999999999999999999906> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f412c85427816aa552ac9428d3ae7a412286e5e3 b/fuzzing/seedcorpus/fuzz_from_chars_float/f412c85427816aa552ac9428d3ae7a412286e5e3 new file mode 100644 index 000000000..925d419b6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f412c85427816aa552ac9428d3ae7a412286e5e3 @@ -0,0 +1,2 @@ +-0.4 +>>>>>>>>>>1>>>>>>>>> \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f6054f9ef50a71730f57ffed633b9e3093345ee0 b/fuzzing/seedcorpus/fuzz_from_chars_float/f6054f9ef50a71730f57ffed633b9e3093345ee0 new file mode 100644 index 000000000..877739d2e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f6054f9ef50a71730f57ffed633b9e3093345ee0 @@ -0,0 +1 @@ +.212553775e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f60d2a2f7993d5825671faef6f38d5d8a0c34130 b/fuzzing/seedcorpus/fuzz_from_chars_float/f60d2a2f7993d5825671faef6f38d5d8a0c34130 new file mode 100644 index 000000000..e66099ecf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f60d2a2f7993d5825671faef6f38d5d8a0c34130 @@ -0,0 +1 @@ +ne \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f661e69b5467ee8827b732327305bce8496213cb b/fuzzing/seedcorpus/fuzz_from_chars_float/f661e69b5467ee8827b732327305bce8496213cb new file mode 100644 index 000000000..24b912fc1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f661e69b5467ee8827b732327305bce8496213cb @@ -0,0 +1 @@ +NAN(I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f6a44447ffe169b915384144f41f7cd98891173d b/fuzzing/seedcorpus/fuzz_from_chars_float/f6a44447ffe169b915384144f41f7cd98891173d new file mode 100644 index 000000000..421fdaa21 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f6a44447ffe169b915384144f41f7cd98891173d @@ -0,0 +1 @@ +.21354e5 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f6df1e7d6f430eb8cc6c1261d1b924b136391753 b/fuzzing/seedcorpus/fuzz_from_chars_float/f6df1e7d6f430eb8cc6c1261d1b924b136391753 new file mode 100644 index 000000000..4ca9bf2bc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f6df1e7d6f430eb8cc6c1261d1b924b136391753 @@ -0,0 +1 @@ +-33001291940003282f6 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f768df72e9f7d1b70e81062dda0484063f731209 b/fuzzing/seedcorpus/fuzz_from_chars_float/f768df72e9f7d1b70e81062dda0484063f731209 new file mode 100644 index 000000000..5d2285d75 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f768df72e9f7d1b70e81062dda0484063f731209 @@ -0,0 +1 @@ +bbbbfbbbabbbbbe \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f77db4df4b66b9f90150c31cd304ca754b59ee52 b/fuzzing/seedcorpus/fuzz_from_chars_float/f77db4df4b66b9f90150c31cd304ca754b59ee52 new file mode 100644 index 000000000..5b0b435dc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f77db4df4b66b9f90150c31cd304ca754b59ee52 @@ -0,0 +1 @@ +-809200000000000008000000333337333685 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f798d195d77e540a84bcebfe76cd22291341c246 b/fuzzing/seedcorpus/fuzz_from_chars_float/f798d195d77e540a84bcebfe76cd22291341c246 new file mode 100644 index 000000000..ab148ffdb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f798d195d77e540a84bcebfe76cd22291341c246 @@ -0,0 +1 @@ +.3300444400000000005.e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f7d01a991b0e48c0d652ac1df548d7f9953d0848 b/fuzzing/seedcorpus/fuzz_from_chars_float/f7d01a991b0e48c0d652ac1df548d7f9953d0848 new file mode 100644 index 000000000..2407115aa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f7d01a991b0e48c0d652ac1df548d7f9953d0848 @@ -0,0 +1 @@ +NAE \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/f844bc59cc79c834661be20999a0d09bed3df561 b/fuzzing/seedcorpus/fuzz_from_chars_float/f844bc59cc79c834661be20999a0d09bed3df561 new file mode 100644 index 000000000..d225435fd --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/f844bc59cc79c834661be20999a0d09bed3df561 @@ -0,0 +1 @@ +.00< \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fb11ea98f9d9e6025c9fe76f3b6d12f1fa0fc933 b/fuzzing/seedcorpus/fuzz_from_chars_float/fb11ea98f9d9e6025c9fe76f3b6d12f1fa0fc933 new file mode 100644 index 000000000..3012bd0d2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/fb11ea98f9d9e6025c9fe76f3b6d12f1fa0fc933 @@ -0,0 +1 @@ +-2A.05AAAAAAAAAAAAAAAAAAAAAAAAAAA1AA33AA6A-5 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fbd1fffdda9d583f09557dccb9e93be366e4d22d b/fuzzing/seedcorpus/fuzz_from_chars_float/fbd1fffdda9d583f09557dccb9e93be366e4d22d new file mode 100644 index 000000000..2d04ad590 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/fbd1fffdda9d583f09557dccb9e93be366e4d22d @@ -0,0 +1 @@ +.0000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fbf282fd42f5ae8ed1a4fb3bc1b5608ccdd398eb b/fuzzing/seedcorpus/fuzz_from_chars_float/fbf282fd42f5ae8ed1a4fb3bc1b5608ccdd398eb new file mode 100644 index 000000000..3271c7433 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/fbf282fd42f5ae8ed1a4fb3bc1b5608ccdd398eb @@ -0,0 +1 @@ +8937373191376 diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fc82525f33d7642e0b00e4f7a29692e088be0d2b b/fuzzing/seedcorpus/fuzz_from_chars_float/fc82525f33d7642e0b00e4f7a29692e088be0d2b new file mode 100644 index 000000000..7d20f1034 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_from_chars_float/fc82525f33d7642e0b00e4f7a29692e088be0d2b differ diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fccf144e5d528b73ec77db7a573b0383698f94ca b/fuzzing/seedcorpus/fuzz_from_chars_float/fccf144e5d528b73ec77db7a573b0383698f94ca new file mode 100644 index 000000000..ccc5f8a7b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/fccf144e5d528b73ec77db7a573b0383698f94ca @@ -0,0 +1 @@ +8010e93 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_from_chars_float/fe3222b25822df337fd3b6c87f54458e69a4f6f4 b/fuzzing/seedcorpus/fuzz_from_chars_float/fe3222b25822df337fd3b6c87f54458e69a4f6f4 new file mode 100644 index 000000000..43fbcdfce --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_from_chars_float/fe3222b25822df337fd3b6c87f54458e69a4f6f4 @@ -0,0 +1 @@ +AAAAAcAAAAAA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/00ec59afdc843654416b3b7ca3e5f4b08376a26c b/fuzzing/seedcorpus/fuzz_string_constructors/00ec59afdc843654416b3b7ca3e5f4b08376a26c new file mode 100644 index 000000000..486f3e8b2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/00ec59afdc843654416b3b7ca3e5f4b08376a26c @@ -0,0 +1 @@ +iNf \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/01d6c69124e8ed4a5baf4f7d843004fbddb8707c b/fuzzing/seedcorpus/fuzz_string_constructors/01d6c69124e8ed4a5baf4f7d843004fbddb8707c new file mode 100644 index 000000000..609b14826 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/01d6c69124e8ed4a5baf4f7d843004fbddb8707c @@ -0,0 +1 @@ +.00000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 b/fuzzing/seedcorpus/fuzz_string_constructors/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 new file mode 100644 index 000000000..e49da69a9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 @@ -0,0 +1 @@ +33980318289839803182.270350031827033189839803182.270350530.00000.8530.00.82703505705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/03e473c16fb04cd9879ae0680ff7e4d574761548 b/fuzzing/seedcorpus/fuzz_string_constructors/03e473c16fb04cd9879ae0680ff7e4d574761548 new file mode 100644 index 000000000..143a57709 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_string_constructors/03e473c16fb04cd9879ae0680ff7e4d574761548 differ diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/042dc4512fa3d391c5170cf3aa61e6a638f84342 b/fuzzing/seedcorpus/fuzz_string_constructors/042dc4512fa3d391c5170cf3aa61e6a638f84342 new file mode 100644 index 000000000..597a6db29 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/042dc4512fa3d391c5170cf3aa61e6a638f84342 @@ -0,0 +1 @@ +i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/081adf20bfe36db540138c8cbcdb900330f1db51 b/fuzzing/seedcorpus/fuzz_string_constructors/081adf20bfe36db540138c8cbcdb900330f1db51 new file mode 100644 index 000000000..f3a254771 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/081adf20bfe36db540138c8cbcdb900330f1db51 @@ -0,0 +1 @@ +988098198120061999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/08a27570f77898e8db880bb05e7a807f2a32f829 b/fuzzing/seedcorpus/fuzz_string_constructors/08a27570f77898e8db880bb05e7a807f2a32f829 new file mode 100644 index 000000000..b28daaa12 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/08a27570f77898e8db880bb05e7a807f2a32f829 @@ -0,0 +1 @@ +198398031827331627035 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/099bee553bdbaebb02d3743dae75c701fc1b690a b/fuzzing/seedcorpus/fuzz_string_constructors/099bee553bdbaebb02d3743dae75c701fc1b690a new file mode 100644 index 000000000..8e2b775cb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/099bee553bdbaebb02d3743dae75c701fc1b690a @@ -0,0 +1 @@ +9.090080079839813141.e8198 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0a129aaaa1f3a215450f61ebc46bf664160d7588 b/fuzzing/seedcorpus/fuzz_string_constructors/0a129aaaa1f3a215450f61ebc46bf664160d7588 new file mode 100644 index 000000000..3a660b1ee --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0a129aaaa1f3a215450f61ebc46bf664160d7588 @@ -0,0 +1 @@ +2e003 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0ad1fd13c204b07abb2409078fee4c00c8d6e39a b/fuzzing/seedcorpus/fuzz_string_constructors/0ad1fd13c204b07abb2409078fee4c00c8d6e39a new file mode 100644 index 000000000..60aa4dc0a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0ad1fd13c204b07abb2409078fee4c00c8d6e39a @@ -0,0 +1 @@ +281398392803182703318908398031872035053.8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 b/fuzzing/seedcorpus/fuzz_string_constructors/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0c7371813bd3bf7d5a835770f71a1d6763b3c00a b/fuzzing/seedcorpus/fuzz_string_constructors/0c7371813bd3bf7d5a835770f71a1d6763b3c00a new file mode 100644 index 000000000..9c910c1d5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0c7371813bd3bf7d5a835770f71a1d6763b3c00a @@ -0,0 +1 @@ +3.790000909999180800809999999999999999919/ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0df5f797909ef949331359a34c7bbcfc3188b96c b/fuzzing/seedcorpus/fuzz_string_constructors/0df5f797909ef949331359a34c7bbcfc3188b96c new file mode 100644 index 000000000..aa8be1fb5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0df5f797909ef949331359a34c7bbcfc3188b96c @@ -0,0 +1 @@ +3.7918080080991808008099999999000000000000000000000000000000000017371412905560592406 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 b/fuzzing/seedcorpus/fuzz_string_constructors/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 new file mode 100644 index 000000000..d03bc1cf0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 @@ -0,0 +1 @@ +000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/0ff84737c510827e1d12442378abbfe26ef2569d b/fuzzing/seedcorpus/fuzz_string_constructors/0ff84737c510827e1d12442378abbfe26ef2569d new file mode 100644 index 000000000..ea0807e60 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/0ff84737c510827e1d12442378abbfe26ef2569d @@ -0,0 +1,2 @@ +99999996008099999998e6128 + diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 b/fuzzing/seedcorpus/fuzz_string_constructors/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 new file mode 100644 index 000000000..b094ced12 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 @@ -0,0 +1 @@ +39839803172833183981.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/11e623a37e87cf7995c466723ec99688d55cae8c b/fuzzing/seedcorpus/fuzz_string_constructors/11e623a37e87cf7995c466723ec99688d55cae8c new file mode 100644 index 000000000..0982929c5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/11e623a37e87cf7995c466723ec99688d55cae8c @@ -0,0 +1 @@ +nan \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a b/fuzzing/seedcorpus/fuzz_string_constructors/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a new file mode 100644 index 000000000..30548b723 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a @@ -0,0 +1 @@ +281239839803182731890839803182727035053.825 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/15346b593c4d0cf05fb6e67a5669d852e6550481 b/fuzzing/seedcorpus/fuzz_string_constructors/15346b593c4d0cf05fb6e67a5669d852e6550481 new file mode 100644 index 000000000..85f98a55b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/15346b593c4d0cf05fb6e67a5669d852e6550481 @@ -0,0 +1 @@ +007 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/160799451addefa79541671e7b54cd69a56ddb77 b/fuzzing/seedcorpus/fuzz_string_constructors/160799451addefa79541671e7b54cd69a56ddb77 new file mode 100644 index 000000000..4ab479ea9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/160799451addefa79541671e7b54cd69a56ddb77 @@ -0,0 +1 @@ +281200000000000000008297558344909248599. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1a4be11edda0564776f09ed1e58f074f67a3ee1c b/fuzzing/seedcorpus/fuzz_string_constructors/1a4be11edda0564776f09ed1e58f074f67a3ee1c new file mode 100644 index 000000000..1c7bae85b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1a4be11edda0564776f09ed1e58f074f67a3ee1c @@ -0,0 +1 @@ +39039500318270189839803533182.2703503500.1..........................................190.01........................00...7..................4.......................................3 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e b/fuzzing/seedcorpus/fuzz_string_constructors/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e new file mode 100644 index 000000000..1c82e33d0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e @@ -0,0 +1 @@ +n \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1bc2d3fdbed8be5af148c372a93d3f448587b171 b/fuzzing/seedcorpus/fuzz_string_constructors/1bc2d3fdbed8be5af148c372a93d3f448587b171 new file mode 100644 index 000000000..b27684f01 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1bc2d3fdbed8be5af148c372a93d3f448587b171 @@ -0,0 +1,57 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +889810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181536167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 b/fuzzing/seedcorpus/fuzz_string_constructors/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 new file mode 100644 index 000000000..524bdf192 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 @@ -0,0 +1 @@ +2E12# \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1d2706e66694c4a168db8c00963e978aedbe3001 b/fuzzing/seedcorpus/fuzz_string_constructors/1d2706e66694c4a168db8c00963e978aedbe3001 new file mode 100644 index 000000000..4297f847a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1d2706e66694c4a168db8c00963e978aedbe3001 @@ -0,0 +1,86 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +889810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130t05205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +34090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/1d542ab3fcee910bafef3179394c31572c4ea7bd b/fuzzing/seedcorpus/fuzz_string_constructors/1d542ab3fcee910bafef3179394c31572c4ea7bd new file mode 100644 index 000000000..a951e05f3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/1d542ab3fcee910bafef3179394c31572c4ea7bd @@ -0,0 +1 @@ +8e772 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/21006037389470e0d8a02503c389647711d53fed b/fuzzing/seedcorpus/fuzz_string_constructors/21006037389470e0d8a02503c389647711d53fed new file mode 100644 index 000000000..467c04108 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/21006037389470e0d8a02503c389647711d53fed @@ -0,0 +1 @@ +8e853693m \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 b/fuzzing/seedcorpus/fuzz_string_constructors/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 new file mode 100644 index 000000000..334395d7e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 @@ -0,0 +1 @@ +9e000000000000000000000000000000002 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/21da4ee5a3b7442cb299d27c7983806be538c101 b/fuzzing/seedcorpus/fuzz_string_constructors/21da4ee5a3b7442cb299d27c7983806be538c101 new file mode 100644 index 000000000..f1af80071 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/21da4ee5a3b7442cb299d27c7983806be538c101 @@ -0,0 +1 @@ +8e-998200 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/225f840511ff1f547609cff02568ca66e73f5776 b/fuzzing/seedcorpus/fuzz_string_constructors/225f840511ff1f547609cff02568ca66e73f5776 new file mode 100644 index 000000000..43a86fc64 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/225f840511ff1f547609cff02568ca66e73f5776 @@ -0,0 +1 @@ +in \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd b/fuzzing/seedcorpus/fuzz_string_constructors/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd new file mode 100644 index 000000000..356ec7d8c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd @@ -0,0 +1 @@ +98698622; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/23790de4fdddf42c06f2564d65fe9a5d660a2b46 b/fuzzing/seedcorpus/fuzz_string_constructors/23790de4fdddf42c06f2564d65fe9a5d660a2b46 new file mode 100644 index 000000000..fd180176a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/23790de4fdddf42c06f2564d65fe9a5d660a2b46 @@ -0,0 +1 @@ +.809999998008980089999901836 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/25add3f5bfca228c15d4feaf213c4eadc18b3a69 b/fuzzing/seedcorpus/fuzz_string_constructors/25add3f5bfca228c15d4feaf213c4eadc18b3a69 new file mode 100644 index 000000000..ec60d2823 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/25add3f5bfca228c15d4feaf213c4eadc18b3a69 @@ -0,0 +1 @@ +98803983180312.20899.e30 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/25b0d22b32d8a8c839dc9cf223153d8bed908b55 b/fuzzing/seedcorpus/fuzz_string_constructors/25b0d22b32d8a8c839dc9cf223153d8bed908b55 new file mode 100644 index 000000000..83f9aeda6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/25b0d22b32d8a8c839dc9cf223153d8bed908b55 @@ -0,0 +1,90 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 b/fuzzing/seedcorpus/fuzz_string_constructors/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 new file mode 100644 index 000000000..9d76fd4bf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 @@ -0,0 +1 @@ +9.098080080862099999800008099999999999999999999999900809999999999999900999999990080999999999999999999999999999999999999999999999000000000000000000000000000000001563499; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/29118d615211d612244a09bf294725003ceca7f3 b/fuzzing/seedcorpus/fuzz_string_constructors/29118d615211d612244a09bf294725003ceca7f3 new file mode 100644 index 000000000..a72122458 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/29118d615211d612244a09bf294725003ceca7f3 @@ -0,0 +1 @@ +1.00872e379 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/296876f1180f368065683614d27bfe752442f3cf b/fuzzing/seedcorpus/fuzz_string_constructors/296876f1180f368065683614d27bfe752442f3cf new file mode 100644 index 000000000..02aefdb5d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/296876f1180f368065683614d27bfe752442f3cf @@ -0,0 +1 @@ +99999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/2a805b6d7eeee930096a8313c82960ca415f925d b/fuzzing/seedcorpus/fuzz_string_constructors/2a805b6d7eeee930096a8313c82960ca415f925d new file mode 100644 index 000000000..3a213c1ac --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/2a805b6d7eeee930096a8313c82960ca415f925d @@ -0,0 +1 @@ +.80909999999090999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/2b8dcee20b962f5f8b415b1c07f6233160203e2a b/fuzzing/seedcorpus/fuzz_string_constructors/2b8dcee20b962f5f8b415b1c07f6233160203e2a new file mode 100644 index 000000000..ef6cb50b1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/2b8dcee20b962f5f8b415b1c07f6233160203e2a @@ -0,0 +1 @@ +.000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 b/fuzzing/seedcorpus/fuzz_string_constructors/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 new file mode 100644 index 000000000..1c8a0e797 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3150b232402b5f20f0bb0278d552baf288dcd57d b/fuzzing/seedcorpus/fuzz_string_constructors/3150b232402b5f20f0bb0278d552baf288dcd57d new file mode 100644 index 000000000..dd2d6cb7e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3150b232402b5f20f0bb0278d552baf288dcd57d @@ -0,0 +1 @@ +980800804804 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/33abc754e958ae3d372d5cab62c15485ea4f1c1d b/fuzzing/seedcorpus/fuzz_string_constructors/33abc754e958ae3d372d5cab62c15485ea4f1c1d new file mode 100644 index 000000000..18bd554bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/33abc754e958ae3d372d5cab62c15485ea4f1c1d @@ -0,0 +1 @@ +.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/33eb8904073f449247417c7f31d125ef1d8b38fe b/fuzzing/seedcorpus/fuzz_string_constructors/33eb8904073f449247417c7f31d125ef1d8b38fe new file mode 100644 index 000000000..cf5162160 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/33eb8904073f449247417c7f31d125ef1d8b38fe @@ -0,0 +1 @@ +.0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 b/fuzzing/seedcorpus/fuzz_string_constructors/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 new file mode 100644 index 000000000..c2f016d67 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 @@ -0,0 +1 @@ +3791808009999999999988000089999999000000000791808009999999999980000000000000000001747 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f b/fuzzing/seedcorpus/fuzz_string_constructors/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f new file mode 100644 index 000000000..34ff322e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/395df8f7c51f007019cb30201c49e884b46b92fa b/fuzzing/seedcorpus/fuzz_string_constructors/395df8f7c51f007019cb30201c49e884b46b92fa new file mode 100644 index 000000000..fa7af8bf5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/395df8f7c51f007019cb30201c49e884b46b92fa @@ -0,0 +1 @@ +z \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/39dfa55283318d31afe5a3ff4a0e3253e2045e43 b/fuzzing/seedcorpus/fuzz_string_constructors/39dfa55283318d31afe5a3ff4a0e3253e2045e43 new file mode 100644 index 000000000..af2e09a3e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/39dfa55283318d31afe5a3ff4a0e3253e2045e43 @@ -0,0 +1 @@ +0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3a189510f050347bbb9224ef01a3f143e8e13584 b/fuzzing/seedcorpus/fuzz_string_constructors/3a189510f050347bbb9224ef01a3f143e8e13584 new file mode 100644 index 000000000..09fef86bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3a189510f050347bbb9224ef01a3f143e8e13584 @@ -0,0 +1 @@ +9e0000000000000000000000000000000000000000000000000000000000000000& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3a52ce780950d4d969792a2559cd519d7ee8c727 b/fuzzing/seedcorpus/fuzz_string_constructors/3a52ce780950d4d969792a2559cd519d7ee8c727 new file mode 100644 index 000000000..945c9b46d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3a52ce780950d4d969792a2559cd519d7ee8c727 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3a6611b8aa5c8485db9ed8be845118890f7ffc28 b/fuzzing/seedcorpus/fuzz_string_constructors/3a6611b8aa5c8485db9ed8be845118890f7ffc28 new file mode 100644 index 000000000..831bbf528 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3a6611b8aa5c8485db9ed8be845118890f7ffc28 @@ -0,0 +1 @@ +.E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 b/fuzzing/seedcorpus/fuzz_string_constructors/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 new file mode 100644 index 000000000..41ac62ab8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 @@ -0,0 +1 @@ +98008087 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 b/fuzzing/seedcorpus/fuzz_string_constructors/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 new file mode 100644 index 000000000..3cf20d57b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3c0526bf781d7b905b018dd399e07d3e614405d8 b/fuzzing/seedcorpus/fuzz_string_constructors/3c0526bf781d7b905b018dd399e07d3e614405d8 new file mode 100644 index 000000000..af37bbe68 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3c0526bf781d7b905b018dd399e07d3e614405d8 @@ -0,0 +1 @@ +3.79880089089180000080707564239575326730 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 b/fuzzing/seedcorpus/fuzz_string_constructors/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 new file mode 100644 index 000000000..d36759ac7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 @@ -0,0 +1 @@ +990800809999999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3f001396ecde47550f65396e5d8daaa0c0ca4743 b/fuzzing/seedcorpus/fuzz_string_constructors/3f001396ecde47550f65396e5d8daaa0c0ca4743 new file mode 100644 index 000000000..8f5855b1b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3f001396ecde47550f65396e5d8daaa0c0ca4743 @@ -0,0 +1 @@ +98e370 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3f16364fd3234c947f326acda17fafe9333288fe b/fuzzing/seedcorpus/fuzz_string_constructors/3f16364fd3234c947f326acda17fafe9333288fe new file mode 100644 index 000000000..44dd0c9f1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3f16364fd3234c947f326acda17fafe9333288fe @@ -0,0 +1 @@ +200000000000000000007665596919578706393...8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/3f7b47892beaa319e4d5b3d811d96e99003a20f1 b/fuzzing/seedcorpus/fuzz_string_constructors/3f7b47892beaa319e4d5b3d811d96e99003a20f1 new file mode 100644 index 000000000..9633dcce0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/3f7b47892beaa319e4d5b3d811d96e99003a20f1 @@ -0,0 +1 @@ +nA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4012c69af25c0f38d8688b2fea8546c1b6a8df30 b/fuzzing/seedcorpus/fuzz_string_constructors/4012c69af25c0f38d8688b2fea8546c1b6a8df30 new file mode 100644 index 000000000..4538d0199 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4012c69af25c0f38d8688b2fea8546c1b6a8df30 @@ -0,0 +1 @@ +30318270331839803182.2703503.1205705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e b/fuzzing/seedcorpus/fuzz_string_constructors/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e new file mode 100644 index 000000000..6502b1cab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e @@ -0,0 +1 @@ +98000073679041073457386 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/40eb4486d987429dde612bab82832cddb27ade49 b/fuzzing/seedcorpus/fuzz_string_constructors/40eb4486d987429dde612bab82832cddb27ade49 new file mode 100644 index 000000000..cb4282be4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/40eb4486d987429dde612bab82832cddb27ade49 @@ -0,0 +1 @@ +.98998989 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/42f01bdd3606222ee7afec06a1d4e439c6f9572d b/fuzzing/seedcorpus/fuzz_string_constructors/42f01bdd3606222ee7afec06a1d4e439c6f9572d new file mode 100644 index 000000000..428fb095a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/42f01bdd3606222ee7afec06a1d4e439c6f9572d @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4624ea4856bed4781dc7ed75d583549ca4994e21 b/fuzzing/seedcorpus/fuzz_string_constructors/4624ea4856bed4781dc7ed75d583549ca4994e21 new file mode 100644 index 000000000..3d5221074 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4624ea4856bed4781dc7ed75d583549ca4994e21 @@ -0,0 +1 @@ +nan(S \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 b/fuzzing/seedcorpus/fuzz_string_constructors/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 new file mode 100644 index 000000000..9e0697c4b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 @@ -0,0 +1 @@ +.000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/486ae2d9b52d66199e10a7b3a2e6e98b2481853a b/fuzzing/seedcorpus/fuzz_string_constructors/486ae2d9b52d66199e10a7b3a2e6e98b2481853a new file mode 100644 index 000000000..344444f66 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/486ae2d9b52d66199e10a7b3a2e6e98b2481853a @@ -0,0 +1 @@ +0000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/488f555086ccf62c3248f7def32d1166c2b4b9da b/fuzzing/seedcorpus/fuzz_string_constructors/488f555086ccf62c3248f7def32d1166c2b4b9da new file mode 100644 index 000000000..b6a133631 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/488f555086ccf62c3248f7def32d1166c2b4b9da @@ -0,0 +1 @@ +980800804995999949930 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 b/fuzzing/seedcorpus/fuzz_string_constructors/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 new file mode 100644 index 000000000..571eaf288 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 @@ -0,0 +1 @@ +.048 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4adc138f92e999e212bb40016d3efbe312457e8b b/fuzzing/seedcorpus/fuzz_string_constructors/4adc138f92e999e212bb40016d3efbe312457e8b new file mode 100644 index 000000000..50188ec1c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4adc138f92e999e212bb40016d3efbe312457e8b @@ -0,0 +1 @@ +98000080999999980000809999999999999999999999999990080999999999999990099999999008999999999999999999999999999999999999008099999999999999999999999008099999999999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 b/fuzzing/seedcorpus/fuzz_string_constructors/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 new file mode 100644 index 000000000..a2e672167 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 @@ -0,0 +1 @@ +28919808532693711565736 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4b2a410256e782bef9dbd6c3ae20a75b61602137 b/fuzzing/seedcorpus/fuzz_string_constructors/4b2a410256e782bef9dbd6c3ae20a75b61602137 new file mode 100644 index 000000000..9a7fb6108 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4b2a410256e782bef9dbd6c3ae20a75b61602137 @@ -0,0 +1 @@ +nAN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4b4b0b325326d4188f894d7e4f3b90e58bb88294 b/fuzzing/seedcorpus/fuzz_string_constructors/4b4b0b325326d4188f894d7e4f3b90e58bb88294 new file mode 100644 index 000000000..e8bf0eca2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4b4b0b325326d4188f894d7e4f3b90e58bb88294 @@ -0,0 +1 @@ +98085369371565736 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea b/fuzzing/seedcorpus/fuzz_string_constructors/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea new file mode 100644 index 000000000..17af5987a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea @@ -0,0 +1 @@ +9999008099999999998e6128 diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/4cc95fce8e76b5e5a50b43086d775beae05030fb b/fuzzing/seedcorpus/fuzz_string_constructors/4cc95fce8e76b5e5a50b43086d775beae05030fb new file mode 100644 index 000000000..4a7814ee5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/4cc95fce8e76b5e5a50b43086d775beae05030fb @@ -0,0 +1 @@ +.0980800e380 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde b/fuzzing/seedcorpus/fuzz_string_constructors/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde new file mode 100644 index 000000000..343e70394 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde @@ -0,0 +1 @@ +11E9008 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5261321468029c1b74871d194c013ec37d81e535 b/fuzzing/seedcorpus/fuzz_string_constructors/5261321468029c1b74871d194c013ec37d81e535 new file mode 100644 index 000000000..80af26551 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/5261321468029c1b74871d194c013ec37d81e535 @@ -0,0 +1,665 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452+20 +9.249513618169916e+20 +1.2682867022928964e+20 +-1.6519723359317599e+20 +6.889407171550021e+20 +5.3134664312315315e+20 +4.031303588284793e+20 +-2.1613637661379455e+20 +1.7784108820391563e+20 +6.706920979119373e+20 +-4.8728731620211296e+20 +7.046654122801136e+20 +9.031763589209249e+298 +-6.667393980239736e+20 +-1.5544661716950814e+20 +-4.0932964584486145e+20 +5.017447491633736e+20 +-1.3244062462146727e+20 +9.578036372991541e+20 +-6.1939210136252056e+20 +4.892731000156886e+20 +-4.6529260937600666e+297 +9.502495704603882e+298 +-2.2063594459611994e+20 +-6.038208749234104e+20 +-7.77598826642031e+20 +-3.8982317740186627e+298 +9.936999057758508e+20 +-4.7156867841932675e+20 +-4.307496737860941e+20 +2.8136487748265513e+20 +3.207661828333713e+20 +6.885726461922003e+20 +-8.494322328697002e+20 +-6.96537527974915e+20 +3.992439250692351e+20 +-4.545388369963799e+20 +-3.568857941011303e+20 +-7.45703918817277e+20 +-2.2893364936941713e+20 +-8.305937318686903e+20 +-4.4922615212878616e+20 +9.576893876418487e+20 +1.5840061571645374e+298 +4.7122005167263046e+20 +-9.54210862628329e+20 +4.231167042030188e+20 +-8.332455871105299e+20 +-2.082488071655912e+20 +6.264272987329364e+20 +-8.805818396799334e+20 +-7.356302017604138e+298 +7.608321636405023e+20 +-7.621709836538286e+20 +8.012151340831442e+20 +-6.041395070658287e+20 +-9.835254480973173e+20 +7.660866830634293e+20 +-6.1004653614515325e+20 +8.205773323786566e+20 +2.380738496429448e+20 +2.2971533461629445e+298 +-7.23637992933319e+20 +-4.768646505358783e+20 +1.2182948366791039e+20 +-3.6766405590176256e+20 +-4.852546206781456e+20 +8.482910661381514e+20 +3.1605229425733825e+20 +-8.807197341322967e+20 +-8.154507730538936e+20 +-3.818984369569052e+20 +6.300920361535928e+20 +4.418660625743166e+20 +3.946715364866346e+20 +-5.764370827908914e+20 +6.583778980494807e+20 +-3.711939883959515e+20 +-9.875088422197167e+20 +-9.259898498020608e+298 +-4.695827532549615e+20 +-1.7991517675766077e+20 +-2.7184779742721584e+20 +6.691824176472904e+20 +6.014074759960023e+20 +1.728180556930459e+20 +9.106813588613468e+20 +-7.937256338332912e+20 +7.038877664612803e+20 +-4.262618560209215e+20 +6.897586384180638e+20 +-6.797568238203055e+20 +3.934124802864398e+20 +-9.344930818779545e+20 +6.469180277710322e+20 +-9.12849810813571e+20 +-7.63998758228186e+20 +1.9252692046031775e+297 +-8.531092871119897e+20 +-6.6413586723736346e+20 +-5.407989360019139e+20 +-2.5785271295759276e+20 +-7.204813485037936e+20 +-9.743349342454864e+20 +5.2921249376234796e+20 +4.491894660426444e+20 +6.283411956596571e+20 +3.1367542507972498e+20 +7.972850957397143e+20 +8.206243149438856e+298 +-5.591602094435806e+20 +6.788463179914664e+20 +2.9337737911439794e+20 +-7.188340734584389e+20 +4.754164463072329e+20 +1.8130784973589347e+20 +1.5698476224492605e+20 +-6.1906766667270024e+20 +-5.200739814776752e+20 +5.645115859874633e+20 +1.8488758923894827e+298 +-9.54367967575992e+20 +4.190495445812153e+20 +-7.344243187417514e+20 +4.719449218038303e+298 +-7.662541869845272e+298 +9.759253676812786e+20 +1.2002094489126975e+20 +2.082797160991275e+298 +-7.362477344994247e+20 +1.5293308478026481e+20 +-1.2859151718805565e+20 +9.063730085966921e+20 +-3.2019377284784837e+20 +9.02098384500453e+20 +6.2940235436754665e+20 +-6.809774301794948e+20 +-2.5646199064519987e+20 +-1.6984397998449136e+20 +-1.3959896238230378e+20 +5.848129204083652e+20 +-6.115078283596731e+20 +-9.469767249267403e+20 +-5.465066080972801e+20 +-1.018983191453689e+20 +-5.3656984330908425e+20 +-3.779105936122385e+20 +9.08480752372907e+298 +-3.577705684435664e+20 +-6.78774960850759e+20 +-1.0936515104206653e+20 +4.339576916974746e+20 +-4.426329021027551e+20 +-8.000202693590154e+20 +6.024350149656952e+20 +-7.770636888541607e+20 +7.58785648238528e+20 +-9.3650031707802e+20 +-6.826622844397532e+20 +-4.726062397587629e+20 +-1.0869456574437904e+20 +-6.938651641367466e+20 +7.102084528383604e+20 +-9.484983091302873e+20 +3.629382577013082e+20 +6.632889633029986e+20 +-7.981224060842942e+20 +4.82040640155586e+20 +3.937541518465696e+20 +-4.3415169481809014e+20 +-8.865040378415628e+20 +7.542982496147842e+20 +-8.309463037834162e+20 +4.1858607058534516e+20 +-4.93262076982169e+20 +8.732476911521904e+20 +-8.274643627890317e+20 +-2.817801131289268e+20 +-6.6763325098813396e+20 +1.886581909805573e+20 +-3.992271837038497e+20 +-1.425311443112795e+20 +-1.6376115465210254e+20 +1.6037554205764363e+20 +-1.883915462421392e+20 +4.908269724768685e+20 +7.799928142448986e+20 +7.216568107558704e+20 +8.011863346137072e+20 +-9.456085905031258e+20 +-3.91436344917693e+20 +-4.64718295132827e+20 +-5.639140138786214e+20 +-5.1451136955956045e+20 +-4.627965186133467e+20 +-1.4934282741369717e+20 +-9.070810059247394e+20 +8.975107637548961e+20 +-6.284829878605853e+298 +-2.2808635150518115e+20 +-6.6202338273593746e+20 +-4.5062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/52b2a004bed72a704176413fd834cd00873bc456 b/fuzzing/seedcorpus/fuzz_string_constructors/52b2a004bed72a704176413fd834cd00873bc456 new file mode 100644 index 000000000..a7da52d85 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/52b2a004bed72a704176413fd834cd00873bc456 @@ -0,0 +1 @@ +98073162e825 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/543633ccad478d5d5ba06d2fea0735bd53ef9314 b/fuzzing/seedcorpus/fuzz_string_constructors/543633ccad478d5d5ba06d2fea0735bd53ef9314 new file mode 100644 index 000000000..595635d34 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/543633ccad478d5d5ba06d2fea0735bd53ef9314 @@ -0,0 +1 @@ +98000080999999999999999999999999999008099999999999999999999999999999999999999989999& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/585420300c5e552abb25ea6687aa42832bde9566 b/fuzzing/seedcorpus/fuzz_string_constructors/585420300c5e552abb25ea6687aa42832bde9566 new file mode 100644 index 000000000..a404acd07 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/585420300c5e552abb25ea6687aa42832bde9566 @@ -0,0 +1 @@ +.0000000000000000000000000000000000000000000000000000000000000000 diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/58e6b3a414a1e090dfc6029add0f3555ccba127f b/fuzzing/seedcorpus/fuzz_string_constructors/58e6b3a414a1e090dfc6029add0f3555ccba127f new file mode 100644 index 000000000..9cbe6ea56 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/58e6b3a414a1e090dfc6029add0f3555ccba127f @@ -0,0 +1 @@ +e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/591ea6c66489b372cd7d5cfeca9635bf304b1aba b/fuzzing/seedcorpus/fuzz_string_constructors/591ea6c66489b372cd7d5cfeca9635bf304b1aba new file mode 100644 index 000000000..2f374ae75 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/591ea6c66489b372cd7d5cfeca9635bf304b1aba @@ -0,0 +1 @@ +39839803182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5a5a305194ac2a147006225e07dcf6ebb85496b0 b/fuzzing/seedcorpus/fuzz_string_constructors/5a5a305194ac2a147006225e07dcf6ebb85496b0 new file mode 100644 index 000000000..99aa3ddf4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/5a5a305194ac2a147006225e07dcf6ebb85496b0 @@ -0,0 +1 @@ +98080080999999999999999898999099999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 b/fuzzing/seedcorpus/fuzz_string_constructors/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 new file mode 100644 index 000000000..d0a3f8d03 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_string_constructors/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 differ diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/fuzzing/seedcorpus/fuzz_string_constructors/5ba93c9db0cff93f52b521d7420e43f6eda2784f new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_string_constructors/5ba93c9db0cff93f52b521d7420e43f6eda2784f differ diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5c84b425a991695560d74cae670364c6f3f4a5ad b/fuzzing/seedcorpus/fuzz_string_constructors/5c84b425a991695560d74cae670364c6f3f4a5ad new file mode 100644 index 000000000..1a727c825 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/5c84b425a991695560d74cae670364c6f3f4a5ad @@ -0,0 +1 @@ +3983980308281771 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/5efb4ac2212f109ebc889dc2a735f791dfc4119a b/fuzzing/seedcorpus/fuzz_string_constructors/5efb4ac2212f109ebc889dc2a735f791dfc4119a new file mode 100644 index 000000000..e11ef7961 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/5efb4ac2212f109ebc889dc2a735f791dfc4119a @@ -0,0 +1 @@ +na \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d b/fuzzing/seedcorpus/fuzz_string_constructors/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d new file mode 100644 index 000000000..f875c5bef --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d @@ -0,0 +1 @@ +9.800800000004991003.e980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf b/fuzzing/seedcorpus/fuzz_string_constructors/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf new file mode 100644 index 000000000..035341d84 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf @@ -0,0 +1 @@ +9808008084048 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/64de12dd467e1c72fb58db3fada825e68cfd5132 b/fuzzing/seedcorpus/fuzz_string_constructors/64de12dd467e1c72fb58db3fada825e68cfd5132 new file mode 100644 index 000000000..4bd3b395a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/64de12dd467e1c72fb58db3fada825e68cfd5132 @@ -0,0 +1 @@ +18E91 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/65792b52ff685ffafd7ecc18ef4960973722c180 b/fuzzing/seedcorpus/fuzz_string_constructors/65792b52ff685ffafd7ecc18ef4960973722c180 new file mode 100644 index 000000000..913d41139 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/65792b52ff685ffafd7ecc18ef4960973722c180 @@ -0,0 +1 @@ +980800809999899999999999999999999999999999999999999800$ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/6662616978c33d45880a9a1ebc7bfd146b4e4df2 b/fuzzing/seedcorpus/fuzz_string_constructors/6662616978c33d45880a9a1ebc7bfd146b4e4df2 new file mode 100644 index 000000000..ac0ca2720 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/6662616978c33d45880a9a1ebc7bfd146b4e4df2 @@ -0,0 +1,59 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/6818590a80af4f68f188567c7f01da00d6f7b406 b/fuzzing/seedcorpus/fuzz_string_constructors/6818590a80af4f68f188567c7f01da00d6f7b406 new file mode 100644 index 000000000..bca44dc95 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/6818590a80af4f68f188567c7f01da00d6f7b406 @@ -0,0 +1 @@ +.9759 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/68e36ae8cd6ca01f4489147651ab7a955e2c1889 b/fuzzing/seedcorpus/fuzz_string_constructors/68e36ae8cd6ca01f4489147651ab7a955e2c1889 new file mode 100644 index 000000000..d5ff67b3f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/68e36ae8cd6ca01f4489147651ab7a955e2c1889 @@ -0,0 +1 @@ +900080999999999999009998270331898018382.270350530.000999999270331898018382.270999999999999990080999999996999999999999999999008099999999999999998387.244994.999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 b/fuzzing/seedcorpus/fuzz_string_constructors/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 new file mode 100644 index 000000000..79c959e01 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 @@ -0,0 +1 @@ +98080080999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/692af001eeb377e753698444ff0f44fc3350b833 b/fuzzing/seedcorpus/fuzz_string_constructors/692af001eeb377e753698444ff0f44fc3350b833 new file mode 100644 index 000000000..31dc1ff07 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/692af001eeb377e753698444ff0f44fc3350b833 @@ -0,0 +1 @@ +39839803103887891839898398031868398031..........8.8...8..8..87 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/6ac006508b459de0cdf7989393f1969cccce95d3 b/fuzzing/seedcorpus/fuzz_string_constructors/6ac006508b459de0cdf7989393f1969cccce95d3 new file mode 100644 index 000000000..c0395000c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/6ac006508b459de0cdf7989393f1969cccce95d3 @@ -0,0 +1 @@ +000000000000000000000000000000002 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e b/fuzzing/seedcorpus/fuzz_string_constructors/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e new file mode 100644 index 000000000..d7db08785 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e @@ -0,0 +1 @@ +9e7038 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/703c45d21c34eb4308838fba8508a81b19554305 b/fuzzing/seedcorpus/fuzz_string_constructors/703c45d21c34eb4308838fba8508a81b19554305 new file mode 100644 index 000000000..5851ec6d1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/703c45d21c34eb4308838fba8508a81b19554305 @@ -0,0 +1 @@ +3839803982033189.27039500903182730327231.1...25....1 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7151c7f46996d49977f91fc77e07abbc2c588465 b/fuzzing/seedcorpus/fuzz_string_constructors/7151c7f46996d49977f91fc77e07abbc2c588465 new file mode 100644 index 000000000..ee02a25ad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7151c7f46996d49977f91fc77e07abbc2c588465 @@ -0,0 +1 @@ +2E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 b/fuzzing/seedcorpus/fuzz_string_constructors/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 new file mode 100644 index 000000000..7056d5bfa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 @@ -0,0 +1 @@ +9309909 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e b/fuzzing/seedcorpus/fuzz_string_constructors/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e new file mode 100644 index 000000000..fe9439a9f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/758f46f0e0b518d15e68fe22a0147300e8991ead b/fuzzing/seedcorpus/fuzz_string_constructors/758f46f0e0b518d15e68fe22a0147300e8991ead new file mode 100644 index 000000000..5490ee71e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/758f46f0e0b518d15e68fe22a0147300e8991ead @@ -0,0 +1,337 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863738.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.58688861477743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 b/fuzzing/seedcorpus/fuzz_string_constructors/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 new file mode 100644 index 000000000..554c71604 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 @@ -0,0 +1 @@ +.80000082975589999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/781c0067ba29c4397ac28aba0d89647ff0f65735 b/fuzzing/seedcorpus/fuzz_string_constructors/781c0067ba29c4397ac28aba0d89647ff0f65735 new file mode 100644 index 000000000..f559a1308 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/781c0067ba29c4397ac28aba0d89647ff0f65735 @@ -0,0 +1 @@ +9900900000000083000000835868090830000000000000199999909999000000000000000199999909999000000000000000000000999999909999998090839964099640500000000000099999990999999809;0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 b/fuzzing/seedcorpus/fuzz_string_constructors/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 new file mode 100644 index 000000000..569164973 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 @@ -0,0 +1 @@ +8e7700365 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f b/fuzzing/seedcorpus/fuzz_string_constructors/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f new file mode 100644 index 000000000..9807597d1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f @@ -0,0 +1,2 @@ +999996008099999999e6128 + diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7b49679772bf91df9d8a39b7228b7efc1f31c528 b/fuzzing/seedcorpus/fuzz_string_constructors/7b49679772bf91df9d8a39b7228b7efc1f31c528 new file mode 100644 index 000000000..0e93421f9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7b49679772bf91df9d8a39b7228b7efc1f31c528 @@ -0,0 +1 @@ +.00 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7b760f16108b09bfd25133daff1f9dbc9b0ae59a b/fuzzing/seedcorpus/fuzz_string_constructors/7b760f16108b09bfd25133daff1f9dbc9b0ae59a new file mode 100644 index 000000000..581367656 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7b760f16108b09bfd25133daff1f9dbc9b0ae59a @@ -0,0 +1 @@ +nan( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7caa348e5a262dfbebc80293ec34cc3d7e03216b b/fuzzing/seedcorpus/fuzz_string_constructors/7caa348e5a262dfbebc80293ec34cc3d7e03216b new file mode 100644 index 000000000..fc943d0a1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7caa348e5a262dfbebc80293ec34cc3d7e03216b @@ -0,0 +1 @@ +iN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7d76bbbccad1b2c6fde44b627b0159943df3d5dd b/fuzzing/seedcorpus/fuzz_string_constructors/7d76bbbccad1b2c6fde44b627b0159943df3d5dd new file mode 100644 index 000000000..ff4d6896a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7d76bbbccad1b2c6fde44b627b0159943df3d5dd @@ -0,0 +1 @@ +89217264850542609780e8500 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7f99c619f89462fc52f924d1a228ca3f4a3d138b b/fuzzing/seedcorpus/fuzz_string_constructors/7f99c619f89462fc52f924d1a228ca3f4a3d138b new file mode 100644 index 000000000..fba38d645 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7f99c619f89462fc52f924d1a228ca3f4a3d138b @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7fbf94d02d1aae374eb05428081f03d682815b39 b/fuzzing/seedcorpus/fuzz_string_constructors/7fbf94d02d1aae374eb05428081f03d682815b39 new file mode 100644 index 000000000..b99a60d06 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7fbf94d02d1aae374eb05428081f03d682815b39 @@ -0,0 +1 @@ +1E4E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/7fde327828905d26b0ac416ddf0ab12f19a446e9 b/fuzzing/seedcorpus/fuzz_string_constructors/7fde327828905d26b0ac416ddf0ab12f19a446e9 new file mode 100644 index 000000000..04a1c1204 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/7fde327828905d26b0ac416ddf0ab12f19a446e9 @@ -0,0 +1 @@ +9080089999099808008999999999999999990998080 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8048c5fe212078cee25624251ab1ae3c5e052c47 b/fuzzing/seedcorpus/fuzz_string_constructors/8048c5fe212078cee25624251ab1ae3c5e052c47 new file mode 100644 index 000000000..77f672a97 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8048c5fe212078cee25624251ab1ae3c5e052c47 @@ -0,0 +1 @@ +.289198107924742306288 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/829f88fd420e51a15b0da7dd236791253f17941c b/fuzzing/seedcorpus/fuzz_string_constructors/829f88fd420e51a15b0da7dd236791253f17941c new file mode 100644 index 000000000..342189218 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/829f88fd420e51a15b0da7dd236791253f17941c @@ -0,0 +1 @@ +5657 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8437513ebed8de872fc0485d23088b653154a8e9 b/fuzzing/seedcorpus/fuzz_string_constructors/8437513ebed8de872fc0485d23088b653154a8e9 new file mode 100644 index 000000000..3623f47fa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8437513ebed8de872fc0485d23088b653154a8e9 @@ -0,0 +1 @@ +8.098080070394049091.e9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/843be429e0a89c2f936a6904bdb46afd70b4ae34 b/fuzzing/seedcorpus/fuzz_string_constructors/843be429e0a89c2f936a6904bdb46afd70b4ae34 new file mode 100644 index 000000000..08b0f6cb2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/843be429e0a89c2f936a6904bdb46afd70b4ae34 @@ -0,0 +1 @@ +90008099999999999999. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8508d752fd34c1a5050811cec00bdddd2925a27a b/fuzzing/seedcorpus/fuzz_string_constructors/8508d752fd34c1a5050811cec00bdddd2925a27a new file mode 100644 index 000000000..2452ac097 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8508d752fd34c1a5050811cec00bdddd2925a27a @@ -0,0 +1 @@ +389839803182727035059883944419191.27039....3...0....30................9.........3.... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/85245af25d1cccb311bd4eaa8b3d425d901ae1db b/fuzzing/seedcorpus/fuzz_string_constructors/85245af25d1cccb311bd4eaa8b3d425d901ae1db new file mode 100644 index 000000000..e3fc79ec7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/85245af25d1cccb311bd4eaa8b3d425d901ae1db @@ -0,0 +1 @@ +1241E93 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8557693b06fd90fe7f6f6ece9998b84f71db0e2f b/fuzzing/seedcorpus/fuzz_string_constructors/8557693b06fd90fe7f6f6ece9998b84f71db0e2f new file mode 100644 index 000000000..1e91d52b1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8557693b06fd90fe7f6f6ece9998b84f71db0e2f @@ -0,0 +1 @@ +9.0908080072e389 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/86242234de9c6d67558d8dd6413c19d389bbdaf4 b/fuzzing/seedcorpus/fuzz_string_constructors/86242234de9c6d67558d8dd6413c19d389bbdaf4 new file mode 100644 index 000000000..ef408df4e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/86242234de9c6d67558d8dd6413c19d389bbdaf4 @@ -0,0 +1 @@ +118080080999999999995E9999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/867e280aa29d13e3ef4b8db01558e80c21aa4084 b/fuzzing/seedcorpus/fuzz_string_constructors/867e280aa29d13e3ef4b8db01558e80c21aa4084 new file mode 100644 index 000000000..5b93bf239 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/867e280aa29d13e3ef4b8db01558e80c21aa4084 @@ -0,0 +1 @@ +21; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 b/fuzzing/seedcorpus/fuzz_string_constructors/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 new file mode 100644 index 000000000..eaed6941c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 @@ -0,0 +1 @@ +8e621 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/888a54ba1d2b757d43420ad105d045f9ddc8a198 b/fuzzing/seedcorpus/fuzz_string_constructors/888a54ba1d2b757d43420ad105d045f9ddc8a198 new file mode 100644 index 000000000..de3354b1b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/888a54ba1d2b757d43420ad105d045f9ddc8a198 @@ -0,0 +1 @@ +39370827031889938031......5.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/88f02424d2a77340a47cc10a18f212395dfbeca7 b/fuzzing/seedcorpus/fuzz_string_constructors/88f02424d2a77340a47cc10a18f212395dfbeca7 new file mode 100644 index 000000000..256e8551d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/88f02424d2a77340a47cc10a18f212395dfbeca7 @@ -0,0 +1 @@ +80000804199999999981.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/89ab4af0020e9385e986279e66b4d39057a0e0b5 b/fuzzing/seedcorpus/fuzz_string_constructors/89ab4af0020e9385e986279e66b4d39057a0e0b5 new file mode 100644 index 000000000..a378d4697 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/89ab4af0020e9385e986279e66b4d39057a0e0b5 @@ -0,0 +1 @@ +nAnA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 b/fuzzing/seedcorpus/fuzz_string_constructors/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 new file mode 100644 index 000000000..1b7e0b97c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 @@ -0,0 +1 @@ +7e000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa b/fuzzing/seedcorpus/fuzz_string_constructors/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa new file mode 100644 index 000000000..e870b7d1c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/906717bd5a741e7abafd6983f46e31840c75d374 b/fuzzing/seedcorpus/fuzz_string_constructors/906717bd5a741e7abafd6983f46e31840c75d374 new file mode 100644 index 000000000..b7e11d23f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/906717bd5a741e7abafd6983f46e31840c75d374 @@ -0,0 +1 @@ +nan(I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/91856e645abe70c73d21adb7142805cb4885635a b/fuzzing/seedcorpus/fuzz_string_constructors/91856e645abe70c73d21adb7142805cb4885635a new file mode 100644 index 000000000..fe2fff928 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/91856e645abe70c73d21adb7142805cb4885635a @@ -0,0 +1 @@ +398398031827033189839803182727035053182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 b/fuzzing/seedcorpus/fuzz_string_constructors/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 new file mode 100644 index 000000000..3314d5b14 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 @@ -0,0 +1 @@ +8e6218 diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 b/fuzzing/seedcorpus/fuzz_string_constructors/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 new file mode 100644 index 000000000..64a37a3df --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 @@ -0,0 +1 @@ +99999999999999999999999999009999999980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/95c7d319a8c481cdb6074924395d43f66bd1a6f6 b/fuzzing/seedcorpus/fuzz_string_constructors/95c7d319a8c481cdb6074924395d43f66bd1a6f6 new file mode 100644 index 000000000..025ba7008 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/95c7d319a8c481cdb6074924395d43f66bd1a6f6 @@ -0,0 +1 @@ +nan(s \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/9616cdce298b78ec414eca803a2ec88991d52768 b/fuzzing/seedcorpus/fuzz_string_constructors/9616cdce298b78ec414eca803a2ec88991d52768 new file mode 100644 index 000000000..35d0b09c1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/9616cdce298b78ec414eca803a2ec88991d52768 @@ -0,0 +1 @@ +398398318983988983981318283980318.27039500313182.270350530.00000.8.8125308.00000.827032.9803182.270350530.00000.8.8125308.00000.827039839803103183.270350533189839803182.270350530.9839803182.270350533189839803182.270350530.00000.50031827018939880313182.350530.0000839803182.27039500318270189839803182.2733189839803182.270350530.0000.8125308.00000.827189839803182.27035053318398703182.27270189839803182.270350533189839803182.270350530.00000.8.8125308.00000.827039839803103182.270175626594919901591.270350530.0000.8.8125308.00000.827039839803182.27035089839803182.270350530.00000.8.8125339803182.2703505339803182.27030000245072229420724091.27035053318983980318.27039500313182.270350530.00000.8.8125308.00000.827032.9803182.270350530.00000.8.8125308.00000.827039839803103182.270350533189839803182.270350530.00000.8.8125308.00000.827039839803182.27035089839803182.270350530.827039839803182.27035089839803122294230.00000.8.8125308.00000.8270355705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/961c2c349adf528f0927b419ea4336d73d72b44a b/fuzzing/seedcorpus/fuzz_string_constructors/961c2c349adf528f0927b419ea4336d73d72b44a new file mode 100644 index 000000000..d1ced3c30 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/961c2c349adf528f0927b419ea4336d73d72b44a @@ -0,0 +1 @@ +3939390318540655461.1..............0.0. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/971322b28fb8dc103df606be81a818edec69cf34 b/fuzzing/seedcorpus/fuzz_string_constructors/971322b28fb8dc103df606be81a818edec69cf34 new file mode 100644 index 000000000..f587f4796 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_string_constructors/971322b28fb8dc103df606be81a818edec69cf34 differ diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/985a9924dbc7a343f147bdd9b982a875750f167f b/fuzzing/seedcorpus/fuzz_string_constructors/985a9924dbc7a343f147bdd9b982a875750f167f new file mode 100644 index 000000000..e63781f35 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/985a9924dbc7a343f147bdd9b982a875750f167f @@ -0,0 +1 @@ +0000. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/9902d381a017c5c8ce22b819deee8efbe1e24f01 b/fuzzing/seedcorpus/fuzz_string_constructors/9902d381a017c5c8ce22b819deee8efbe1e24f01 new file mode 100644 index 000000000..186532917 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/9902d381a017c5c8ce22b819deee8efbe1e24f01 @@ -0,0 +1 @@ +3. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/99991a46f79e031e016f6b02b28cf8f62167dfca b/fuzzing/seedcorpus/fuzz_string_constructors/99991a46f79e031e016f6b02b28cf8f62167dfca new file mode 100644 index 000000000..3458c71b7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/99991a46f79e031e016f6b02b28cf8f62167dfca @@ -0,0 +1 @@ +00000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 b/fuzzing/seedcorpus/fuzz_string_constructors/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 new file mode 100644 index 000000000..82b1327e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 @@ -0,0 +1 @@ +2E98 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/9c37c6045ec3e1acc1281820aab4317ea2d110b3 b/fuzzing/seedcorpus/fuzz_string_constructors/9c37c6045ec3e1acc1281820aab4317ea2d110b3 new file mode 100644 index 000000000..451ed81e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/9c37c6045ec3e1acc1281820aab4317ea2d110b3 @@ -0,0 +1 @@ +.909999989 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/9d70c51941aa3a76bac12cefae2241edc09f8475 b/fuzzing/seedcorpus/fuzz_string_constructors/9d70c51941aa3a76bac12cefae2241edc09f8475 new file mode 100644 index 000000000..489799dfb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/9d70c51941aa3a76bac12cefae2241edc09f8475 @@ -0,0 +1 @@ +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a07058e7dbd3681dbb8500f714411399d1c9e9c7 b/fuzzing/seedcorpus/fuzz_string_constructors/a07058e7dbd3681dbb8500f714411399d1c9e9c7 new file mode 100644 index 000000000..4bc03a1e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a07058e7dbd3681dbb8500f714411399d1c9e9c7 @@ -0,0 +1 @@ +980000890999999999999099990809999999645.9545956 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 b/fuzzing/seedcorpus/fuzz_string_constructors/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 new file mode 100644 index 000000000..42f552841 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 @@ -0,0 +1 @@ +29e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a181caf6a5e4ca9750cd0f637b002ef09d023a17 b/fuzzing/seedcorpus/fuzz_string_constructors/a181caf6a5e4ca9750cd0f637b002ef09d023a17 new file mode 100644 index 000000000..24b4a94c0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a181caf6a5e4ca9750cd0f637b002ef09d023a17 @@ -0,0 +1 @@ +981808008040804; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 b/fuzzing/seedcorpus/fuzz_string_constructors/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 new file mode 100644 index 000000000..02c454b84 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 @@ -0,0 +1 @@ +9.09808008086209999999999999999999999909888 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a2692f525c304805e367dd45a114adf8b6d8f6b5 b/fuzzing/seedcorpus/fuzz_string_constructors/a2692f525c304805e367dd45a114adf8b6d8f6b5 new file mode 100644 index 000000000..b2e9a88e6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a2692f525c304805e367dd45a114adf8b6d8f6b5 @@ -0,0 +1 @@ +198136796964088908624288004000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a2ac47e1458897c2106586cd82ba4cf955250db9 b/fuzzing/seedcorpus/fuzz_string_constructors/a2ac47e1458897c2106586cd82ba4cf955250db9 new file mode 100644 index 000000000..3ce504130 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a2ac47e1458897c2106586cd82ba4cf955250db9 @@ -0,0 +1 @@ +i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a2baf6238ebf35764b4592a439b22737cf6b77a0 b/fuzzing/seedcorpus/fuzz_string_constructors/a2baf6238ebf35764b4592a439b22737cf6b77a0 new file mode 100644 index 000000000..173dd6f9a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a2baf6238ebf35764b4592a439b22737cf6b77a0 @@ -0,0 +1 @@ +11E997 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 b/fuzzing/seedcorpus/fuzz_string_constructors/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 new file mode 100644 index 000000000..7b9d05c74 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 @@ -0,0 +1 @@ +.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a6021c83979739c55bfe0b66628ac1d4457c4585 b/fuzzing/seedcorpus/fuzz_string_constructors/a6021c83979739c55bfe0b66628ac1d4457c4585 new file mode 100644 index 000000000..b8871b0d5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a6021c83979739c55bfe0b66628ac1d4457c4585 @@ -0,0 +1 @@ +8e770038 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a64b4e7c8770bdc235b86aeb32d8521db72a542b b/fuzzing/seedcorpus/fuzz_string_constructors/a64b4e7c8770bdc235b86aeb32d8521db72a542b new file mode 100644 index 000000000..499dd8298 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a64b4e7c8770bdc235b86aeb32d8521db72a542b @@ -0,0 +1,359 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 b/fuzzing/seedcorpus/fuzz_string_constructors/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 new file mode 100644 index 000000000..06d3ff7db --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 @@ -0,0 +1 @@ +18446744073709551618 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a7fced1fdbeb07582033148094f1deb7d171d16b b/fuzzing/seedcorpus/fuzz_string_constructors/a7fced1fdbeb07582033148094f1deb7d171d16b new file mode 100644 index 000000000..820db0263 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a7fced1fdbeb07582033148094f1deb7d171d16b @@ -0,0 +1 @@ +980002809999999990000009909180800239644.959226290442866 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a905df1efff3e9361d1f823fee642ef87ec1eb52 b/fuzzing/seedcorpus/fuzz_string_constructors/a905df1efff3e9361d1f823fee642ef87ec1eb52 new file mode 100644 index 000000000..054df32f3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a905df1efff3e9361d1f823fee642ef87ec1eb52 @@ -0,0 +1 @@ +9.098080070339938182.e920394 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c b/fuzzing/seedcorpus/fuzz_string_constructors/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c new file mode 100644 index 000000000..9b26e9b10 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c @@ -0,0 +1 @@ ++ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/adb06e660444a43e1033dc92fbcc32eb4cc95f3a b/fuzzing/seedcorpus/fuzz_string_constructors/adb06e660444a43e1033dc92fbcc32eb4cc95f3a new file mode 100644 index 000000000..1d62b7418 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/adb06e660444a43e1033dc92fbcc32eb4cc95f3a @@ -0,0 +1 @@ +9808080080999999999808008099 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/af10ef20dd9060bbeead0afbc55381a66af442ef b/fuzzing/seedcorpus/fuzz_string_constructors/af10ef20dd9060bbeead0afbc55381a66af442ef new file mode 100644 index 000000000..f087d8914 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/af10ef20dd9060bbeead0afbc55381a66af442ef @@ -0,0 +1 @@ +in \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/afc97ea131fd7e2695a98ef34013608f97f34e1d b/fuzzing/seedcorpus/fuzz_string_constructors/afc97ea131fd7e2695a98ef34013608f97f34e1d new file mode 100644 index 000000000..cf5106d72 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/afc97ea131fd7e2695a98ef34013608f97f34e1d @@ -0,0 +1 @@ +999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/b46dbafdabe8b0cff532f144835276bc1dbc1d8f b/fuzzing/seedcorpus/fuzz_string_constructors/b46dbafdabe8b0cff532f144835276bc1dbc1d8f new file mode 100644 index 000000000..0255bf130 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/b46dbafdabe8b0cff532f144835276bc1dbc1d8f @@ -0,0 +1,56 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86636 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.504 +-80A1581185.957868 +-3894457067.979211 +787240530.00000.8530.009997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.58203#15289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/b51a60734da64be0e618bacbea2865a8a7dcd669 b/fuzzing/seedcorpus/fuzz_string_constructors/b51a60734da64be0e618bacbea2865a8a7dcd669 new file mode 100644 index 000000000..2f94675b7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/b51a60734da64be0e618bacbea2865a8a7dcd669 @@ -0,0 +1 @@ +N \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/b57453fb3aa94518fa1a1915eaa874ae2368cc86 b/fuzzing/seedcorpus/fuzz_string_constructors/b57453fb3aa94518fa1a1915eaa874ae2368cc86 new file mode 100644 index 000000000..3e0f102f9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/b57453fb3aa94518fa1a1915eaa874ae2368cc86 @@ -0,0 +1 @@ +.e8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/b62b76505678b9d7e77475ca45fbc9f15deb61f7 b/fuzzing/seedcorpus/fuzz_string_constructors/b62b76505678b9d7e77475ca45fbc9f15deb61f7 new file mode 100644 index 000000000..f9abf3d9a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/b62b76505678b9d7e77475ca45fbc9f15deb61f7 @@ -0,0 +1 @@ +298120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c b/fuzzing/seedcorpus/fuzz_string_constructors/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c new file mode 100644 index 000000000..c22708346 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ba085e7b393a22d5bcf382b4673d66428b726131 b/fuzzing/seedcorpus/fuzz_string_constructors/ba085e7b393a22d5bcf382b4673d66428b726131 new file mode 100644 index 000000000..8cdc48997 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ba085e7b393a22d5bcf382b4673d66428b726131 @@ -0,0 +1 @@ +929e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/bb589d0621e5472f470fa3425a234c74b1e202e8 b/fuzzing/seedcorpus/fuzz_string_constructors/bb589d0621e5472f470fa3425a234c74b1e202e8 new file mode 100644 index 000000000..ad2823b48 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/bb589d0621e5472f470fa3425a234c74b1e202e8 @@ -0,0 +1 @@ +' \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/bdba068c531049e22ec9534cea647768cd265414 b/fuzzing/seedcorpus/fuzz_string_constructors/bdba068c531049e22ec9534cea647768cd265414 new file mode 100644 index 000000000..bc2c6d14c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/bdba068c531049e22ec9534cea647768cd265414 @@ -0,0 +1 @@ +18E998 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 b/fuzzing/seedcorpus/fuzz_string_constructors/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 new file mode 100644 index 000000000..37e9215ec --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 @@ -0,0 +1 @@ +2EE \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/be06cf696332b8261092aca2751daf12a4a3cd34 b/fuzzing/seedcorpus/fuzz_string_constructors/be06cf696332b8261092aca2751daf12a4a3cd34 new file mode 100644 index 000000000..7464f47e7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/be06cf696332b8261092aca2751daf12a4a3cd34 @@ -0,0 +1 @@ +9.09808008620999080080862099999999999999999999999990980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 b/fuzzing/seedcorpus/fuzz_string_constructors/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 new file mode 100644 index 000000000..c7d354934 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 @@ -0,0 +1 @@ +nA; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c202931b0efa026332e5048ba2dabd9ac9b0af2b b/fuzzing/seedcorpus/fuzz_string_constructors/c202931b0efa026332e5048ba2dabd9ac9b0af2b new file mode 100644 index 000000000..0148c2f32 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c202931b0efa026332e5048ba2dabd9ac9b0af2b @@ -0,0 +1 @@ +12980.000999999998008990899999999989908 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 b/fuzzing/seedcorpus/fuzz_string_constructors/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 new file mode 100644 index 000000000..244a1c972 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 @@ -0,0 +1 @@ +7e85 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c24dee1111bde34637da8f10e400ceddb47e1a42 b/fuzzing/seedcorpus/fuzz_string_constructors/c24dee1111bde34637da8f10e400ceddb47e1a42 new file mode 100644 index 000000000..54738b958 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c24dee1111bde34637da8f10e400ceddb47e1a42 @@ -0,0 +1 @@ +98080080999999999999999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c28dcb678244590d45bce1bab9e7f7a56b765056 b/fuzzing/seedcorpus/fuzz_string_constructors/c28dcb678244590d45bce1bab9e7f7a56b765056 new file mode 100644 index 000000000..a3bce0b72 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c28dcb678244590d45bce1bab9e7f7a56b765056 @@ -0,0 +1,253 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863738.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+28 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 b/fuzzing/seedcorpus/fuzz_string_constructors/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 new file mode 100644 index 000000000..c99b1a35a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 @@ -0,0 +1 @@ +9.098080800808608620999999999999999999990980999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/c50b8326c52e1f5a59d3549dec588af705b3bee8 b/fuzzing/seedcorpus/fuzz_string_constructors/c50b8326c52e1f5a59d3549dec588af705b3bee8 new file mode 100644 index 000000000..3eeb2b881 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/c50b8326c52e1f5a59d3549dec588af705b3bee8 @@ -0,0 +1 @@ +281239839808270330004662711377164635110.82 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ca73ab65568cd125c2d27a22bbd9e863c10b675d b/fuzzing/seedcorpus/fuzz_string_constructors/ca73ab65568cd125c2d27a22bbd9e863c10b675d new file mode 100644 index 000000000..b4158c40d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ca73ab65568cd125c2d27a22bbd9e863c10b675d @@ -0,0 +1 @@ +I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d b/fuzzing/seedcorpus/fuzz_string_constructors/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d new file mode 100644 index 000000000..a19920e57 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d @@ -0,0 +1 @@ +.8822 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/cc08b3ec1b721133a466105cbfe88eb0ed86d30f b/fuzzing/seedcorpus/fuzz_string_constructors/cc08b3ec1b721133a466105cbfe88eb0ed86d30f new file mode 100644 index 000000000..43f826b55 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/cc08b3ec1b721133a466105cbfe88eb0ed86d30f @@ -0,0 +1 @@ +.0000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 b/fuzzing/seedcorpus/fuzz_string_constructors/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 new file mode 100644 index 000000000..41ea2fa1e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 @@ -0,0 +1 @@ +9e0000. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/cd3e870b525405e2a233f805117ff55b4563144b b/fuzzing/seedcorpus/fuzz_string_constructors/cd3e870b525405e2a233f805117ff55b4563144b new file mode 100644 index 000000000..981aa2ee5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/cd3e870b525405e2a233f805117ff55b4563144b @@ -0,0 +1 @@ +9e+218 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 b/fuzzing/seedcorpus/fuzz_string_constructors/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 new file mode 100644 index 000000000..01f42e214 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 @@ -0,0 +1 @@ +9.098080186080000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/cfad63c69e4f84745060b1a1954fe688f65a552d b/fuzzing/seedcorpus/fuzz_string_constructors/cfad63c69e4f84745060b1a1954fe688f65a552d new file mode 100644 index 000000000..f4c0ea5be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/cfad63c69e4f84745060b1a1954fe688f65a552d @@ -0,0 +1 @@ +9e-9890 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d07e4bc786c88b8d2304f84c7db2098666f822c0 b/fuzzing/seedcorpus/fuzz_string_constructors/d07e4bc786c88b8d2304f84c7db2098666f822c0 new file mode 100644 index 000000000..5639b6ddc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d07e4bc786c88b8d2304f84c7db2098666f822c0 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e b/fuzzing/seedcorpus/fuzz_string_constructors/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e new file mode 100644 index 000000000..fcfe98db4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e @@ -0,0 +1 @@ +9e70799y \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d1854cae891ec7b29161ccaf79a24b00c274bdaa b/fuzzing/seedcorpus/fuzz_string_constructors/d1854cae891ec7b29161ccaf79a24b00c274bdaa new file mode 100644 index 000000000..ef073cc45 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d1854cae891ec7b29161ccaf79a24b00c274bdaa @@ -0,0 +1 @@ +n \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d281f13dedd0cc21f91ef0df57288227266e5973 b/fuzzing/seedcorpus/fuzz_string_constructors/d281f13dedd0cc21f91ef0df57288227266e5973 new file mode 100644 index 000000000..78e7f75a9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d281f13dedd0cc21f91ef0df57288227266e5973 @@ -0,0 +1 @@ +90e85368 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d533dd0d2c17d4dfeabd44a10e43b976bda9872a b/fuzzing/seedcorpus/fuzz_string_constructors/d533dd0d2c17d4dfeabd44a10e43b976bda9872a new file mode 100644 index 000000000..1f061e3dc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d533dd0d2c17d4dfeabd44a10e43b976bda9872a @@ -0,0 +1 @@ +4.094419906569906591.e81980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d53407c9291c2e34919523cd3b35ab291ae505d6 b/fuzzing/seedcorpus/fuzz_string_constructors/d53407c9291c2e34919523cd3b35ab291ae505d6 new file mode 100644 index 000000000..138864de9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d53407c9291c2e34919523cd3b35ab291ae505d6 @@ -0,0 +1 @@ +398938031827189839889839802701808139382.3....................3........... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d72b31bd2c612402b4575d33979f6bcb941a8b82 b/fuzzing/seedcorpus/fuzz_string_constructors/d72b31bd2c612402b4575d33979f6bcb941a8b82 new file mode 100644 index 000000000..bee387e46 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d72b31bd2c612402b4575d33979f6bcb941a8b82 @@ -0,0 +1,57 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.504 +-80A1581185.957868 +-3894457067.979211 +787240530.00000.8530.009997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/d9ec4c78aa727434495e91f497a8255ccfa2f51f b/fuzzing/seedcorpus/fuzz_string_constructors/d9ec4c78aa727434495e91f497a8255ccfa2f51f new file mode 100644 index 000000000..3afcaffad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/d9ec4c78aa727434495e91f497a8255ccfa2f51f @@ -0,0 +1 @@ +9e-990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/db1f77c2e01ab20855fa2513741f77e63d470439 b/fuzzing/seedcorpus/fuzz_string_constructors/db1f77c2e01ab20855fa2513741f77e63d470439 new file mode 100644 index 000000000..64c76f8e9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/db1f77c2e01ab20855fa2513741f77e63d470439 @@ -0,0 +1 @@ +9e00000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/dd6b1aaa2553c97b57eb1e0c553e3c38729936de b/fuzzing/seedcorpus/fuzz_string_constructors/dd6b1aaa2553c97b57eb1e0c553e3c38729936de new file mode 100644 index 000000000..d79664163 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/dd6b1aaa2553c97b57eb1e0c553e3c38729936de @@ -0,0 +1 @@ +2E- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/dde8fa867fad2d8c1163a10586ff602b5e06fc13 b/fuzzing/seedcorpus/fuzz_string_constructors/dde8fa867fad2d8c1163a10586ff602b5e06fc13 new file mode 100644 index 000000000..71bfddb15 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/dde8fa867fad2d8c1163a10586ff602b5e06fc13 @@ -0,0 +1,2 @@ +999999008099999999998e6128 +90 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/df79d037bf616251b47482ab444da97a1717fb94 b/fuzzing/seedcorpus/fuzz_string_constructors/df79d037bf616251b47482ab444da97a1717fb94 new file mode 100644 index 000000000..a9e56a0d6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/df79d037bf616251b47482ab444da97a1717fb94 @@ -0,0 +1 @@ +8070098498387.244994.e-9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e0184adedf913b076626646d3f52c3b49c39ad6d b/fuzzing/seedcorpus/fuzz_string_constructors/e0184adedf913b076626646d3f52c3b49c39ad6d new file mode 100644 index 000000000..9fb75b8d4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e0184adedf913b076626646d3f52c3b49c39ad6d @@ -0,0 +1 @@ +E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e0ce700f7251111e7de2a72c206bf8b8404c1625 b/fuzzing/seedcorpus/fuzz_string_constructors/e0ce700f7251111e7de2a72c206bf8b8404c1625 new file mode 100644 index 000000000..a913e89be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e0ce700f7251111e7de2a72c206bf8b8404c1625 @@ -0,0 +1 @@ +281239839803180318272703505312398398031.8227033199803182727035053.82705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 b/fuzzing/seedcorpus/fuzz_string_constructors/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 new file mode 100644 index 000000000..b413dfe0c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 @@ -0,0 +1 @@ +nan(i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e5cfb53dc80712e65116c90e68d89a2a949d283d b/fuzzing/seedcorpus/fuzz_string_constructors/e5cfb53dc80712e65116c90e68d89a2a949d283d new file mode 100644 index 000000000..2a30ccf3e Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_string_constructors/e5cfb53dc80712e65116c90e68d89a2a949d283d differ diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e6c141d1e0aa21c965231473af366d62ddd80c89 b/fuzzing/seedcorpus/fuzz_string_constructors/e6c141d1e0aa21c965231473af366d62ddd80c89 new file mode 100644 index 000000000..f07eeb10a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e6c141d1e0aa21c965231473af366d62ddd80c89 @@ -0,0 +1 @@ +2E199999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e81019bfd2f759c3e98e3040201a7659d6bd4cec b/fuzzing/seedcorpus/fuzz_string_constructors/e81019bfd2f759c3e98e3040201a7659d6bd4cec new file mode 100644 index 000000000..916d65c90 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e81019bfd2f759c3e98e3040201a7659d6bd4cec @@ -0,0 +1 @@ +39803182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/e8f81a39cfabffba92d7a164ce2449835ab33c3a b/fuzzing/seedcorpus/fuzz_string_constructors/e8f81a39cfabffba92d7a164ce2449835ab33c3a new file mode 100644 index 000000000..71176ef21 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/e8f81a39cfabffba92d7a164ce2449835ab33c3a @@ -0,0 +1 @@ +980083270 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ea2977e307197a2a61488c59648670df15979ef6 b/fuzzing/seedcorpus/fuzz_string_constructors/ea2977e307197a2a61488c59648670df15979ef6 new file mode 100644 index 000000000..1dd0624cb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ea2977e307197a2a61488c59648670df15979ef6 @@ -0,0 +1 @@ +9808008099999999999999990999999999408980e8534 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ec776842a2bcd5d045633a674526f7f32085e555 b/fuzzing/seedcorpus/fuzz_string_constructors/ec776842a2bcd5d045633a674526f7f32085e555 new file mode 100644 index 000000000..3ed26649f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ec776842a2bcd5d045633a674526f7f32085e555 @@ -0,0 +1 @@ +9180809180080080999999999999909999999999999044 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/eca59e5d9d93eaa3b8a3604431b27e213b961244 b/fuzzing/seedcorpus/fuzz_string_constructors/eca59e5d9d93eaa3b8a3604431b27e213b961244 new file mode 100644 index 000000000..d0407e4ab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/eca59e5d9d93eaa3b8a3604431b27e213b961244 @@ -0,0 +1,91 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 b/fuzzing/seedcorpus/fuzz_string_constructors/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 new file mode 100644 index 000000000..11d92a2bf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 @@ -0,0 +1 @@ +11808008099999999999999999999999998 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f3689a11195bec0993096768550b1ca19883c2bc b/fuzzing/seedcorpus/fuzz_string_constructors/f3689a11195bec0993096768550b1ca19883c2bc new file mode 100644 index 000000000..bba62cfd1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f3689a11195bec0993096768550b1ca19883c2bc @@ -0,0 +1 @@ +9E05 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f371163b0be7a0d6b619a4fe98581cc8a555a421 b/fuzzing/seedcorpus/fuzz_string_constructors/f371163b0be7a0d6b619a4fe98581cc8a555a421 new file mode 100644 index 000000000..13e4f2cfa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f371163b0be7a0d6b619a4fe98581cc8a555a421 @@ -0,0 +1 @@ +98370350570338031820.1........................3..3...3...............0..................8. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f54338af0ebb664c1370622680defda872bc7c32 b/fuzzing/seedcorpus/fuzz_string_constructors/f54338af0ebb664c1370622680defda872bc7c32 new file mode 100644 index 000000000..7039a8060 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f54338af0ebb664c1370622680defda872bc7c32 @@ -0,0 +1 @@ +9e0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f58080c4f5bc8f14e0d148832483f3996a4d7393 b/fuzzing/seedcorpus/fuzz_string_constructors/f58080c4f5bc8f14e0d148832483f3996a4d7393 new file mode 100644 index 000000000..a52cb3e46 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f58080c4f5bc8f14e0d148832483f3996a4d7393 @@ -0,0 +1 @@ +9800832700 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f5982a144fe613ac6849a6b43ed08baf52161f52 b/fuzzing/seedcorpus/fuzz_string_constructors/f5982a144fe613ac6849a6b43ed08baf52161f52 new file mode 100644 index 000000000..bd34de2f0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f5982a144fe613ac6849a6b43ed08baf52161f52 @@ -0,0 +1 @@ +iNF \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c b/fuzzing/seedcorpus/fuzz_string_constructors/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c new file mode 100644 index 000000000..cb4b00639 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c @@ -0,0 +1 @@ +128E92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c b/fuzzing/seedcorpus/fuzz_string_constructors/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c new file mode 100644 index 000000000..c5ceb2f4a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c @@ -0,0 +1 @@ +.Z \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/f8be78b0d0194e487c8e219d809ec875ad70772c b/fuzzing/seedcorpus/fuzz_string_constructors/f8be78b0d0194e487c8e219d809ec875ad70772c new file mode 100644 index 000000000..a7bd3d31c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/f8be78b0d0194e487c8e219d809ec875ad70772c @@ -0,0 +1 @@ +980800809999999999999999999999999000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fa60d9942f9385dcced990bf13d2fd3511f8c505 b/fuzzing/seedcorpus/fuzz_string_constructors/fa60d9942f9385dcced990bf13d2fd3511f8c505 new file mode 100644 index 000000000..6040820db --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fa60d9942f9385dcced990bf13d2fd3511f8c505 @@ -0,0 +1 @@ +398398031827033189839803182727035053.82705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/faf1631572e1d19b59a96de1bb71d047fdd030d5 b/fuzzing/seedcorpus/fuzz_string_constructors/faf1631572e1d19b59a96de1bb71d047fdd030d5 new file mode 100644 index 000000000..d361d6a36 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/faf1631572e1d19b59a96de1bb71d047fdd030d5 @@ -0,0 +1 @@ +9e9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fb0c125a2486b9707a53b731ba012af4e3789cb5 b/fuzzing/seedcorpus/fuzz_string_constructors/fb0c125a2486b9707a53b731ba012af4e3789cb5 new file mode 100644 index 000000000..3eed846e4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fb0c125a2486b9707a53b731ba012af4e3789cb5 @@ -0,0 +1 @@ +8e0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fb6c14b8efa4f8844872f33db91f5b8195c43136 b/fuzzing/seedcorpus/fuzz_string_constructors/fb6c14b8efa4f8844872f33db91f5b8195c43136 new file mode 100644 index 000000000..8df71c9c5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fb6c14b8efa4f8844872f33db91f5b8195c43136 @@ -0,0 +1 @@ +nan( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fbde7ce9657042789e40729235b79eb676cec72d b/fuzzing/seedcorpus/fuzz_string_constructors/fbde7ce9657042789e40729235b79eb676cec72d new file mode 100644 index 000000000..2b340399c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fbde7ce9657042789e40729235b79eb676cec72d @@ -0,0 +1 @@ +980809810809999999999999999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fde7ea94eb806031185e8b4596be747a521a80cc b/fuzzing/seedcorpus/fuzz_string_constructors/fde7ea94eb806031185e8b4596be747a521a80cc new file mode 100644 index 000000000..e21954863 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fde7ea94eb806031185e8b4596be747a521a80cc @@ -0,0 +1 @@ +39839803182703182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/fea3b29291b269898651be5c1b719cb12cc031cf b/fuzzing/seedcorpus/fuzz_string_constructors/fea3b29291b269898651be5c1b719cb12cc031cf new file mode 100644 index 000000000..244c1e82b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/fea3b29291b269898651be5c1b719cb12cc031cf @@ -0,0 +1 @@ +98120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/ff672df6d83863b94c711a5ca44ea4d61660ca06 b/fuzzing/seedcorpus/fuzz_string_constructors/ff672df6d83863b94c711a5ca44ea4d61660ca06 new file mode 100644 index 000000000..f47f54ce2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/ff672df6d83863b94c711a5ca44ea4d61660ca06 @@ -0,0 +1 @@ +999999999999999999999999999999999994 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_string_constructors/strtod.txt b/fuzzing/seedcorpus/fuzz_string_constructors/strtod.txt new file mode 100644 index 000000000..da1cd7be6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_string_constructors/strtod.txt @@ -0,0 +1,991 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452 +-6989049626.595518 +-4656828161.473779 +9763680224.51627 +9751951081.686802 +-337738879.7371044 +-3218308721.9295416 +5316866140.38973 +253140072.20806503 +-67015884.19111252 +-4145941047.9776325 +9982650191.863255 +-4805195750.912774 +2007631436.0563717 +-1336980163.13908 +3876768555.2980576 +6369274349.731985 +714573945.7687016 +8217335015.851101 +-7220020049.135553 +-1375882154.3342018 +-7965288568.390052 +-4972087297.866529 +-9617862443.628145 +4847618299.542833 +-8064903300.436237 +4916757135.607399 +515751419.4691963 +9215353924.090961 +-364913989.2347889 +-3507329283.0497313 +1317810244.4926357 +-7295868652.742394 +6876470676.15094 +-2438584710.5560446 +7832150646.9747505 +8400914366.011929 +1239217006.5196457 +6751063909.677446 +-8090155725.787666 +-791010118.7786922 +-5761208048.211159 +-2168171518.217272 +157362439.9876709 +-9381050662.044998 +8463512975.957085 +-8942516901.275276 +3082320494.2169495 +1724377540.4461613 +7891183680.86731 +2768052907.1448727 +9622664872.800652 +1364929177.6346016 +2438745344.650511 +-8880072185.722937 +-6613261965.832544 +8413085097.502716 +4088601626.3673477 +6574025563.215904 +-4496754459.192869 +-2814059126.8972635 +4825485746.352711 +464568475.3084049 +-4498633535.888028 +-7225560661.85226 +-3221258349.00179 +5420486017.349937 +4323332602.043682 +-3964379910.549527 +-8222017305.183034 +-4650765900.672444 +-2191806433.5125217 +-2721890544.328933 +5717273607.065279 +-28422478.223329544 +4212720813.701809 +5311208464.502592 +3225483549.0651913 +-9788638244.599714 +-3077024169.4503174 +7411855396.694576 +-9054016057.921425 +6534847129.909836 +-8143145194.103385 +9188388528.00267 +5250026150.321932 +-8975805075.502327 +969935862.4870129 +-8707655672.63136 +5467137200.623861 +-5780239257.465727 +-3409155374.6815004 +-4095011398.0845385 +7253745994.176674 +-7161651473.528198 +-7849491793.200878 +4828368247.266005 +8914484950.901321 +-9115356835.02289 +-8225833870.461037 +-2539903677.6078243 +4294051454.55299 +-1853640047.8603191 +-1112420684.1528187 +4810742993.5433235 +4053102452.6137695 +3592594405.398941 +-7926418595.777629 +2145393045.0870895 +-5739192900.8195915 +-4408654069.571105 +-4371124148.663783 +7743510829.925953 +-1261382088.5091038 +2581814671.28006 +-7039298048.791871 +-8076767027.845224 +4329518147.451557 +1161621381.1248627 +1208250030.101286 +-6534218378.205525 +5114456196.548088 +4088022020.578598 +8992977247.728653 +-5097582856.498999 +9886148343.725456 +9912642453.119267 +3719453860.4919453 +7078570223.815897 +624118266.2463989 +863886173.3964558 +-1932314022.626196 +-4949766274.704357 +1728676263.0908527 +3655675109.9528294 +677889306.7410755 +-4604582434.624218 +6852562064.798929 +-5073083424.205593 +-1310860351.7890434 +9076521028.02076 +-6795320982.856365 +-815720359.5432167 +3469105793.853657 +369526499.6803398 +-8116569459.547374 +-2185814709.778287 +-3041629136.8767996 +-5346460950.374048 +2620956357.0461655 +-7377613242.535397 +1533795868.133503 +-4375472275.006776 +4044440867.6627426 +9503935866.642864 +-173165501.02918053 +3204021627.0289707 +-9106488941.48659 +4640411716.87112 +-3855456670.21 +1806278957.86557 +-7719725766.293733 +4870997554.669283 +-2645372770.749628 +1412833844.6981277 +3235738635.1283627 +-5467691529.236322 +8423135631.25145 +4366804024.218529 +7475317508.951164 +-6729951259.834599 +-3042731230.1005173 +-8052832339.079965 +-9910878365.52365 +-1406785809.4684315 +1325159253.5445614 +5899318569.084028 +-7335586270.0054455 +2722923617.737646 +1965337620.4644394 +6687202389.800978 +4625471957.369957 +-1627665340.1117573 +-8705574779.906586 +-4020333220.7047033 +-168217295.5267563 +1353090961.899828 +-5673224931.216288 +-8840443040.525124 +-7842962545.884165 +-1635234877.4911537 +-5086175166.746623 +-5190316401.77241 +6885977762.7181015 +6670679088.13579 +9377637707.2052 +4740081906.320965 +-9855927038.85421 +-393083365.2558689 +1930287943.1776905 +-2593616140.4156933 +6973281423.628536 +-1785710158.250329 +-143515758.43083954 +-9165566885.262552 +-3271947075.442127 +1866146881.2823467 +9922318687.247532 +2105889374.9543476 +1412191145.1990738 +4899253184.97513 +-4963639159.271849 +8618179390.053493 +-4270177979.582361 +6055692117.72047 +323727457.89961624 +-1997101808.7895699 +5636742008.106144 +4691147693.264648 +-1339528188.4935036 +-5129832360.937038 +-7851471851.588366 +5036450555.008472 +-2531325190.1094837 +-4269349462.4435883 +-9714134709.103092 +-1759752342.380949 +-2786309738.9712315 +8482952443.393608 +-1767831217.3464785 +-9591336055.176716 +6235445085.696083 +-4558818055.646798 +-4746793816.840109 +-4656884038.338767 +8283627521.822033 +7271616925.880337 +-4975594184.59415 +5719936545.010145 +3926786838.1136494 +-1573054519.4802885 +-5528363043.595613 +-8159000612.363343 +-3072957148.7078047 +3079220817.911688 +-8458471846.61787 +-9222562952.799414 +-1587906788.0184402 +2845544102.5235634 +7892509404.137733 +-8394088799.434449 +-8871970975.653664 +6878128182.769302 +-2977407410.038788 +-6725749678.392197 +9254656545.983723 +6289186404.1730995 +5128165261.277636 +-5241260072.736095 +6917249801.302614 +-7568111942.267646 +-6857866820.515381 +8962461589.683685 +-5729987652.684038 +1471350203.0483437 +-9729367141.66414 +2395854137.699234 +7749640698.397217 +-2110788646.8097095 +-2186817857.724968 +-9.12434048525892e+20 +-2.487370407039252e+20 +7.059778770319386e+20 +-1.1474292187493714e+20 +7.543787358849793e+20 +4.613801268236794e+20 +-9.335581580814339e+20 +-4.957887898426344e+298 +-9.055478281801209e+20 +-5.970115306346393e+20 +9.305909352849319e+20 +2.803715496169754e+20 +-7.615729522564583e+20 +4.805477501654648e+20 +5.795519629478846e+20 +-9.21243319444016e+20 +-4.609469937594853e+20 +-6.193080224477834e+20 +-5.700305838705103e+20 +-4.248046351482304e+20 +-8.397645239040469e+20 +2.3180271918597217e+20 +-9.024561143823087e+20 +3.346012550814175e+298 +-1.824696985453855e+20 +2.191788368665382e+20 +-1.1839345825514319e+20 +9.745729914146592e+298 +2.7052142748551614e+20 +2.2397355687783092e+20 +7.464393825326926e+20 +3.6095471425709134e+20 +6.185764994658908e+20 +-7.969301933095325e+20 +9.76581643819547e+20 +1.2436474804223092e+20 +-8.225774544713958e+20 +6.24089075862213e+20 +-4.851016699851025e+20 +-2.52483406820521e+298 +-3.2710997184048525e+20 +4.096171191739356e+20 +-7.489582215906195e+20 +4.696202482613724e+20 +-4.994493874866151e+20 +1.4727069872766155e+20 +6.950743059992088e+298 +-7.303027799337066e+20 +3.1392666170561626e+20 +5.763760463074156e+20 +-9.05402716337512e+20 +-3.349737925024725e+20 +-9.947524209836941e+298 +-6.990178120287133e+20 +-9.450759011476229e+20 +7.533474877574206e+20 +5.297356088600568e+20 +9.249513618169916e+20 +1.2682867022928964e+20 +-1.6519723359317599e+20 +6.889407171550021e+20 +5.3134664312315315e+20 +4.031303588284793e+20 +-2.1613637661379455e+20 +1.7784108820391563e+20 +6.706920979119373e+20 +-4.8728731620211296e+20 +7.046654122801136e+20 +9.031763589209249e+298 +-6.667393980239736e+20 +-1.5544661716950814e+20 +-4.0932964584486145e+20 +5.017447491633736e+20 +-1.3244062462146727e+20 +9.578036372991541e+20 +-6.1939210136252056e+20 +4.892731000156886e+20 +-4.6529260937600666e+297 +9.502495704603882e+298 +-2.2063594459611994e+20 +-6.038208749234104e+20 +-7.77598826642031e+20 +-3.8982317740186627e+298 +9.936999057758508e+20 +-4.7156867841932675e+20 +-4.307496737860941e+20 +2.8136487748265513e+20 +3.207661828333713e+20 +6.885726461922003e+20 +-8.494322328697002e+20 +-6.96537527974915e+20 +3.992439250692351e+20 +-4.545388369963799e+20 +-3.568857941011303e+20 +-7.45703918817277e+20 +-2.2893364936941713e+20 +-8.305937318686903e+20 +-4.4922615212878616e+20 +9.576893876418487e+20 +1.5840061571645374e+298 +4.7122005167263046e+20 +-9.54210862628329e+20 +4.231167042030188e+20 +-8.332455871105299e+20 +-2.082488071655912e+20 +6.264272987329364e+20 +-8.805818396799334e+20 +-7.356302017604138e+298 +7.608321636405023e+20 +-7.621709836538286e+20 +8.012151340831442e+20 +-6.041395070658287e+20 +-9.835254480973173e+20 +7.660866830634293e+20 +-6.1004653614515325e+20 +8.205773323786566e+20 +2.380738496429448e+20 +2.2971533461629445e+298 +-7.23637992933319e+20 +-4.768646505358783e+20 +1.2182948366791039e+20 +-3.6766405590176256e+20 +-4.852546206781456e+20 +8.482910661381514e+20 +3.1605229425733825e+20 +-8.807197341322967e+20 +-8.154507730538936e+20 +-3.818984369569052e+20 +6.300920361535928e+20 +4.418660625743166e+20 +3.946715364866346e+20 +-5.764370827908914e+20 +6.583778980494807e+20 +-3.711939883959515e+20 +-9.875088422197167e+20 +-9.259898498020608e+298 +-4.695827532549615e+20 +-1.7991517675766077e+20 +-2.7184779742721584e+20 +6.691824176472904e+20 +6.014074759960023e+20 +1.728180556930459e+20 +9.106813588613468e+20 +-7.937256338332912e+20 +7.038877664612803e+20 +-4.262618560209215e+20 +6.897586384180638e+20 +-6.797568238203055e+20 +3.934124802864398e+20 +-9.344930818779545e+20 +6.469180277710322e+20 +-9.12849810813571e+20 +-7.63998758228186e+20 +1.9252692046031775e+297 +-8.531092871119897e+20 +-6.6413586723736346e+20 +-5.407989360019139e+20 +-2.5785271295759276e+20 +-7.204813485037936e+20 +-9.743349342454864e+20 +5.2921249376234796e+20 +4.491894660426444e+20 +6.283411956596571e+20 +3.1367542507972498e+20 +7.972850957397143e+20 +8.206243149438856e+298 +-5.591602094435806e+20 +6.788463179914664e+20 +2.9337737911439794e+20 +-7.188340734584389e+20 +4.754164463072329e+20 +1.8130784973589347e+20 +1.5698476224492605e+20 +-6.1906766667270024e+20 +-5.200739814776752e+20 +5.645115859874633e+20 +1.8488758923894827e+298 +-9.54367967575992e+20 +4.190495445812153e+20 +-7.344243187417514e+20 +4.719449218038303e+298 +-7.662541869845272e+298 +9.759253676812786e+20 +1.2002094489126975e+20 +2.082797160991275e+298 +-7.362477344994247e+20 +1.5293308478026481e+20 +-1.2859151718805565e+20 +9.063730085966921e+20 +-3.2019377284784837e+20 +9.02098384500453e+20 +6.2940235436754665e+20 +-6.809774301794948e+20 +-2.5646199064519987e+20 +-1.6984397998449136e+20 +-1.3959896238230378e+20 +5.848129204083652e+20 +-6.115078283596731e+20 +-9.469767249267403e+20 +-5.465066080972801e+20 +-1.018983191453689e+20 +-5.3656984330908425e+20 +-3.779105936122385e+20 +9.08480752372907e+298 +-3.577705684435664e+20 +-6.78774960850759e+20 +-1.0936515104206653e+20 +4.339576916974746e+20 +-4.426329021027551e+20 +-8.000202693590154e+20 +6.024350149656952e+20 +-7.770636888541607e+20 +7.58785648238528e+20 +-9.3650031707802e+20 +-6.826622844397532e+20 +-4.726062397587629e+20 +-1.0869456574437904e+20 +-6.938651641367466e+20 +7.102084528383604e+20 +-9.484983091302873e+20 +3.629382577013082e+20 +6.632889633029986e+20 +-7.981224060842942e+20 +4.82040640155586e+20 +3.937541518465696e+20 +-4.3415169481809014e+20 +-8.865040378415628e+20 +7.542982496147842e+20 +-8.309463037834162e+20 +4.1858607058534516e+20 +-4.93262076982169e+20 +8.732476911521904e+20 +-8.274643627890317e+20 +-2.817801131289268e+20 +-6.6763325098813396e+20 +1.886581909805573e+20 +-3.992271837038497e+20 +-1.425311443112795e+20 +-1.6376115465210254e+20 +1.6037554205764363e+20 +-1.883915462421392e+20 +4.908269724768685e+20 +7.799928142448986e+20 +7.216568107558704e+20 +8.011863346137072e+20 +-9.456085905031258e+20 +-3.91436344917693e+20 +-4.64718295132827e+20 +-5.639140138786214e+20 +-5.1451136955956045e+20 +-4.627965186133467e+20 +-1.4934282741369717e+20 +-9.070810059247394e+20 +8.975107637548961e+20 +-6.284829878605853e+298 +-2.2808635150518115e+20 +-6.6202338273593746e+20 +-4.5062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/00ec59afdc843654416b3b7ca3e5f4b08376a26c b/fuzzing/seedcorpus/fuzz_strtod/00ec59afdc843654416b3b7ca3e5f4b08376a26c new file mode 100644 index 000000000..486f3e8b2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/00ec59afdc843654416b3b7ca3e5f4b08376a26c @@ -0,0 +1 @@ +iNf \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/01d6c69124e8ed4a5baf4f7d843004fbddb8707c b/fuzzing/seedcorpus/fuzz_strtod/01d6c69124e8ed4a5baf4f7d843004fbddb8707c new file mode 100644 index 000000000..609b14826 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/01d6c69124e8ed4a5baf4f7d843004fbddb8707c @@ -0,0 +1 @@ +.00000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 b/fuzzing/seedcorpus/fuzz_strtod/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 new file mode 100644 index 000000000..e49da69a9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0368c968bee483f7bbf6a9a8f2f7f34607c7e338 @@ -0,0 +1 @@ +33980318289839803182.270350031827033189839803182.270350530.00000.8530.00.82703505705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/03e473c16fb04cd9879ae0680ff7e4d574761548 b/fuzzing/seedcorpus/fuzz_strtod/03e473c16fb04cd9879ae0680ff7e4d574761548 new file mode 100644 index 000000000..143a57709 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_strtod/03e473c16fb04cd9879ae0680ff7e4d574761548 differ diff --git a/fuzzing/seedcorpus/fuzz_strtod/042dc4512fa3d391c5170cf3aa61e6a638f84342 b/fuzzing/seedcorpus/fuzz_strtod/042dc4512fa3d391c5170cf3aa61e6a638f84342 new file mode 100644 index 000000000..597a6db29 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/042dc4512fa3d391c5170cf3aa61e6a638f84342 @@ -0,0 +1 @@ +i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/081adf20bfe36db540138c8cbcdb900330f1db51 b/fuzzing/seedcorpus/fuzz_strtod/081adf20bfe36db540138c8cbcdb900330f1db51 new file mode 100644 index 000000000..f3a254771 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/081adf20bfe36db540138c8cbcdb900330f1db51 @@ -0,0 +1 @@ +988098198120061999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/08a27570f77898e8db880bb05e7a807f2a32f829 b/fuzzing/seedcorpus/fuzz_strtod/08a27570f77898e8db880bb05e7a807f2a32f829 new file mode 100644 index 000000000..b28daaa12 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/08a27570f77898e8db880bb05e7a807f2a32f829 @@ -0,0 +1 @@ +198398031827331627035 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/099bee553bdbaebb02d3743dae75c701fc1b690a b/fuzzing/seedcorpus/fuzz_strtod/099bee553bdbaebb02d3743dae75c701fc1b690a new file mode 100644 index 000000000..8e2b775cb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/099bee553bdbaebb02d3743dae75c701fc1b690a @@ -0,0 +1 @@ +9.090080079839813141.e8198 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0a129aaaa1f3a215450f61ebc46bf664160d7588 b/fuzzing/seedcorpus/fuzz_strtod/0a129aaaa1f3a215450f61ebc46bf664160d7588 new file mode 100644 index 000000000..3a660b1ee --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0a129aaaa1f3a215450f61ebc46bf664160d7588 @@ -0,0 +1 @@ +2e003 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0ad1fd13c204b07abb2409078fee4c00c8d6e39a b/fuzzing/seedcorpus/fuzz_strtod/0ad1fd13c204b07abb2409078fee4c00c8d6e39a new file mode 100644 index 000000000..60aa4dc0a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0ad1fd13c204b07abb2409078fee4c00c8d6e39a @@ -0,0 +1 @@ +281398392803182703318908398031872035053.8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 b/fuzzing/seedcorpus/fuzz_strtod/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0ade7c2cf97f75d009975f4d720d1fa6c19f4897 @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0c7371813bd3bf7d5a835770f71a1d6763b3c00a b/fuzzing/seedcorpus/fuzz_strtod/0c7371813bd3bf7d5a835770f71a1d6763b3c00a new file mode 100644 index 000000000..9c910c1d5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0c7371813bd3bf7d5a835770f71a1d6763b3c00a @@ -0,0 +1 @@ +3.790000909999180800809999999999999999919/ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0df5f797909ef949331359a34c7bbcfc3188b96c b/fuzzing/seedcorpus/fuzz_strtod/0df5f797909ef949331359a34c7bbcfc3188b96c new file mode 100644 index 000000000..aa8be1fb5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0df5f797909ef949331359a34c7bbcfc3188b96c @@ -0,0 +1 @@ +3.7918080080991808008099999999000000000000000000000000000000000017371412905560592406 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 b/fuzzing/seedcorpus/fuzz_strtod/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 new file mode 100644 index 000000000..d03bc1cf0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0f58d5a5515f1a8a9d179aa58858b67b2f8a3388 @@ -0,0 +1 @@ +000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/0ff84737c510827e1d12442378abbfe26ef2569d b/fuzzing/seedcorpus/fuzz_strtod/0ff84737c510827e1d12442378abbfe26ef2569d new file mode 100644 index 000000000..ea0807e60 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/0ff84737c510827e1d12442378abbfe26ef2569d @@ -0,0 +1,2 @@ +99999996008099999998e6128 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 b/fuzzing/seedcorpus/fuzz_strtod/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 new file mode 100644 index 000000000..b094ced12 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/11a1dc7eb8827b70a0ad451f09ac419f0d2f5856 @@ -0,0 +1 @@ +39839803172833183981.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/11e623a37e87cf7995c466723ec99688d55cae8c b/fuzzing/seedcorpus/fuzz_strtod/11e623a37e87cf7995c466723ec99688d55cae8c new file mode 100644 index 000000000..0982929c5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/11e623a37e87cf7995c466723ec99688d55cae8c @@ -0,0 +1 @@ +nan \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a b/fuzzing/seedcorpus/fuzz_strtod/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a new file mode 100644 index 000000000..30548b723 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1278bdde31408f557fcd5cc68ac640b4fa0bbc3a @@ -0,0 +1 @@ +281239839803182731890839803182727035053.825 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/15346b593c4d0cf05fb6e67a5669d852e6550481 b/fuzzing/seedcorpus/fuzz_strtod/15346b593c4d0cf05fb6e67a5669d852e6550481 new file mode 100644 index 000000000..85f98a55b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/15346b593c4d0cf05fb6e67a5669d852e6550481 @@ -0,0 +1 @@ +007 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/160799451addefa79541671e7b54cd69a56ddb77 b/fuzzing/seedcorpus/fuzz_strtod/160799451addefa79541671e7b54cd69a56ddb77 new file mode 100644 index 000000000..4ab479ea9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/160799451addefa79541671e7b54cd69a56ddb77 @@ -0,0 +1 @@ +281200000000000000008297558344909248599. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1a4be11edda0564776f09ed1e58f074f67a3ee1c b/fuzzing/seedcorpus/fuzz_strtod/1a4be11edda0564776f09ed1e58f074f67a3ee1c new file mode 100644 index 000000000..1c7bae85b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1a4be11edda0564776f09ed1e58f074f67a3ee1c @@ -0,0 +1 @@ +39039500318270189839803533182.2703503500.1..........................................190.01........................00...7..................4.......................................3 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e b/fuzzing/seedcorpus/fuzz_strtod/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e new file mode 100644 index 000000000..1c82e33d0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1bb15ba0d01116b9b7ea0903ca32d13cd4c1114e @@ -0,0 +1 @@ +n \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1bc2d3fdbed8be5af148c372a93d3f448587b171 b/fuzzing/seedcorpus/fuzz_strtod/1bc2d3fdbed8be5af148c372a93d3f448587b171 new file mode 100644 index 000000000..b27684f01 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1bc2d3fdbed8be5af148c372a93d3f448587b171 @@ -0,0 +1,57 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +889810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181536167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 b/fuzzing/seedcorpus/fuzz_strtod/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 new file mode 100644 index 000000000..524bdf192 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1c3869e8bfa8204fc4ca12598ce8d87335838cf2 @@ -0,0 +1 @@ +2E12# \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1d2706e66694c4a168db8c00963e978aedbe3001 b/fuzzing/seedcorpus/fuzz_strtod/1d2706e66694c4a168db8c00963e978aedbe3001 new file mode 100644 index 000000000..4297f847a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1d2706e66694c4a168db8c00963e978aedbe3001 @@ -0,0 +1,86 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +889810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130t05205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +34090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/1d542ab3fcee910bafef3179394c31572c4ea7bd b/fuzzing/seedcorpus/fuzz_strtod/1d542ab3fcee910bafef3179394c31572c4ea7bd new file mode 100644 index 000000000..a951e05f3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/1d542ab3fcee910bafef3179394c31572c4ea7bd @@ -0,0 +1 @@ +8e772 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/21006037389470e0d8a02503c389647711d53fed b/fuzzing/seedcorpus/fuzz_strtod/21006037389470e0d8a02503c389647711d53fed new file mode 100644 index 000000000..467c04108 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/21006037389470e0d8a02503c389647711d53fed @@ -0,0 +1 @@ +8e853693m \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 b/fuzzing/seedcorpus/fuzz_strtod/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 new file mode 100644 index 000000000..334395d7e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/21b2e84c3dfd340320f35bb4bb8a348f74e41d50 @@ -0,0 +1 @@ +9e000000000000000000000000000000002 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/21da4ee5a3b7442cb299d27c7983806be538c101 b/fuzzing/seedcorpus/fuzz_strtod/21da4ee5a3b7442cb299d27c7983806be538c101 new file mode 100644 index 000000000..f1af80071 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/21da4ee5a3b7442cb299d27c7983806be538c101 @@ -0,0 +1 @@ +8e-998200 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/225f840511ff1f547609cff02568ca66e73f5776 b/fuzzing/seedcorpus/fuzz_strtod/225f840511ff1f547609cff02568ca66e73f5776 new file mode 100644 index 000000000..43a86fc64 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/225f840511ff1f547609cff02568ca66e73f5776 @@ -0,0 +1 @@ +in \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd b/fuzzing/seedcorpus/fuzz_strtod/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd new file mode 100644 index 000000000..356ec7d8c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/22838cdce94b7ad4ee1f0275c5605f302e4dc8bd @@ -0,0 +1 @@ +98698622; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/23790de4fdddf42c06f2564d65fe9a5d660a2b46 b/fuzzing/seedcorpus/fuzz_strtod/23790de4fdddf42c06f2564d65fe9a5d660a2b46 new file mode 100644 index 000000000..fd180176a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/23790de4fdddf42c06f2564d65fe9a5d660a2b46 @@ -0,0 +1 @@ +.809999998008980089999901836 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/25add3f5bfca228c15d4feaf213c4eadc18b3a69 b/fuzzing/seedcorpus/fuzz_strtod/25add3f5bfca228c15d4feaf213c4eadc18b3a69 new file mode 100644 index 000000000..ec60d2823 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/25add3f5bfca228c15d4feaf213c4eadc18b3a69 @@ -0,0 +1 @@ +98803983180312.20899.e30 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/25b0d22b32d8a8c839dc9cf223153d8bed908b55 b/fuzzing/seedcorpus/fuzz_strtod/25b0d22b32d8a8c839dc9cf223153d8bed908b55 new file mode 100644 index 000000000..83f9aeda6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/25b0d22b32d8a8c839dc9cf223153d8bed908b55 @@ -0,0 +1,90 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 b/fuzzing/seedcorpus/fuzz_strtod/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 new file mode 100644 index 000000000..9d76fd4bf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/28b8c22f91d6d8f0ea2511cdf29ede5e7ab4ab94 @@ -0,0 +1 @@ +9.098080080862099999800008099999999999999999999999900809999999999999900999999990080999999999999999999999999999999999999999999999000000000000000000000000000000001563499; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/29118d615211d612244a09bf294725003ceca7f3 b/fuzzing/seedcorpus/fuzz_strtod/29118d615211d612244a09bf294725003ceca7f3 new file mode 100644 index 000000000..a72122458 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/29118d615211d612244a09bf294725003ceca7f3 @@ -0,0 +1 @@ +1.00872e379 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/296876f1180f368065683614d27bfe752442f3cf b/fuzzing/seedcorpus/fuzz_strtod/296876f1180f368065683614d27bfe752442f3cf new file mode 100644 index 000000000..02aefdb5d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/296876f1180f368065683614d27bfe752442f3cf @@ -0,0 +1 @@ +99999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/2a805b6d7eeee930096a8313c82960ca415f925d b/fuzzing/seedcorpus/fuzz_strtod/2a805b6d7eeee930096a8313c82960ca415f925d new file mode 100644 index 000000000..3a213c1ac --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/2a805b6d7eeee930096a8313c82960ca415f925d @@ -0,0 +1 @@ +.80909999999090999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/2b8dcee20b962f5f8b415b1c07f6233160203e2a b/fuzzing/seedcorpus/fuzz_strtod/2b8dcee20b962f5f8b415b1c07f6233160203e2a new file mode 100644 index 000000000..ef6cb50b1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/2b8dcee20b962f5f8b415b1c07f6233160203e2a @@ -0,0 +1 @@ +.000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 b/fuzzing/seedcorpus/fuzz_strtod/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 new file mode 100644 index 000000000..1c8a0e797 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/2d14ab97cc3dc294c51c0d6814f4ea45f4b4e312 @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3150b232402b5f20f0bb0278d552baf288dcd57d b/fuzzing/seedcorpus/fuzz_strtod/3150b232402b5f20f0bb0278d552baf288dcd57d new file mode 100644 index 000000000..dd2d6cb7e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3150b232402b5f20f0bb0278d552baf288dcd57d @@ -0,0 +1 @@ +980800804804 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/33abc754e958ae3d372d5cab62c15485ea4f1c1d b/fuzzing/seedcorpus/fuzz_strtod/33abc754e958ae3d372d5cab62c15485ea4f1c1d new file mode 100644 index 000000000..18bd554bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/33abc754e958ae3d372d5cab62c15485ea4f1c1d @@ -0,0 +1 @@ +.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/33eb8904073f449247417c7f31d125ef1d8b38fe b/fuzzing/seedcorpus/fuzz_strtod/33eb8904073f449247417c7f31d125ef1d8b38fe new file mode 100644 index 000000000..cf5162160 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/33eb8904073f449247417c7f31d125ef1d8b38fe @@ -0,0 +1 @@ +.0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 b/fuzzing/seedcorpus/fuzz_strtod/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 new file mode 100644 index 000000000..c2f016d67 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/354f7a870c4dc8ba496a3e0a6afd4186e40b6658 @@ -0,0 +1 @@ +3791808009999999999988000089999999000000000791808009999999999980000000000000000001747 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f b/fuzzing/seedcorpus/fuzz_strtod/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f new file mode 100644 index 000000000..34ff322e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/37654c325b5c6032fa0fef14c4552b5c4a4d2b7f @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/395df8f7c51f007019cb30201c49e884b46b92fa b/fuzzing/seedcorpus/fuzz_strtod/395df8f7c51f007019cb30201c49e884b46b92fa new file mode 100644 index 000000000..fa7af8bf5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/395df8f7c51f007019cb30201c49e884b46b92fa @@ -0,0 +1 @@ +z \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/39dfa55283318d31afe5a3ff4a0e3253e2045e43 b/fuzzing/seedcorpus/fuzz_strtod/39dfa55283318d31afe5a3ff4a0e3253e2045e43 new file mode 100644 index 000000000..af2e09a3e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/39dfa55283318d31afe5a3ff4a0e3253e2045e43 @@ -0,0 +1 @@ +0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3a189510f050347bbb9224ef01a3f143e8e13584 b/fuzzing/seedcorpus/fuzz_strtod/3a189510f050347bbb9224ef01a3f143e8e13584 new file mode 100644 index 000000000..09fef86bb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3a189510f050347bbb9224ef01a3f143e8e13584 @@ -0,0 +1 @@ +9e0000000000000000000000000000000000000000000000000000000000000000& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3a52ce780950d4d969792a2559cd519d7ee8c727 b/fuzzing/seedcorpus/fuzz_strtod/3a52ce780950d4d969792a2559cd519d7ee8c727 new file mode 100644 index 000000000..945c9b46d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3a52ce780950d4d969792a2559cd519d7ee8c727 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3a6611b8aa5c8485db9ed8be845118890f7ffc28 b/fuzzing/seedcorpus/fuzz_strtod/3a6611b8aa5c8485db9ed8be845118890f7ffc28 new file mode 100644 index 000000000..831bbf528 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3a6611b8aa5c8485db9ed8be845118890f7ffc28 @@ -0,0 +1 @@ +.E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 b/fuzzing/seedcorpus/fuzz_strtod/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 new file mode 100644 index 000000000..41ac62ab8 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3a6b5d3b20cfc9045f94c730067cd2a7200b18c0 @@ -0,0 +1 @@ +98008087 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 b/fuzzing/seedcorpus/fuzz_strtod/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 new file mode 100644 index 000000000..3cf20d57b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3bc15c8aae3e4124dd409035f32ea2fd6835efc9 @@ -0,0 +1 @@ +- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3c0526bf781d7b905b018dd399e07d3e614405d8 b/fuzzing/seedcorpus/fuzz_strtod/3c0526bf781d7b905b018dd399e07d3e614405d8 new file mode 100644 index 000000000..af37bbe68 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3c0526bf781d7b905b018dd399e07d3e614405d8 @@ -0,0 +1 @@ +3.79880089089180000080707564239575326730 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 b/fuzzing/seedcorpus/fuzz_strtod/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 new file mode 100644 index 000000000..d36759ac7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3dfe66c5ee6904ccfbc5355eaa426b08da1efed5 @@ -0,0 +1 @@ +990800809999999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3f001396ecde47550f65396e5d8daaa0c0ca4743 b/fuzzing/seedcorpus/fuzz_strtod/3f001396ecde47550f65396e5d8daaa0c0ca4743 new file mode 100644 index 000000000..8f5855b1b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3f001396ecde47550f65396e5d8daaa0c0ca4743 @@ -0,0 +1 @@ +98e370 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3f16364fd3234c947f326acda17fafe9333288fe b/fuzzing/seedcorpus/fuzz_strtod/3f16364fd3234c947f326acda17fafe9333288fe new file mode 100644 index 000000000..44dd0c9f1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3f16364fd3234c947f326acda17fafe9333288fe @@ -0,0 +1 @@ +200000000000000000007665596919578706393...8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/3f7b47892beaa319e4d5b3d811d96e99003a20f1 b/fuzzing/seedcorpus/fuzz_strtod/3f7b47892beaa319e4d5b3d811d96e99003a20f1 new file mode 100644 index 000000000..9633dcce0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/3f7b47892beaa319e4d5b3d811d96e99003a20f1 @@ -0,0 +1 @@ +nA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4012c69af25c0f38d8688b2fea8546c1b6a8df30 b/fuzzing/seedcorpus/fuzz_strtod/4012c69af25c0f38d8688b2fea8546c1b6a8df30 new file mode 100644 index 000000000..4538d0199 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4012c69af25c0f38d8688b2fea8546c1b6a8df30 @@ -0,0 +1 @@ +30318270331839803182.2703503.1205705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e b/fuzzing/seedcorpus/fuzz_strtod/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e new file mode 100644 index 000000000..6502b1cab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4088fb4c77a3c3c0d1b67f03499cb79dd2b57d1e @@ -0,0 +1 @@ +98000073679041073457386 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/40eb4486d987429dde612bab82832cddb27ade49 b/fuzzing/seedcorpus/fuzz_strtod/40eb4486d987429dde612bab82832cddb27ade49 new file mode 100644 index 000000000..cb4282be4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/40eb4486d987429dde612bab82832cddb27ade49 @@ -0,0 +1 @@ +.98998989 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/42f01bdd3606222ee7afec06a1d4e439c6f9572d b/fuzzing/seedcorpus/fuzz_strtod/42f01bdd3606222ee7afec06a1d4e439c6f9572d new file mode 100644 index 000000000..428fb095a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/42f01bdd3606222ee7afec06a1d4e439c6f9572d @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4624ea4856bed4781dc7ed75d583549ca4994e21 b/fuzzing/seedcorpus/fuzz_strtod/4624ea4856bed4781dc7ed75d583549ca4994e21 new file mode 100644 index 000000000..3d5221074 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4624ea4856bed4781dc7ed75d583549ca4994e21 @@ -0,0 +1 @@ +nan(S \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 b/fuzzing/seedcorpus/fuzz_strtod/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 new file mode 100644 index 000000000..9e0697c4b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4867cf63ba9aa2e6c0d3f85cb3799ee5bd6a6c43 @@ -0,0 +1 @@ +.000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/486ae2d9b52d66199e10a7b3a2e6e98b2481853a b/fuzzing/seedcorpus/fuzz_strtod/486ae2d9b52d66199e10a7b3a2e6e98b2481853a new file mode 100644 index 000000000..344444f66 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/486ae2d9b52d66199e10a7b3a2e6e98b2481853a @@ -0,0 +1 @@ +0000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/488f555086ccf62c3248f7def32d1166c2b4b9da b/fuzzing/seedcorpus/fuzz_strtod/488f555086ccf62c3248f7def32d1166c2b4b9da new file mode 100644 index 000000000..b6a133631 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/488f555086ccf62c3248f7def32d1166c2b4b9da @@ -0,0 +1 @@ +980800804995999949930 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 b/fuzzing/seedcorpus/fuzz_strtod/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 new file mode 100644 index 000000000..571eaf288 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/48d8b9f1851e28a60d91e79e1ae0fccc1cbdff58 @@ -0,0 +1 @@ +.048 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4adc138f92e999e212bb40016d3efbe312457e8b b/fuzzing/seedcorpus/fuzz_strtod/4adc138f92e999e212bb40016d3efbe312457e8b new file mode 100644 index 000000000..50188ec1c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4adc138f92e999e212bb40016d3efbe312457e8b @@ -0,0 +1 @@ +98000080999999980000809999999999999999999999999990080999999999999990099999999008999999999999999999999999999999999999008099999999999999999999999008099999999999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 b/fuzzing/seedcorpus/fuzz_strtod/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 new file mode 100644 index 000000000..a2e672167 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4afa9a5905939f3ab43b9634d3b26c9a94a87cb9 @@ -0,0 +1 @@ +28919808532693711565736 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4b2a410256e782bef9dbd6c3ae20a75b61602137 b/fuzzing/seedcorpus/fuzz_strtod/4b2a410256e782bef9dbd6c3ae20a75b61602137 new file mode 100644 index 000000000..9a7fb6108 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4b2a410256e782bef9dbd6c3ae20a75b61602137 @@ -0,0 +1 @@ +nAN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4b4b0b325326d4188f894d7e4f3b90e58bb88294 b/fuzzing/seedcorpus/fuzz_strtod/4b4b0b325326d4188f894d7e4f3b90e58bb88294 new file mode 100644 index 000000000..e8bf0eca2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4b4b0b325326d4188f894d7e4f3b90e58bb88294 @@ -0,0 +1 @@ +98085369371565736 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea b/fuzzing/seedcorpus/fuzz_strtod/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea new file mode 100644 index 000000000..17af5987a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4cb5c7ad3176d0d3d321f94d456fa11f95ce3aea @@ -0,0 +1 @@ +9999008099999999998e6128 diff --git a/fuzzing/seedcorpus/fuzz_strtod/4cc95fce8e76b5e5a50b43086d775beae05030fb b/fuzzing/seedcorpus/fuzz_strtod/4cc95fce8e76b5e5a50b43086d775beae05030fb new file mode 100644 index 000000000..4a7814ee5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/4cc95fce8e76b5e5a50b43086d775beae05030fb @@ -0,0 +1 @@ +.0980800e380 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde b/fuzzing/seedcorpus/fuzz_strtod/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde new file mode 100644 index 000000000..343e70394 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/51d2bb4c06fb65c2d8110a7d6eb445c0467adcde @@ -0,0 +1 @@ +11E9008 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/5261321468029c1b74871d194c013ec37d81e535 b/fuzzing/seedcorpus/fuzz_strtod/5261321468029c1b74871d194c013ec37d81e535 new file mode 100644 index 000000000..80af26551 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/5261321468029c1b74871d194c013ec37d81e535 @@ -0,0 +1,665 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.59212 +-5140434931.028948 +1291347902.382536 +2143389631.5744896 +5625590659.83761 +-400810168.17588997 +-1643549451.8078175 +1915698977.9557571 +-9705078636.016256 +-3259393351.6171303 +9980402523.415977 +9370863815.173698 +-6065763024.999098 +-731837984.3906708 +482204937.4413338 +5407687827.584879 +-9095241395.623558 +-7170919719.5120125 +1498537514.8390026 +3290246045.3495216 +-5862776307.19445 +-4792108572.06628 +-1657407221.1657858 +5179769430.57585 +-5277498862.210313 +9502025687.055431 +9127095580.829601 +-5166885222.381794 +-5142722131.617035 +85198772.19066429 +5999512504.67028 +2950167535.78706 +1724434926.0195599 +-461685711.2811775 +4064514289.7584114 +155977503.6039772 +-9131411887.221684 +6264429709.930468 +4918790568.632765 +-9758223087.908476 +-3370203827.9100657 +-9407108618.183048 +7436463505.383816 +8925872836.15746 +3415909901.822489 +-6225180480.5907955 +-729223218.1247368 +-9666849838.568687 +-4936092452.9210415 +2454227293.3521404 +6911082916.813517 +8917639570.099339 +-4175570161.4323206 +129706681.05668259 +-2972612357.725539 +4112219880.490652 +1120608858.7157574 +-1878675560.2178288 +-5851958847.808603 +-3834569271.5098686 +9974464303.486187 +-6234125901.390328 +-5704230775.793579 +3945233255.1335583 +-5240861496.47967 +-899767826.1207142 +3747927117.9332523 +-333524565.3329735 +2686842020.5887394 +-8303620678.741965 +-7694710148.881316 +6376657588.817335 +5125164486.633806 +5254512832.678324 +5610197046.113955 +-6478722037.439985 +-9561874112.801605 +-8173454935.984654 +-2521262409.862934 +-6826992236.890399 +-1697071384.5651388 +2069674230.9296799 +4661554438.893492 +5473996472.771767 +-8248961912.902115 +2567842784.261524 +9084912731.658218 +5297140851.247459 +-2973064858.748502 +4843495291.3372345 +9982928811.015408 +4950828258.523006 +-2770978365.4529247 +-6519977770.839958 +-326895032.8064461 +4531122793.149134 +-7133663611.324923 +-9166282833.002764 +4355364879.907223 +3117473978.1587677 +-5707544130.056734 +239546660.54986 +2897343145.4596615 +-3840172843.493888 +-7219075298.386128 +-9053482195.649452+20 +9.249513618169916e+20 +1.2682867022928964e+20 +-1.6519723359317599e+20 +6.889407171550021e+20 +5.3134664312315315e+20 +4.031303588284793e+20 +-2.1613637661379455e+20 +1.7784108820391563e+20 +6.706920979119373e+20 +-4.8728731620211296e+20 +7.046654122801136e+20 +9.031763589209249e+298 +-6.667393980239736e+20 +-1.5544661716950814e+20 +-4.0932964584486145e+20 +5.017447491633736e+20 +-1.3244062462146727e+20 +9.578036372991541e+20 +-6.1939210136252056e+20 +4.892731000156886e+20 +-4.6529260937600666e+297 +9.502495704603882e+298 +-2.2063594459611994e+20 +-6.038208749234104e+20 +-7.77598826642031e+20 +-3.8982317740186627e+298 +9.936999057758508e+20 +-4.7156867841932675e+20 +-4.307496737860941e+20 +2.8136487748265513e+20 +3.207661828333713e+20 +6.885726461922003e+20 +-8.494322328697002e+20 +-6.96537527974915e+20 +3.992439250692351e+20 +-4.545388369963799e+20 +-3.568857941011303e+20 +-7.45703918817277e+20 +-2.2893364936941713e+20 +-8.305937318686903e+20 +-4.4922615212878616e+20 +9.576893876418487e+20 +1.5840061571645374e+298 +4.7122005167263046e+20 +-9.54210862628329e+20 +4.231167042030188e+20 +-8.332455871105299e+20 +-2.082488071655912e+20 +6.264272987329364e+20 +-8.805818396799334e+20 +-7.356302017604138e+298 +7.608321636405023e+20 +-7.621709836538286e+20 +8.012151340831442e+20 +-6.041395070658287e+20 +-9.835254480973173e+20 +7.660866830634293e+20 +-6.1004653614515325e+20 +8.205773323786566e+20 +2.380738496429448e+20 +2.2971533461629445e+298 +-7.23637992933319e+20 +-4.768646505358783e+20 +1.2182948366791039e+20 +-3.6766405590176256e+20 +-4.852546206781456e+20 +8.482910661381514e+20 +3.1605229425733825e+20 +-8.807197341322967e+20 +-8.154507730538936e+20 +-3.818984369569052e+20 +6.300920361535928e+20 +4.418660625743166e+20 +3.946715364866346e+20 +-5.764370827908914e+20 +6.583778980494807e+20 +-3.711939883959515e+20 +-9.875088422197167e+20 +-9.259898498020608e+298 +-4.695827532549615e+20 +-1.7991517675766077e+20 +-2.7184779742721584e+20 +6.691824176472904e+20 +6.014074759960023e+20 +1.728180556930459e+20 +9.106813588613468e+20 +-7.937256338332912e+20 +7.038877664612803e+20 +-4.262618560209215e+20 +6.897586384180638e+20 +-6.797568238203055e+20 +3.934124802864398e+20 +-9.344930818779545e+20 +6.469180277710322e+20 +-9.12849810813571e+20 +-7.63998758228186e+20 +1.9252692046031775e+297 +-8.531092871119897e+20 +-6.6413586723736346e+20 +-5.407989360019139e+20 +-2.5785271295759276e+20 +-7.204813485037936e+20 +-9.743349342454864e+20 +5.2921249376234796e+20 +4.491894660426444e+20 +6.283411956596571e+20 +3.1367542507972498e+20 +7.972850957397143e+20 +8.206243149438856e+298 +-5.591602094435806e+20 +6.788463179914664e+20 +2.9337737911439794e+20 +-7.188340734584389e+20 +4.754164463072329e+20 +1.8130784973589347e+20 +1.5698476224492605e+20 +-6.1906766667270024e+20 +-5.200739814776752e+20 +5.645115859874633e+20 +1.8488758923894827e+298 +-9.54367967575992e+20 +4.190495445812153e+20 +-7.344243187417514e+20 +4.719449218038303e+298 +-7.662541869845272e+298 +9.759253676812786e+20 +1.2002094489126975e+20 +2.082797160991275e+298 +-7.362477344994247e+20 +1.5293308478026481e+20 +-1.2859151718805565e+20 +9.063730085966921e+20 +-3.2019377284784837e+20 +9.02098384500453e+20 +6.2940235436754665e+20 +-6.809774301794948e+20 +-2.5646199064519987e+20 +-1.6984397998449136e+20 +-1.3959896238230378e+20 +5.848129204083652e+20 +-6.115078283596731e+20 +-9.469767249267403e+20 +-5.465066080972801e+20 +-1.018983191453689e+20 +-5.3656984330908425e+20 +-3.779105936122385e+20 +9.08480752372907e+298 +-3.577705684435664e+20 +-6.78774960850759e+20 +-1.0936515104206653e+20 +4.339576916974746e+20 +-4.426329021027551e+20 +-8.000202693590154e+20 +6.024350149656952e+20 +-7.770636888541607e+20 +7.58785648238528e+20 +-9.3650031707802e+20 +-6.826622844397532e+20 +-4.726062397587629e+20 +-1.0869456574437904e+20 +-6.938651641367466e+20 +7.102084528383604e+20 +-9.484983091302873e+20 +3.629382577013082e+20 +6.632889633029986e+20 +-7.981224060842942e+20 +4.82040640155586e+20 +3.937541518465696e+20 +-4.3415169481809014e+20 +-8.865040378415628e+20 +7.542982496147842e+20 +-8.309463037834162e+20 +4.1858607058534516e+20 +-4.93262076982169e+20 +8.732476911521904e+20 +-8.274643627890317e+20 +-2.817801131289268e+20 +-6.6763325098813396e+20 +1.886581909805573e+20 +-3.992271837038497e+20 +-1.425311443112795e+20 +-1.6376115465210254e+20 +1.6037554205764363e+20 +-1.883915462421392e+20 +4.908269724768685e+20 +7.799928142448986e+20 +7.216568107558704e+20 +8.011863346137072e+20 +-9.456085905031258e+20 +-3.91436344917693e+20 +-4.64718295132827e+20 +-5.639140138786214e+20 +-5.1451136955956045e+20 +-4.627965186133467e+20 +-1.4934282741369717e+20 +-9.070810059247394e+20 +8.975107637548961e+20 +-6.284829878605853e+298 +-2.2808635150518115e+20 +-6.6202338273593746e+20 +-4.5062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/52b2a004bed72a704176413fd834cd00873bc456 b/fuzzing/seedcorpus/fuzz_strtod/52b2a004bed72a704176413fd834cd00873bc456 new file mode 100644 index 000000000..a7da52d85 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/52b2a004bed72a704176413fd834cd00873bc456 @@ -0,0 +1 @@ +98073162e825 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/543633ccad478d5d5ba06d2fea0735bd53ef9314 b/fuzzing/seedcorpus/fuzz_strtod/543633ccad478d5d5ba06d2fea0735bd53ef9314 new file mode 100644 index 000000000..595635d34 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/543633ccad478d5d5ba06d2fea0735bd53ef9314 @@ -0,0 +1 @@ +98000080999999999999999999999999999008099999999999999999999999999999999999999989999& \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/585420300c5e552abb25ea6687aa42832bde9566 b/fuzzing/seedcorpus/fuzz_strtod/585420300c5e552abb25ea6687aa42832bde9566 new file mode 100644 index 000000000..a404acd07 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/585420300c5e552abb25ea6687aa42832bde9566 @@ -0,0 +1 @@ +.0000000000000000000000000000000000000000000000000000000000000000 diff --git a/fuzzing/seedcorpus/fuzz_strtod/58e6b3a414a1e090dfc6029add0f3555ccba127f b/fuzzing/seedcorpus/fuzz_strtod/58e6b3a414a1e090dfc6029add0f3555ccba127f new file mode 100644 index 000000000..9cbe6ea56 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/58e6b3a414a1e090dfc6029add0f3555ccba127f @@ -0,0 +1 @@ +e \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/591ea6c66489b372cd7d5cfeca9635bf304b1aba b/fuzzing/seedcorpus/fuzz_strtod/591ea6c66489b372cd7d5cfeca9635bf304b1aba new file mode 100644 index 000000000..2f374ae75 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/591ea6c66489b372cd7d5cfeca9635bf304b1aba @@ -0,0 +1 @@ +39839803182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/5a5a305194ac2a147006225e07dcf6ebb85496b0 b/fuzzing/seedcorpus/fuzz_strtod/5a5a305194ac2a147006225e07dcf6ebb85496b0 new file mode 100644 index 000000000..99aa3ddf4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/5a5a305194ac2a147006225e07dcf6ebb85496b0 @@ -0,0 +1 @@ +98080080999999999999999898999099999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 b/fuzzing/seedcorpus/fuzz_strtod/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 new file mode 100644 index 000000000..d0a3f8d03 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_strtod/5b2f94a02fdd8340850b38e4af8a4c0aa7de3955 differ diff --git a/fuzzing/seedcorpus/fuzz_strtod/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/fuzzing/seedcorpus/fuzz_strtod/5ba93c9db0cff93f52b521d7420e43f6eda2784f new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_strtod/5ba93c9db0cff93f52b521d7420e43f6eda2784f differ diff --git a/fuzzing/seedcorpus/fuzz_strtod/5c84b425a991695560d74cae670364c6f3f4a5ad b/fuzzing/seedcorpus/fuzz_strtod/5c84b425a991695560d74cae670364c6f3f4a5ad new file mode 100644 index 000000000..1a727c825 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/5c84b425a991695560d74cae670364c6f3f4a5ad @@ -0,0 +1 @@ +3983980308281771 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/5efb4ac2212f109ebc889dc2a735f791dfc4119a b/fuzzing/seedcorpus/fuzz_strtod/5efb4ac2212f109ebc889dc2a735f791dfc4119a new file mode 100644 index 000000000..e11ef7961 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/5efb4ac2212f109ebc889dc2a735f791dfc4119a @@ -0,0 +1 @@ +na \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d b/fuzzing/seedcorpus/fuzz_strtod/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d new file mode 100644 index 000000000..f875c5bef --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/62b9b1c16b8225486d3d4cbe8a70cee4e05e0c4d @@ -0,0 +1 @@ +9.800800000004991003.e980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf b/fuzzing/seedcorpus/fuzz_strtod/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf new file mode 100644 index 000000000..035341d84 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/62f66b6f9b55f2f3d0f52f20241c4d2b718238bf @@ -0,0 +1 @@ +9808008084048 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/64de12dd467e1c72fb58db3fada825e68cfd5132 b/fuzzing/seedcorpus/fuzz_strtod/64de12dd467e1c72fb58db3fada825e68cfd5132 new file mode 100644 index 000000000..4bd3b395a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/64de12dd467e1c72fb58db3fada825e68cfd5132 @@ -0,0 +1 @@ +18E91 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/65792b52ff685ffafd7ecc18ef4960973722c180 b/fuzzing/seedcorpus/fuzz_strtod/65792b52ff685ffafd7ecc18ef4960973722c180 new file mode 100644 index 000000000..913d41139 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/65792b52ff685ffafd7ecc18ef4960973722c180 @@ -0,0 +1 @@ +980800809999899999999999999999999999999999999999999800$ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/6662616978c33d45880a9a1ebc7bfd146b4e4df2 b/fuzzing/seedcorpus/fuzz_strtod/6662616978c33d45880a9a1ebc7bfd146b4e4df2 new file mode 100644 index 000000000..ac0ca2720 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/6662616978c33d45880a9a1ebc7bfd146b4e4df2 @@ -0,0 +1,59 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902682397e-242 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/6818590a80af4f68f188567c7f01da00d6f7b406 b/fuzzing/seedcorpus/fuzz_strtod/6818590a80af4f68f188567c7f01da00d6f7b406 new file mode 100644 index 000000000..bca44dc95 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/6818590a80af4f68f188567c7f01da00d6f7b406 @@ -0,0 +1 @@ +.9759 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/68e36ae8cd6ca01f4489147651ab7a955e2c1889 b/fuzzing/seedcorpus/fuzz_strtod/68e36ae8cd6ca01f4489147651ab7a955e2c1889 new file mode 100644 index 000000000..d5ff67b3f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/68e36ae8cd6ca01f4489147651ab7a955e2c1889 @@ -0,0 +1 @@ +900080999999999999009998270331898018382.270350530.000999999270331898018382.270999999999999990080999999996999999999999999999008099999999999999998387.244994.999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 b/fuzzing/seedcorpus/fuzz_strtod/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 new file mode 100644 index 000000000..79c959e01 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/68e46b7a23e8d4ed511a70c3de54e00d4a28abc7 @@ -0,0 +1 @@ +98080080999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/692af001eeb377e753698444ff0f44fc3350b833 b/fuzzing/seedcorpus/fuzz_strtod/692af001eeb377e753698444ff0f44fc3350b833 new file mode 100644 index 000000000..31dc1ff07 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/692af001eeb377e753698444ff0f44fc3350b833 @@ -0,0 +1 @@ +39839803103887891839898398031868398031..........8.8...8..8..87 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/6ac006508b459de0cdf7989393f1969cccce95d3 b/fuzzing/seedcorpus/fuzz_strtod/6ac006508b459de0cdf7989393f1969cccce95d3 new file mode 100644 index 000000000..c0395000c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/6ac006508b459de0cdf7989393f1969cccce95d3 @@ -0,0 +1 @@ +000000000000000000000000000000002 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e b/fuzzing/seedcorpus/fuzz_strtod/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e new file mode 100644 index 000000000..d7db08785 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/6dbcf0e6d1b212ef79ca9dedd254c0cd24288e1e @@ -0,0 +1 @@ +9e7038 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/703c45d21c34eb4308838fba8508a81b19554305 b/fuzzing/seedcorpus/fuzz_strtod/703c45d21c34eb4308838fba8508a81b19554305 new file mode 100644 index 000000000..5851ec6d1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/703c45d21c34eb4308838fba8508a81b19554305 @@ -0,0 +1 @@ +3839803982033189.27039500903182730327231.1...25....1 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7151c7f46996d49977f91fc77e07abbc2c588465 b/fuzzing/seedcorpus/fuzz_strtod/7151c7f46996d49977f91fc77e07abbc2c588465 new file mode 100644 index 000000000..ee02a25ad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7151c7f46996d49977f91fc77e07abbc2c588465 @@ -0,0 +1 @@ +2E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 b/fuzzing/seedcorpus/fuzz_strtod/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 new file mode 100644 index 000000000..7056d5bfa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/716544ba6400193fe69b42c4ae0ff97f7af4b4b2 @@ -0,0 +1 @@ +9309909 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e b/fuzzing/seedcorpus/fuzz_strtod/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e new file mode 100644 index 000000000..fe9439a9f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/72768ef1f559e5d1dde8cb8304539fa67d1cfa8e @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/758f46f0e0b518d15e68fe22a0147300e8991ead b/fuzzing/seedcorpus/fuzz_strtod/758f46f0e0b518d15e68fe22a0147300e8991ead new file mode 100644 index 000000000..5490ee71e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/758f46f0e0b518d15e68fe22a0147300e8991ead @@ -0,0 +1,337 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863738.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.58688861477743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 b/fuzzing/seedcorpus/fuzz_strtod/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 new file mode 100644 index 000000000..554c71604 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/76cb7e0c51cdcfbdf8aca69e0702c3006d4497b0 @@ -0,0 +1 @@ +.80000082975589999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/781c0067ba29c4397ac28aba0d89647ff0f65735 b/fuzzing/seedcorpus/fuzz_strtod/781c0067ba29c4397ac28aba0d89647ff0f65735 new file mode 100644 index 000000000..f559a1308 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/781c0067ba29c4397ac28aba0d89647ff0f65735 @@ -0,0 +1 @@ +9900900000000083000000835868090830000000000000199999909999000000000000000199999909999000000000000000000000999999909999998090839964099640500000000000099999990999999809;0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 b/fuzzing/seedcorpus/fuzz_strtod/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 new file mode 100644 index 000000000..569164973 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/79a1fb30ead6e23c5f71c2b78b7470da2f2ee3b8 @@ -0,0 +1 @@ +8e7700365 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f b/fuzzing/seedcorpus/fuzz_strtod/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f new file mode 100644 index 000000000..9807597d1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7ae264f5f4d85b75634c08c075f93a4f1d6fdc6f @@ -0,0 +1,2 @@ +999996008099999999e6128 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/7b49679772bf91df9d8a39b7228b7efc1f31c528 b/fuzzing/seedcorpus/fuzz_strtod/7b49679772bf91df9d8a39b7228b7efc1f31c528 new file mode 100644 index 000000000..0e93421f9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7b49679772bf91df9d8a39b7228b7efc1f31c528 @@ -0,0 +1 @@ +.00 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7b760f16108b09bfd25133daff1f9dbc9b0ae59a b/fuzzing/seedcorpus/fuzz_strtod/7b760f16108b09bfd25133daff1f9dbc9b0ae59a new file mode 100644 index 000000000..581367656 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7b760f16108b09bfd25133daff1f9dbc9b0ae59a @@ -0,0 +1 @@ +nan( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7caa348e5a262dfbebc80293ec34cc3d7e03216b b/fuzzing/seedcorpus/fuzz_strtod/7caa348e5a262dfbebc80293ec34cc3d7e03216b new file mode 100644 index 000000000..fc943d0a1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7caa348e5a262dfbebc80293ec34cc3d7e03216b @@ -0,0 +1 @@ +iN \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7d76bbbccad1b2c6fde44b627b0159943df3d5dd b/fuzzing/seedcorpus/fuzz_strtod/7d76bbbccad1b2c6fde44b627b0159943df3d5dd new file mode 100644 index 000000000..ff4d6896a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7d76bbbccad1b2c6fde44b627b0159943df3d5dd @@ -0,0 +1 @@ +89217264850542609780e8500 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7f99c619f89462fc52f924d1a228ca3f4a3d138b b/fuzzing/seedcorpus/fuzz_strtod/7f99c619f89462fc52f924d1a228ca3f4a3d138b new file mode 100644 index 000000000..fba38d645 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7f99c619f89462fc52f924d1a228ca3f4a3d138b @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7fbf94d02d1aae374eb05428081f03d682815b39 b/fuzzing/seedcorpus/fuzz_strtod/7fbf94d02d1aae374eb05428081f03d682815b39 new file mode 100644 index 000000000..b99a60d06 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7fbf94d02d1aae374eb05428081f03d682815b39 @@ -0,0 +1 @@ +1E4E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/7fde327828905d26b0ac416ddf0ab12f19a446e9 b/fuzzing/seedcorpus/fuzz_strtod/7fde327828905d26b0ac416ddf0ab12f19a446e9 new file mode 100644 index 000000000..04a1c1204 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/7fde327828905d26b0ac416ddf0ab12f19a446e9 @@ -0,0 +1 @@ +9080089999099808008999999999999999990998080 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8048c5fe212078cee25624251ab1ae3c5e052c47 b/fuzzing/seedcorpus/fuzz_strtod/8048c5fe212078cee25624251ab1ae3c5e052c47 new file mode 100644 index 000000000..77f672a97 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8048c5fe212078cee25624251ab1ae3c5e052c47 @@ -0,0 +1 @@ +.289198107924742306288 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/829f88fd420e51a15b0da7dd236791253f17941c b/fuzzing/seedcorpus/fuzz_strtod/829f88fd420e51a15b0da7dd236791253f17941c new file mode 100644 index 000000000..342189218 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/829f88fd420e51a15b0da7dd236791253f17941c @@ -0,0 +1 @@ +5657 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8437513ebed8de872fc0485d23088b653154a8e9 b/fuzzing/seedcorpus/fuzz_strtod/8437513ebed8de872fc0485d23088b653154a8e9 new file mode 100644 index 000000000..3623f47fa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8437513ebed8de872fc0485d23088b653154a8e9 @@ -0,0 +1 @@ +8.098080070394049091.e9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/843be429e0a89c2f936a6904bdb46afd70b4ae34 b/fuzzing/seedcorpus/fuzz_strtod/843be429e0a89c2f936a6904bdb46afd70b4ae34 new file mode 100644 index 000000000..08b0f6cb2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/843be429e0a89c2f936a6904bdb46afd70b4ae34 @@ -0,0 +1 @@ +90008099999999999999. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8508d752fd34c1a5050811cec00bdddd2925a27a b/fuzzing/seedcorpus/fuzz_strtod/8508d752fd34c1a5050811cec00bdddd2925a27a new file mode 100644 index 000000000..2452ac097 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8508d752fd34c1a5050811cec00bdddd2925a27a @@ -0,0 +1 @@ +389839803182727035059883944419191.27039....3...0....30................9.........3.... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/85245af25d1cccb311bd4eaa8b3d425d901ae1db b/fuzzing/seedcorpus/fuzz_strtod/85245af25d1cccb311bd4eaa8b3d425d901ae1db new file mode 100644 index 000000000..e3fc79ec7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/85245af25d1cccb311bd4eaa8b3d425d901ae1db @@ -0,0 +1 @@ +1241E93 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8557693b06fd90fe7f6f6ece9998b84f71db0e2f b/fuzzing/seedcorpus/fuzz_strtod/8557693b06fd90fe7f6f6ece9998b84f71db0e2f new file mode 100644 index 000000000..1e91d52b1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8557693b06fd90fe7f6f6ece9998b84f71db0e2f @@ -0,0 +1 @@ +9.0908080072e389 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/86242234de9c6d67558d8dd6413c19d389bbdaf4 b/fuzzing/seedcorpus/fuzz_strtod/86242234de9c6d67558d8dd6413c19d389bbdaf4 new file mode 100644 index 000000000..ef408df4e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/86242234de9c6d67558d8dd6413c19d389bbdaf4 @@ -0,0 +1 @@ +118080080999999999995E9999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/867e280aa29d13e3ef4b8db01558e80c21aa4084 b/fuzzing/seedcorpus/fuzz_strtod/867e280aa29d13e3ef4b8db01558e80c21aa4084 new file mode 100644 index 000000000..5b93bf239 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/867e280aa29d13e3ef4b8db01558e80c21aa4084 @@ -0,0 +1 @@ +21; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 b/fuzzing/seedcorpus/fuzz_strtod/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 new file mode 100644 index 000000000..eaed6941c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/87a7b790b309a4c4b00d9a8d8bc9644136fa9331 @@ -0,0 +1 @@ +8e621 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/888a54ba1d2b757d43420ad105d045f9ddc8a198 b/fuzzing/seedcorpus/fuzz_strtod/888a54ba1d2b757d43420ad105d045f9ddc8a198 new file mode 100644 index 000000000..de3354b1b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/888a54ba1d2b757d43420ad105d045f9ddc8a198 @@ -0,0 +1 @@ +39370827031889938031......5.. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/88f02424d2a77340a47cc10a18f212395dfbeca7 b/fuzzing/seedcorpus/fuzz_strtod/88f02424d2a77340a47cc10a18f212395dfbeca7 new file mode 100644 index 000000000..256e8551d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/88f02424d2a77340a47cc10a18f212395dfbeca7 @@ -0,0 +1 @@ +80000804199999999981.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/89ab4af0020e9385e986279e66b4d39057a0e0b5 b/fuzzing/seedcorpus/fuzz_strtod/89ab4af0020e9385e986279e66b4d39057a0e0b5 new file mode 100644 index 000000000..a378d4697 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/89ab4af0020e9385e986279e66b4d39057a0e0b5 @@ -0,0 +1 @@ +nAnA \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 b/fuzzing/seedcorpus/fuzz_strtod/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 new file mode 100644 index 000000000..1b7e0b97c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8b62a267da11bcfddd1f1317fcd0d4eb39e63782 @@ -0,0 +1 @@ +7e000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa b/fuzzing/seedcorpus/fuzz_strtod/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa new file mode 100644 index 000000000..e870b7d1c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/8dbb8725c16c2bcbc4ec4b977a18629f4640c5fa @@ -0,0 +1,58 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.165504 +-80A1581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/906717bd5a741e7abafd6983f46e31840c75d374 b/fuzzing/seedcorpus/fuzz_strtod/906717bd5a741e7abafd6983f46e31840c75d374 new file mode 100644 index 000000000..b7e11d23f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/906717bd5a741e7abafd6983f46e31840c75d374 @@ -0,0 +1 @@ +nan(I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/91856e645abe70c73d21adb7142805cb4885635a b/fuzzing/seedcorpus/fuzz_strtod/91856e645abe70c73d21adb7142805cb4885635a new file mode 100644 index 000000000..fe2fff928 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/91856e645abe70c73d21adb7142805cb4885635a @@ -0,0 +1 @@ +398398031827033189839803182727035053182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 b/fuzzing/seedcorpus/fuzz_strtod/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 new file mode 100644 index 000000000..3314d5b14 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/927db8ed92fa97dce4155dcbf51855c5bb0d74b2 @@ -0,0 +1 @@ +8e6218 diff --git a/fuzzing/seedcorpus/fuzz_strtod/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 b/fuzzing/seedcorpus/fuzz_strtod/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 new file mode 100644 index 000000000..64a37a3df --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/93b3d5d7cecd699b8a3ba8c32f2d570bf85b5217 @@ -0,0 +1 @@ +99999999999999999999999999009999999980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/95c7d319a8c481cdb6074924395d43f66bd1a6f6 b/fuzzing/seedcorpus/fuzz_strtod/95c7d319a8c481cdb6074924395d43f66bd1a6f6 new file mode 100644 index 000000000..025ba7008 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/95c7d319a8c481cdb6074924395d43f66bd1a6f6 @@ -0,0 +1 @@ +nan(s \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/9616cdce298b78ec414eca803a2ec88991d52768 b/fuzzing/seedcorpus/fuzz_strtod/9616cdce298b78ec414eca803a2ec88991d52768 new file mode 100644 index 000000000..35d0b09c1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/9616cdce298b78ec414eca803a2ec88991d52768 @@ -0,0 +1 @@ +398398318983988983981318283980318.27039500313182.270350530.00000.8.8125308.00000.827032.9803182.270350530.00000.8.8125308.00000.827039839803103183.270350533189839803182.270350530.9839803182.270350533189839803182.270350530.00000.50031827018939880313182.350530.0000839803182.27039500318270189839803182.2733189839803182.270350530.0000.8125308.00000.827189839803182.27035053318398703182.27270189839803182.270350533189839803182.270350530.00000.8.8125308.00000.827039839803103182.270175626594919901591.270350530.0000.8.8125308.00000.827039839803182.27035089839803182.270350530.00000.8.8125339803182.2703505339803182.27030000245072229420724091.27035053318983980318.27039500313182.270350530.00000.8.8125308.00000.827032.9803182.270350530.00000.8.8125308.00000.827039839803103182.270350533189839803182.270350530.00000.8.8125308.00000.827039839803182.27035089839803182.270350530.827039839803182.27035089839803122294230.00000.8.8125308.00000.8270355705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/961c2c349adf528f0927b419ea4336d73d72b44a b/fuzzing/seedcorpus/fuzz_strtod/961c2c349adf528f0927b419ea4336d73d72b44a new file mode 100644 index 000000000..d1ced3c30 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/961c2c349adf528f0927b419ea4336d73d72b44a @@ -0,0 +1 @@ +3939390318540655461.1..............0.0. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/971322b28fb8dc103df606be81a818edec69cf34 b/fuzzing/seedcorpus/fuzz_strtod/971322b28fb8dc103df606be81a818edec69cf34 new file mode 100644 index 000000000..f587f4796 Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_strtod/971322b28fb8dc103df606be81a818edec69cf34 differ diff --git a/fuzzing/seedcorpus/fuzz_strtod/985a9924dbc7a343f147bdd9b982a875750f167f b/fuzzing/seedcorpus/fuzz_strtod/985a9924dbc7a343f147bdd9b982a875750f167f new file mode 100644 index 000000000..e63781f35 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/985a9924dbc7a343f147bdd9b982a875750f167f @@ -0,0 +1 @@ +0000. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/9902d381a017c5c8ce22b819deee8efbe1e24f01 b/fuzzing/seedcorpus/fuzz_strtod/9902d381a017c5c8ce22b819deee8efbe1e24f01 new file mode 100644 index 000000000..186532917 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/9902d381a017c5c8ce22b819deee8efbe1e24f01 @@ -0,0 +1 @@ +3. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/99991a46f79e031e016f6b02b28cf8f62167dfca b/fuzzing/seedcorpus/fuzz_strtod/99991a46f79e031e016f6b02b28cf8f62167dfca new file mode 100644 index 000000000..3458c71b7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/99991a46f79e031e016f6b02b28cf8f62167dfca @@ -0,0 +1 @@ +00000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 b/fuzzing/seedcorpus/fuzz_strtod/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 new file mode 100644 index 000000000..82b1327e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/9aa2597e2bd99c2ab621e73f56c4fa35fc5cdcb2 @@ -0,0 +1 @@ +2E98 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/9c37c6045ec3e1acc1281820aab4317ea2d110b3 b/fuzzing/seedcorpus/fuzz_strtod/9c37c6045ec3e1acc1281820aab4317ea2d110b3 new file mode 100644 index 000000000..451ed81e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/9c37c6045ec3e1acc1281820aab4317ea2d110b3 @@ -0,0 +1 @@ +.909999989 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/9d70c51941aa3a76bac12cefae2241edc09f8475 b/fuzzing/seedcorpus/fuzz_strtod/9d70c51941aa3a76bac12cefae2241edc09f8475 new file mode 100644 index 000000000..489799dfb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/9d70c51941aa3a76bac12cefae2241edc09f8475 @@ -0,0 +1 @@ +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a07058e7dbd3681dbb8500f714411399d1c9e9c7 b/fuzzing/seedcorpus/fuzz_strtod/a07058e7dbd3681dbb8500f714411399d1c9e9c7 new file mode 100644 index 000000000..4bc03a1e0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a07058e7dbd3681dbb8500f714411399d1c9e9c7 @@ -0,0 +1 @@ +980000890999999999999099990809999999645.9545956 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 b/fuzzing/seedcorpus/fuzz_strtod/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 new file mode 100644 index 000000000..42f552841 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a0b1516aec0ca87db8bbbc3e0c1c8d1db4c53674 @@ -0,0 +1 @@ +29e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a181caf6a5e4ca9750cd0f637b002ef09d023a17 b/fuzzing/seedcorpus/fuzz_strtod/a181caf6a5e4ca9750cd0f637b002ef09d023a17 new file mode 100644 index 000000000..24b4a94c0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a181caf6a5e4ca9750cd0f637b002ef09d023a17 @@ -0,0 +1 @@ +981808008040804; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 b/fuzzing/seedcorpus/fuzz_strtod/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 new file mode 100644 index 000000000..02c454b84 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a198fec6aee3bf858d4afb5c37a1e3a2bc645a39 @@ -0,0 +1 @@ +9.09808008086209999999999999999999999909888 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a2692f525c304805e367dd45a114adf8b6d8f6b5 b/fuzzing/seedcorpus/fuzz_strtod/a2692f525c304805e367dd45a114adf8b6d8f6b5 new file mode 100644 index 000000000..b2e9a88e6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a2692f525c304805e367dd45a114adf8b6d8f6b5 @@ -0,0 +1 @@ +198136796964088908624288004000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a2ac47e1458897c2106586cd82ba4cf955250db9 b/fuzzing/seedcorpus/fuzz_strtod/a2ac47e1458897c2106586cd82ba4cf955250db9 new file mode 100644 index 000000000..3ce504130 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a2ac47e1458897c2106586cd82ba4cf955250db9 @@ -0,0 +1 @@ +i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a2baf6238ebf35764b4592a439b22737cf6b77a0 b/fuzzing/seedcorpus/fuzz_strtod/a2baf6238ebf35764b4592a439b22737cf6b77a0 new file mode 100644 index 000000000..173dd6f9a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a2baf6238ebf35764b4592a439b22737cf6b77a0 @@ -0,0 +1 @@ +11E997 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 b/fuzzing/seedcorpus/fuzz_strtod/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 new file mode 100644 index 000000000..7b9d05c74 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a39f7616b9bb60d3c3fd2bcdcc6e09f4ce6a8cb1 @@ -0,0 +1 @@ +.0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a6021c83979739c55bfe0b66628ac1d4457c4585 b/fuzzing/seedcorpus/fuzz_strtod/a6021c83979739c55bfe0b66628ac1d4457c4585 new file mode 100644 index 000000000..b8871b0d5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a6021c83979739c55bfe0b66628ac1d4457c4585 @@ -0,0 +1 @@ +8e770038 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a64b4e7c8770bdc235b86aeb32d8521db72a542b b/fuzzing/seedcorpus/fuzz_strtod/a64b4e7c8770bdc235b86aeb32d8521db72a542b new file mode 100644 index 000000000..499dd8298 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a64b4e7c8770bdc235b86aeb32d8521db72a542b @@ -0,0 +1,359 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +20505426358836677347e-221 +836168422905420598437e-234 +4891559871276714924261e+222 +78459735791271921e+049 +-1.398276 +4085175404.2987347 +-3221966137.966876 +-6357323758.488493 +-2894404348.8540497 +-8902308186.10741 +-7250399334.123063 +-2596658794.58463 +-8149241490.530097 +-485364761.409914 +3681574431.7665367 +-3284991640.688921 +6698969656.836899 +3592526373.406824 +-7152990635.059179 +4674891628.675188 +-9308142522.674536 +8991180302.483883 +4691822009.442257 +-8803828164.623482 +9223061569.563828 +-4771021407.830767 +-8630070078.314186 +6687006990.92934 +8454429013.326324 +1921101243.763029 +-4837363132.127019 +-1590134469.0835571 +-856475839.8793297 +3817421813.491993 +4506070522.618269 +6882444300.4463215 +-541356395.6479034 +-7849838248.44633 +9146226385.295017 +4424846613.612682 +-2216621264.279706 +-877104960.4215527 +-9556342553.52092 +-678419349.3304977 +3518603934.229557 +7562483952.853828 +7882138472.013321 +8668221119.909203 +-9687549455.02824 +848668597.1303635 +-1890103115.6834793 +7562314189.139416 +-3687535787.702711 +5327849278.389738 +8594196782.752499 +-3778632985.018255 +5905743665.084358 +5414480590.90015 +-1024434058.2402039 +4061334669.7759647 +-6130854286.053664 +-3007239644.9545956 +5288460984.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863538.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+20 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.44001219357361e+20 +1.2536622959705993e+20 +-9.463308936516173e+20 +-2.6978869237912216e+20 +-8.862900061618213e+298 +-2.81231962822423e+298 +-1.3625284107982965e+20 +-3.744808743719544e+20 +-4.538840358945076e+20 +-6.045388459743684e+20 +-2.5801175260273326e+20 +7.035101821352075e+20 +-6.549520719067397e+20 +3.594254563918537e+20 +7.757714736760639e+20 +-1.5825518171804993e+298 +5.2047153237286724e+20 +-3.9817282843203786e+20 +4.1198892369955834e+20 +-1.9002647462263526e+20 +-4.949284897151789e+20 +7.7838340091077e+20 +3.511596756290671e+20 +7.57410384711072e+20 +7.08652023390211e+20 +8.57154266580247e+20 +5.058001461019743e+297 +-8.885383709414783e+20 +-5.965216558051927e+20 +1.3498288093904145e+20 +-7.238456079406055e+20 +5.440334272298565e+20 +5.393453331944822e+20 +8.88121548641883e+298 +5.206237603979129e+298 +5.844804520223339e+298 +2.059215854764529e+20 +8.385502673992724e+20 +-5.154969276216062e+20 +4.306236492262164e+20 +8.199003972356504e+20 +5.985730045751924e+20 +8.078963402853968e+20 +2.3775261609457693e+20 +-7.03696787484421e+20 +-7.432257359616441e+20 +-6.255702544062725e+20 +-1.3877528516443855e+20 +-3.586888614778576e+20 +2.7350631066999755e+20 +4.174634587678437e+20 +-4.9856013217239495e+20 +9.652916475546432e+20 +-7.87208147238843e+20 +1.1860507934819055e+20 +4.2669209229538335e+20 +2.7110709880939756e+20 +-4.4549419413418414e+20 +-7.939542985204633e+20 +-7.342883612186115e+20 +-2.3922598883162777e+20 +1.798386063469952e+20 +2.01513790959235e+298 +8.363313923400434e+20 +-9.80642189348544e+20 +6.340412915598392e+20 +-2.7227921174831335e+20 +-5.533409871384972e+298 +-4.784813819850131e+20 +-1.862843277163022e+20 +8.303060863211473e+20 +-3.825818526589968e+20 +-6.794073099684725e+20 +5.527805860226476e+20 +7.91202486215104e+20 +9.627550168742959e+20 +9.930220546654244e+20 +-1.315749121315002e+20 +3.418756962024236e+20 +-5.776529116146246e+20 +3.788763768615891e+20 +-2.422343107151308e+20 + diff --git a/fuzzing/seedcorpus/fuzz_strtod/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 b/fuzzing/seedcorpus/fuzz_strtod/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 new file mode 100644 index 000000000..06d3ff7db --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a7d65aad9c2795b9fd5c41eb85bfa819393d3fd0 @@ -0,0 +1 @@ +18446744073709551618 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a7fced1fdbeb07582033148094f1deb7d171d16b b/fuzzing/seedcorpus/fuzz_strtod/a7fced1fdbeb07582033148094f1deb7d171d16b new file mode 100644 index 000000000..820db0263 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a7fced1fdbeb07582033148094f1deb7d171d16b @@ -0,0 +1 @@ +980002809999999990000009909180800239644.959226290442866 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a905df1efff3e9361d1f823fee642ef87ec1eb52 b/fuzzing/seedcorpus/fuzz_strtod/a905df1efff3e9361d1f823fee642ef87ec1eb52 new file mode 100644 index 000000000..054df32f3 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a905df1efff3e9361d1f823fee642ef87ec1eb52 @@ -0,0 +1 @@ +9.098080070339938182.e920394 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c b/fuzzing/seedcorpus/fuzz_strtod/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c new file mode 100644 index 000000000..9b26e9b10 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/a979ef10cc6f6a36df6b8a323307ee3bb2e2db9c @@ -0,0 +1 @@ ++ \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/adb06e660444a43e1033dc92fbcc32eb4cc95f3a b/fuzzing/seedcorpus/fuzz_strtod/adb06e660444a43e1033dc92fbcc32eb4cc95f3a new file mode 100644 index 000000000..1d62b7418 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/adb06e660444a43e1033dc92fbcc32eb4cc95f3a @@ -0,0 +1 @@ +9808080080999999999808008099 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/af10ef20dd9060bbeead0afbc55381a66af442ef b/fuzzing/seedcorpus/fuzz_strtod/af10ef20dd9060bbeead0afbc55381a66af442ef new file mode 100644 index 000000000..f087d8914 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/af10ef20dd9060bbeead0afbc55381a66af442ef @@ -0,0 +1 @@ +in \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/afc97ea131fd7e2695a98ef34013608f97f34e1d b/fuzzing/seedcorpus/fuzz_strtod/afc97ea131fd7e2695a98ef34013608f97f34e1d new file mode 100644 index 000000000..cf5106d72 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/afc97ea131fd7e2695a98ef34013608f97f34e1d @@ -0,0 +1 @@ +999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/b46dbafdabe8b0cff532f144835276bc1dbc1d8f b/fuzzing/seedcorpus/fuzz_strtod/b46dbafdabe8b0cff532f144835276bc1dbc1d8f new file mode 100644 index 000000000..0255bf130 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/b46dbafdabe8b0cff532f144835276bc1dbc1d8f @@ -0,0 +1,56 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86636 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.504 +-80A1581185.957868 +-3894457067.979211 +787240530.00000.8530.009997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.58203#15289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/b51a60734da64be0e618bacbea2865a8a7dcd669 b/fuzzing/seedcorpus/fuzz_strtod/b51a60734da64be0e618bacbea2865a8a7dcd669 new file mode 100644 index 000000000..2f94675b7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/b51a60734da64be0e618bacbea2865a8a7dcd669 @@ -0,0 +1 @@ +N \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/b57453fb3aa94518fa1a1915eaa874ae2368cc86 b/fuzzing/seedcorpus/fuzz_strtod/b57453fb3aa94518fa1a1915eaa874ae2368cc86 new file mode 100644 index 000000000..3e0f102f9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/b57453fb3aa94518fa1a1915eaa874ae2368cc86 @@ -0,0 +1 @@ +.e8 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/b62b76505678b9d7e77475ca45fbc9f15deb61f7 b/fuzzing/seedcorpus/fuzz_strtod/b62b76505678b9d7e77475ca45fbc9f15deb61f7 new file mode 100644 index 000000000..f9abf3d9a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/b62b76505678b9d7e77475ca45fbc9f15deb61f7 @@ -0,0 +1 @@ +298120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c b/fuzzing/seedcorpus/fuzz_strtod/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c new file mode 100644 index 000000000..c22708346 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/b6589fc6ab0dc82cf12099d1c2d40ab994e8410c @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ba085e7b393a22d5bcf382b4673d66428b726131 b/fuzzing/seedcorpus/fuzz_strtod/ba085e7b393a22d5bcf382b4673d66428b726131 new file mode 100644 index 000000000..8cdc48997 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ba085e7b393a22d5bcf382b4673d66428b726131 @@ -0,0 +1 @@ +929e92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/bb589d0621e5472f470fa3425a234c74b1e202e8 b/fuzzing/seedcorpus/fuzz_strtod/bb589d0621e5472f470fa3425a234c74b1e202e8 new file mode 100644 index 000000000..ad2823b48 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/bb589d0621e5472f470fa3425a234c74b1e202e8 @@ -0,0 +1 @@ +' \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/bdba068c531049e22ec9534cea647768cd265414 b/fuzzing/seedcorpus/fuzz_strtod/bdba068c531049e22ec9534cea647768cd265414 new file mode 100644 index 000000000..bc2c6d14c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/bdba068c531049e22ec9534cea647768cd265414 @@ -0,0 +1 @@ +18E998 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 b/fuzzing/seedcorpus/fuzz_strtod/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 new file mode 100644 index 000000000..37e9215ec --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/bdc5e1a180c1f1b27b63ace3c8c77f1397fedfa2 @@ -0,0 +1 @@ +2EE \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/be06cf696332b8261092aca2751daf12a4a3cd34 b/fuzzing/seedcorpus/fuzz_strtod/be06cf696332b8261092aca2751daf12a4a3cd34 new file mode 100644 index 000000000..7464f47e7 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/be06cf696332b8261092aca2751daf12a4a3cd34 @@ -0,0 +1 @@ +9.09808008620999080080862099999999999999999999999990980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 b/fuzzing/seedcorpus/fuzz_strtod/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 new file mode 100644 index 000000000..c7d354934 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c14715f7d6592bfaa4aa865d1e419b1941b4d9f9 @@ -0,0 +1 @@ +nA; \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c202931b0efa026332e5048ba2dabd9ac9b0af2b b/fuzzing/seedcorpus/fuzz_strtod/c202931b0efa026332e5048ba2dabd9ac9b0af2b new file mode 100644 index 000000000..0148c2f32 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c202931b0efa026332e5048ba2dabd9ac9b0af2b @@ -0,0 +1 @@ +12980.000999999998008990899999999989908 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 b/fuzzing/seedcorpus/fuzz_strtod/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 new file mode 100644 index 000000000..244a1c972 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c244b31fc8efb78e7ff43a48834f1b07abaec2f9 @@ -0,0 +1 @@ +7e85 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c24dee1111bde34637da8f10e400ceddb47e1a42 b/fuzzing/seedcorpus/fuzz_strtod/c24dee1111bde34637da8f10e400ceddb47e1a42 new file mode 100644 index 000000000..54738b958 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c24dee1111bde34637da8f10e400ceddb47e1a42 @@ -0,0 +1 @@ +98080080999999999999999999999999999999999999990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c28dcb678244590d45bce1bab9e7f7a56b765056 b/fuzzing/seedcorpus/fuzz_strtod/c28dcb678244590d45bce1bab9e7f7a56b765056 new file mode 100644 index 000000000..a3bce0b72 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c28dcb678244590d45bce1bab9e7f7a56b765056 @@ -0,0 +1,253 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-9944999757.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.9844475 +-1133439341.760744 +283125413.30306435 +2655887234.5390606 +-2834454891.569254 +-9838440569.917286 +7490473498.520126 +-4297589672.232147 +-4475537891.376121 +-1246016012.5750446 +-3594122015.8431997 +-7778192747.044838 +5119744027.894331 +-7507768336.733436 +3107440950.938305 +8087197826.752613 +8627371955.66367 +-3001444291.3169146 +-9653912497.318966 +4298404430.77368 +-7986711371.146531 +-1194988223.8673096 +-9105692799.919487 +2859084549.321411 +-1024713097.7194271 +-9850091280.622812 +-3703515456.0545206 +2739822062.2363014 +9484675686.77908 +8259525635.834816 +4421163560.051752 +-7851891784.561371 +8119727986.808456 +168307487.93410683 +1618919273.7877693 +-778423007.7539673 +29113740.24382019 +9499722538.902527 +796528331.5813694 +7126904754.280651 +-9790211567.553501 +-5984728508.749706 +1384520242.8921604 +-9126937330.521118 +-1117470497.5896568 +8274863738.686867 +2709272301.989956 +4251086569.7801456 +-5332617826.3962755 +-5529685892.62735 +7657371750.1461525 +-6530555899.87366 +2450235224.9255543 +844521120.6915207 +-9433948679.5921062735505967865e+20 +8.636603806244379e+20 +1.2897088675600334e+20 +-1.4127075322477746e+20 +2.3802302615188302e+20 +-5.025076746504314e+20 +3.804107095252895e+20 +-3.40228686521763e+20 +9.34464541485495e+20 +3.778087541113501e+20 +1.4932690717714123e+20 +3.856711740732798e+20 +-8.8129621449138e+20 +6.757278994999792e+20 +3.913168242155768e+20 +-8.008644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919303e+20 +6.788151190495758e+20 +-2.3168798596578214e+20 +-4.6505624780019144e+20 +8.029705583446802e+298 +1.8376555720891744e+298 +3.687041257269647e+20 +2.6177911421647736e+20 +-1.1208342149876693e+20 +6.926912795590656e+20 +3.199394663066377e+20 +-7.324371300044846e+20 +-9.422875615735778e+20 +-1.9482733944034182e+298 +-6.270659679086801e+20 +-8.92365207182281e+20 +9.10139163406178e+28 +9.541278154748038e+20 +-3.641297840433948e+20 +-3.3887022096602814e+20 +7.534310444023287e+20 +8.486703806475801e+20 +9.87369122628879e+298 +8.696933508912566e+20 +-6.81500662493189e+298 +4.488759323111065e+298 +-5.881145999714648e+20 +9.127888192176085e+20 +3.082891302507487e+20 +-1.757629095378162e+20 +6.001232841928033e+20 +8.158173204460408e+20 +4.7601439064756015e+20 +-3.0328486434293715e+20 +-7.38108926372829e+20 +-2.675852607254631e+298 +-9.836498458410544e+20 +-6.289219130691684e+20 +6.681610382696533e+20 +-5.086997173279147e+298 +4.9642838338008775e+20 +7.43903198812593e+20 +-1.2900377953820756e+20 +-4.765174271331947e+20 +1.836583484193637e+20 +9.823593245038008e+20 +9.524504361273124e+20 +-3.7573032767746416e+20 +-6.723578147363712e+20 +-5.603751547236776e+298 +-7.655902908695984e+20 +-4.909573094479229e+298 +-3.836987008894679e+20 +-2.1929658437764777e+20 +-4.378605389200188e+298 +-2.2322108694088976e+20 +1.2139496996663562e+20 +2.554952712750673e+298 +-2.5107491812237243e+20 +1.3075531102186762e+20 +-1.3019085251769529e+20 +9.988025173739155e+20 +-2.849886548263754e+20 +8.788071489626828e+20 +7.697596830344097e+20 +-6.226942432875869e+20 +3.2235060893837056e+20 +8.068755519825467e+298 +-3.5523900865807256e+20 +-5.516076969678274e+20 +7.367913715453331e+20 +4.51571427667033e+20 +2.6665879095418395e+20 +-8.844814485142003e+20 +9.262522393466221e+20 +-7.852385648230882e+20 +-2.4336434537202874e+20 +7.666928520911611e+20 +1.853641206317662e+20 +-6.726821137900118e+20 +-6.6210196103469234e+20 +3.416103131845767e+298 +5.481178595373923e+20 +9.853213243964176e+20 +7.948-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-309 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 b/fuzzing/seedcorpus/fuzz_strtod/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 new file mode 100644 index 000000000..c99b1a35a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c2d9e1b7c774412256ee7cc38b3658fcb3b17341 @@ -0,0 +1 @@ +9.098080800808608620999999999999999999990980999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/c50b8326c52e1f5a59d3549dec588af705b3bee8 b/fuzzing/seedcorpus/fuzz_strtod/c50b8326c52e1f5a59d3549dec588af705b3bee8 new file mode 100644 index 000000000..3eeb2b881 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/c50b8326c52e1f5a59d3549dec588af705b3bee8 @@ -0,0 +1 @@ +281239839808270330004662711377164635110.82 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ca73ab65568cd125c2d27a22bbd9e863c10b675d b/fuzzing/seedcorpus/fuzz_strtod/ca73ab65568cd125c2d27a22bbd9e863c10b675d new file mode 100644 index 000000000..b4158c40d --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ca73ab65568cd125c2d27a22bbd9e863c10b675d @@ -0,0 +1 @@ +I \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d b/fuzzing/seedcorpus/fuzz_strtod/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d new file mode 100644 index 000000000..a19920e57 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/cadaed5ccd6ba23b3e00638fc4eaf193fb4bd59d @@ -0,0 +1 @@ +.8822 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/cc08b3ec1b721133a466105cbfe88eb0ed86d30f b/fuzzing/seedcorpus/fuzz_strtod/cc08b3ec1b721133a466105cbfe88eb0ed86d30f new file mode 100644 index 000000000..43f826b55 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/cc08b3ec1b721133a466105cbfe88eb0ed86d30f @@ -0,0 +1 @@ +.0000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 b/fuzzing/seedcorpus/fuzz_strtod/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 new file mode 100644 index 000000000..41ea2fa1e --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ccce55a1d969999e62aa516b926b73aa1c4ec9c4 @@ -0,0 +1 @@ +9e0000. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/cd3e870b525405e2a233f805117ff55b4563144b b/fuzzing/seedcorpus/fuzz_strtod/cd3e870b525405e2a233f805117ff55b4563144b new file mode 100644 index 000000000..981aa2ee5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/cd3e870b525405e2a233f805117ff55b4563144b @@ -0,0 +1 @@ +9e+218 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 b/fuzzing/seedcorpus/fuzz_strtod/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 new file mode 100644 index 000000000..01f42e214 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/cd45ed8fecd9f81a7613a45120c66dfb22ccf9d8 @@ -0,0 +1 @@ +9.098080186080000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/cfad63c69e4f84745060b1a1954fe688f65a552d b/fuzzing/seedcorpus/fuzz_strtod/cfad63c69e4f84745060b1a1954fe688f65a552d new file mode 100644 index 000000000..f4c0ea5be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/cfad63c69e4f84745060b1a1954fe688f65a552d @@ -0,0 +1 @@ +9e-9890 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d07e4bc786c88b8d2304f84c7db2098666f822c0 b/fuzzing/seedcorpus/fuzz_strtod/d07e4bc786c88b8d2304f84c7db2098666f822c0 new file mode 100644 index 000000000..5639b6ddc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d07e4bc786c88b8d2304f84c7db2098666f822c0 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e b/fuzzing/seedcorpus/fuzz_strtod/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e new file mode 100644 index 000000000..fcfe98db4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d0ec9dfc7a8251fcf5ba5d251e84de1d941f153e @@ -0,0 +1 @@ +9e70799y \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d1854cae891ec7b29161ccaf79a24b00c274bdaa b/fuzzing/seedcorpus/fuzz_strtod/d1854cae891ec7b29161ccaf79a24b00c274bdaa new file mode 100644 index 000000000..ef073cc45 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d1854cae891ec7b29161ccaf79a24b00c274bdaa @@ -0,0 +1 @@ +n \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d281f13dedd0cc21f91ef0df57288227266e5973 b/fuzzing/seedcorpus/fuzz_strtod/d281f13dedd0cc21f91ef0df57288227266e5973 new file mode 100644 index 000000000..78e7f75a9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d281f13dedd0cc21f91ef0df57288227266e5973 @@ -0,0 +1 @@ +90e85368 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d533dd0d2c17d4dfeabd44a10e43b976bda9872a b/fuzzing/seedcorpus/fuzz_strtod/d533dd0d2c17d4dfeabd44a10e43b976bda9872a new file mode 100644 index 000000000..1f061e3dc --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d533dd0d2c17d4dfeabd44a10e43b976bda9872a @@ -0,0 +1 @@ +4.094419906569906591.e81980 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d53407c9291c2e34919523cd3b35ab291ae505d6 b/fuzzing/seedcorpus/fuzz_strtod/d53407c9291c2e34919523cd3b35ab291ae505d6 new file mode 100644 index 000000000..138864de9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d53407c9291c2e34919523cd3b35ab291ae505d6 @@ -0,0 +1 @@ +398938031827189839889839802701808139382.3....................3........... \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d72b31bd2c612402b4575d33979f6bcb941a8b82 b/fuzzing/seedcorpus/fuzz_strtod/d72b31bd2c612402b4575d33979f6bcb941a8b82 new file mode 100644 index 000000000..bee387e46 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d72b31bd2c612402b4575d33979f6bcb941a8b82 @@ -0,0 +1,57 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +46]]]]]]]]]]]]]]]]]]03285e-24 +8775437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080z55902682397m-242 +88981089217264050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181-0.7 +9e-265 +86;32 +1798265 +86632 +6 +-728!1203743626360493413e-165 +94080055902642 +8998108921726453.504 +-80A1581185.957868 +-3894457067.979211 +787240530.00000.8530.009997866247594242e+20 +-707825977327728e+20 +7.664516908652013e+20 +-9.5820315289163e+298 +-4.367874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440476e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565787835516.7666457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/d9ec4c78aa727434495e91f497a8255ccfa2f51f b/fuzzing/seedcorpus/fuzz_strtod/d9ec4c78aa727434495e91f497a8255ccfa2f51f new file mode 100644 index 000000000..3afcaffad --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/d9ec4c78aa727434495e91f497a8255ccfa2f51f @@ -0,0 +1 @@ +9e-990 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/db1f77c2e01ab20855fa2513741f77e63d470439 b/fuzzing/seedcorpus/fuzz_strtod/db1f77c2e01ab20855fa2513741f77e63d470439 new file mode 100644 index 000000000..64c76f8e9 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/db1f77c2e01ab20855fa2513741f77e63d470439 @@ -0,0 +1 @@ +9e00000000000000000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/dd6b1aaa2553c97b57eb1e0c553e3c38729936de b/fuzzing/seedcorpus/fuzz_strtod/dd6b1aaa2553c97b57eb1e0c553e3c38729936de new file mode 100644 index 000000000..d79664163 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/dd6b1aaa2553c97b57eb1e0c553e3c38729936de @@ -0,0 +1 @@ +2E- \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/dde8fa867fad2d8c1163a10586ff602b5e06fc13 b/fuzzing/seedcorpus/fuzz_strtod/dde8fa867fad2d8c1163a10586ff602b5e06fc13 new file mode 100644 index 000000000..71bfddb15 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/dde8fa867fad2d8c1163a10586ff602b5e06fc13 @@ -0,0 +1,2 @@ +999999008099999999998e6128 +90 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/df79d037bf616251b47482ab444da97a1717fb94 b/fuzzing/seedcorpus/fuzz_strtod/df79d037bf616251b47482ab444da97a1717fb94 new file mode 100644 index 000000000..a9e56a0d6 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/df79d037bf616251b47482ab444da97a1717fb94 @@ -0,0 +1 @@ +8070098498387.244994.e-9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e0184adedf913b076626646d3f52c3b49c39ad6d b/fuzzing/seedcorpus/fuzz_strtod/e0184adedf913b076626646d3f52c3b49c39ad6d new file mode 100644 index 000000000..9fb75b8d4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e0184adedf913b076626646d3f52c3b49c39ad6d @@ -0,0 +1 @@ +E \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e0ce700f7251111e7de2a72c206bf8b8404c1625 b/fuzzing/seedcorpus/fuzz_strtod/e0ce700f7251111e7de2a72c206bf8b8404c1625 new file mode 100644 index 000000000..a913e89be --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e0ce700f7251111e7de2a72c206bf8b8404c1625 @@ -0,0 +1 @@ +281239839803180318272703505312398398031.8227033199803182727035053.82705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 b/fuzzing/seedcorpus/fuzz_strtod/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 new file mode 100644 index 000000000..b413dfe0c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e5b940d908bbdc5d4965a0896bc1fa46f18d2b79 @@ -0,0 +1 @@ +nan(i \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e5cfb53dc80712e65116c90e68d89a2a949d283d b/fuzzing/seedcorpus/fuzz_strtod/e5cfb53dc80712e65116c90e68d89a2a949d283d new file mode 100644 index 000000000..2a30ccf3e Binary files /dev/null and b/fuzzing/seedcorpus/fuzz_strtod/e5cfb53dc80712e65116c90e68d89a2a949d283d differ diff --git a/fuzzing/seedcorpus/fuzz_strtod/e6c141d1e0aa21c965231473af366d62ddd80c89 b/fuzzing/seedcorpus/fuzz_strtod/e6c141d1e0aa21c965231473af366d62ddd80c89 new file mode 100644 index 000000000..f07eeb10a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e6c141d1e0aa21c965231473af366d62ddd80c89 @@ -0,0 +1 @@ +2E199999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e81019bfd2f759c3e98e3040201a7659d6bd4cec b/fuzzing/seedcorpus/fuzz_strtod/e81019bfd2f759c3e98e3040201a7659d6bd4cec new file mode 100644 index 000000000..916d65c90 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e81019bfd2f759c3e98e3040201a7659d6bd4cec @@ -0,0 +1 @@ +39803182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/e8f81a39cfabffba92d7a164ce2449835ab33c3a b/fuzzing/seedcorpus/fuzz_strtod/e8f81a39cfabffba92d7a164ce2449835ab33c3a new file mode 100644 index 000000000..71176ef21 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/e8f81a39cfabffba92d7a164ce2449835ab33c3a @@ -0,0 +1 @@ +980083270 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ea2977e307197a2a61488c59648670df15979ef6 b/fuzzing/seedcorpus/fuzz_strtod/ea2977e307197a2a61488c59648670df15979ef6 new file mode 100644 index 000000000..1dd0624cb --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ea2977e307197a2a61488c59648670df15979ef6 @@ -0,0 +1 @@ +9808008099999999999999990999999999408980e8534 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ec776842a2bcd5d045633a674526f7f32085e555 b/fuzzing/seedcorpus/fuzz_strtod/ec776842a2bcd5d045633a674526f7f32085e555 new file mode 100644 index 000000000..3ed26649f --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ec776842a2bcd5d045633a674526f7f32085e555 @@ -0,0 +1 @@ +9180809180080080999999999999909999999999999044 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/eca59e5d9d93eaa3b8a3604431b27e213b961244 b/fuzzing/seedcorpus/fuzz_strtod/eca59e5d9d93eaa3b8a3604431b27e213b961244 new file mode 100644 index 000000000..d0407e4ab --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/eca59e5d9d93eaa3b8a3604431b27e213b961244 @@ -0,0 +1,91 @@ +-0.7 +9e-265 +85e-37 +623e+100 +3571e+263 +81661e+153 +920657e-23 +4603285e-24 +87575437e-3.9 +245540327e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +460725069845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958644750298803e+20 +6.341026985513891e+20 +8.457256389845352e+20 +2.439181502963422e+20 +-9.519026674833305e+20 +6.46635813153362e+20 +-8.915161226564948e+20 +5.843437877683319e+20 +-2.431289830689101e+20 +5.9032408929665024e+20 +-6.599231080528363e+20 +1.4947317610910415e+20 +9.330446301017545e+20 +4.361241354367741e+20 +-7.129546147161119e+20 +-7.324672222958528e+20 +4.1130405205172115e+20 +2.238309932868172e+20 +-2.800899337626482e+20 +-9.747355404919307e+122 +6138508175e+120 +83356057653e+193 +619534293513e+124 +2335141086879e+218 +36167929443327e-159 +609610927149051e-255 +3743626360493413e-165 +94080055902682397e-242 +899810892172646163e+283 +7120190517612959703e+120 +2050542607239644.9545956 +6580492884.511721 +4607250654.587957 +-1592934090.4738808 +-8327548253.165504 +-8071581185.957868 +-3894457067.979211 +7872439715.424465 +-99449997866247594242e+20 +-7.507825977327728e+20 +7.664516908652013e+20 +-9.876107251051618e+298 +-2.2245820315289163e+298 +-4.36137874691906e+20 +7.898346319182928e+20 +3.65461464395618e+20 +8.4457.9318 +672918681.5396633 +-7981565732.591891 +5387835516.766457 +-483167149.6071758 +4920681763.602953 +-1513888746.1602364 +3706223463.98440475 +-1133439341.760744 +283120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 b/fuzzing/seedcorpus/fuzz_strtod/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 new file mode 100644 index 000000000..11d92a2bf --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ee2d91af829d2d7936ae70e8eabb0d3a80a5e817 @@ -0,0 +1 @@ +11808008099999999999999999999999998 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f3689a11195bec0993096768550b1ca19883c2bc b/fuzzing/seedcorpus/fuzz_strtod/f3689a11195bec0993096768550b1ca19883c2bc new file mode 100644 index 000000000..bba62cfd1 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f3689a11195bec0993096768550b1ca19883c2bc @@ -0,0 +1 @@ +9E05 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f371163b0be7a0d6b619a4fe98581cc8a555a421 b/fuzzing/seedcorpus/fuzz_strtod/f371163b0be7a0d6b619a4fe98581cc8a555a421 new file mode 100644 index 000000000..13e4f2cfa --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f371163b0be7a0d6b619a4fe98581cc8a555a421 @@ -0,0 +1 @@ +98370350570338031820.1........................3..3...3...............0..................8. \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f54338af0ebb664c1370622680defda872bc7c32 b/fuzzing/seedcorpus/fuzz_strtod/f54338af0ebb664c1370622680defda872bc7c32 new file mode 100644 index 000000000..7039a8060 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f54338af0ebb664c1370622680defda872bc7c32 @@ -0,0 +1 @@ +9e0000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f58080c4f5bc8f14e0d148832483f3996a4d7393 b/fuzzing/seedcorpus/fuzz_strtod/f58080c4f5bc8f14e0d148832483f3996a4d7393 new file mode 100644 index 000000000..a52cb3e46 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f58080c4f5bc8f14e0d148832483f3996a4d7393 @@ -0,0 +1 @@ +9800832700 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f5982a144fe613ac6849a6b43ed08baf52161f52 b/fuzzing/seedcorpus/fuzz_strtod/f5982a144fe613ac6849a6b43ed08baf52161f52 new file mode 100644 index 000000000..bd34de2f0 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f5982a144fe613ac6849a6b43ed08baf52161f52 @@ -0,0 +1 @@ +iNF \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c b/fuzzing/seedcorpus/fuzz_strtod/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c new file mode 100644 index 000000000..cb4b00639 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f5ab0673067d00fa9227cd8b7544c1f6a20a0c5c @@ -0,0 +1 @@ +128E92 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c b/fuzzing/seedcorpus/fuzz_strtod/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c new file mode 100644 index 000000000..c5ceb2f4a --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f77f04fb6bbc29a388247e2ace5e8aeb778aad0c @@ -0,0 +1 @@ +.Z \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/f8be78b0d0194e487c8e219d809ec875ad70772c b/fuzzing/seedcorpus/fuzz_strtod/f8be78b0d0194e487c8e219d809ec875ad70772c new file mode 100644 index 000000000..a7bd3d31c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/f8be78b0d0194e487c8e219d809ec875ad70772c @@ -0,0 +1 @@ +980800809999999999999999999999999000 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fa60d9942f9385dcced990bf13d2fd3511f8c505 b/fuzzing/seedcorpus/fuzz_strtod/fa60d9942f9385dcced990bf13d2fd3511f8c505 new file mode 100644 index 000000000..6040820db --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fa60d9942f9385dcced990bf13d2fd3511f8c505 @@ -0,0 +1 @@ +398398031827033189839803182727035053.82705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/faf1631572e1d19b59a96de1bb71d047fdd030d5 b/fuzzing/seedcorpus/fuzz_strtod/faf1631572e1d19b59a96de1bb71d047fdd030d5 new file mode 100644 index 000000000..d361d6a36 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/faf1631572e1d19b59a96de1bb71d047fdd030d5 @@ -0,0 +1 @@ +9e9 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fb0c125a2486b9707a53b731ba012af4e3789cb5 b/fuzzing/seedcorpus/fuzz_strtod/fb0c125a2486b9707a53b731ba012af4e3789cb5 new file mode 100644 index 000000000..3eed846e4 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fb0c125a2486b9707a53b731ba012af4e3789cb5 @@ -0,0 +1 @@ +8e0 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fb6c14b8efa4f8844872f33db91f5b8195c43136 b/fuzzing/seedcorpus/fuzz_strtod/fb6c14b8efa4f8844872f33db91f5b8195c43136 new file mode 100644 index 000000000..8df71c9c5 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fb6c14b8efa4f8844872f33db91f5b8195c43136 @@ -0,0 +1 @@ +nan( \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fbde7ce9657042789e40729235b79eb676cec72d b/fuzzing/seedcorpus/fuzz_strtod/fbde7ce9657042789e40729235b79eb676cec72d new file mode 100644 index 000000000..2b340399c --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fbde7ce9657042789e40729235b79eb676cec72d @@ -0,0 +1 @@ +980809810809999999999999999999999999999 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fde7ea94eb806031185e8b4596be747a521a80cc b/fuzzing/seedcorpus/fuzz_strtod/fde7ea94eb806031185e8b4596be747a521a80cc new file mode 100644 index 000000000..e21954863 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fde7ea94eb806031185e8b4596be747a521a80cc @@ -0,0 +1 @@ +39839803182703182705 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/fea3b29291b269898651be5c1b719cb12cc031cf b/fuzzing/seedcorpus/fuzz_strtod/fea3b29291b269898651be5c1b719cb12cc031cf new file mode 100644 index 000000000..244c1e82b --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/fea3b29291b269898651be5c1b719cb12cc031cf @@ -0,0 +1 @@ +98120 \ No newline at end of file diff --git a/fuzzing/seedcorpus/fuzz_strtod/ff672df6d83863b94c711a5ca44ea4d61660ca06 b/fuzzing/seedcorpus/fuzz_strtod/ff672df6d83863b94c711a5ca44ea4d61660ca06 new file mode 100644 index 000000000..f47f54ce2 --- /dev/null +++ b/fuzzing/seedcorpus/fuzz_strtod/ff672df6d83863b94c711a5ca44ea4d61660ca06 @@ -0,0 +1 @@ +999999999999999999999999999999999994 \ No newline at end of file diff --git a/include/boost/decimal.hpp b/include/boost/decimal.hpp index ad08bae81..eb28e95dd 100644 --- a/include/boost/decimal.hpp +++ b/include/boost/decimal.hpp @@ -43,10 +43,7 @@ #include #include #include - -#ifndef BOOST_DECIMAL_BUILD_MODULE -#include -#endif +#include #if defined(__clang__) && !defined(__GNUC__) # pragma clang diagnostic pop diff --git a/include/boost/decimal/bid_conversion.hpp b/include/boost/decimal/bid_conversion.hpp index 18bcd90c4..321f9d39e 100644 --- a/include/boost/decimal/bid_conversion.hpp +++ b/include/boost/decimal/bid_conversion.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "detail/int128.hpp" diff --git a/include/boost/decimal/cfenv.hpp b/include/boost/decimal/cfenv.hpp index 9182d489a..a995ef33a 100644 --- a/include/boost/decimal/cfenv.hpp +++ b/include/boost/decimal/cfenv.hpp @@ -7,6 +7,46 @@ #include +#ifdef BOOST_DECIMAL_FE_DEC_DOWNWARD +# define BOOST_DECIMAL_MODE_1 1 +#else +# define BOOST_DECIMAL_MODE_1 0 +#endif + +#ifdef BOOST_DECIMAL_FE_DEC_TO_NEAREST +# define BOOST_DECIMAL_MODE_2 1 +#else +# define BOOST_DECIMAL_MODE_2 0 +#endif + +#ifdef BOOST_DECIMAL_FE_DEC_TO_NEAREST_FROM_ZERO +# define BOOST_DECIMAL_MODE_3 1 +#else +# define BOOST_DECIMAL_MODE_3 0 +#endif + +#ifdef BOOST_DECIMAL_FE_DEC_TOWARD_ZERO +# define BOOST_DECIMAL_MODE_4 1 +#else +# define BOOST_DECIMAL_MODE_4 0 +#endif + +#ifdef BOOST_DECIMAL_FE_DEC_UPWARD +# define BOOST_DECIMAL_MODE_5 1 +#else +# define BOOST_DECIMAL_MODE_5 0 +#endif + +// Now we can safely use arithmetic in preprocessor +#define BOOST_DECIMAL_MODE_COUNT \ +(BOOST_DECIMAL_MODE_1 + BOOST_DECIMAL_MODE_2 + \ +BOOST_DECIMAL_MODE_3 + BOOST_DECIMAL_MODE_4 + \ +BOOST_DECIMAL_MODE_5) + +#if BOOST_DECIMAL_MODE_COUNT > 1 +# error "Only one rounding mode macro can be defined" +#endif + #ifndef BOOST_DECIMAL_BUILD_MODULE #include #endif @@ -21,23 +61,43 @@ BOOST_DECIMAL_EXPORT enum class rounding_mode : unsigned fe_dec_to_nearest_from_zero = 1 << 2, fe_dec_toward_zero = 1 << 3, fe_dec_upward = 1 << 4, - fe_dec_default = fe_dec_to_nearest_from_zero + fe_dec_default = fe_dec_to_nearest +}; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto _boost_decimal_global_rounding_mode { + #ifdef BOOST_DECIMAL_FE_DEC_DOWNWARD + rounding_mode::fe_dec_downward + #elif defined(BOOST_DECIMAL_FE_DEC_TO_NEAREST) + rounding_mode::fe_dec_to_nearest + #elif defined(BOOST_DECIMAL_FE_DEC_TO_NEAREST_FROM_ZERO) + rounding_mode::fe_dec_to_nearest_from_zero + #elif defined (BOOST_DECIMAL_FE_DEC_TOWARD_ZERO) + rounding_mde::fe_dec_toward_zero + #elif defined(BOOST_DECIMAL_FE_DEC_UPWARD) + rounding_mode::fe_dec_upward + #else + rounding_mode::fe_dec_default + #endif }; -BOOST_DECIMAL_INLINE_VARIABLE rounding_mode _boost_decimal_global_rounding_mode {rounding_mode::fe_dec_default}; +BOOST_DECIMAL_INLINE_VARIABLE auto _boost_decimal_global_runtime_rounding_mode {_boost_decimal_global_rounding_mode}; BOOST_DECIMAL_EXPORT inline auto fegetround() noexcept -> rounding_mode { - return _boost_decimal_global_rounding_mode; + return _boost_decimal_global_runtime_rounding_mode; } -// If we can't support constexpr and non-constexpr code paths we won't honor the updated rounding-mode, -// since it will not be used anyway. -// Return the default rounding mode -BOOST_DECIMAL_EXPORT inline auto fesetround(const rounding_mode round) noexcept -> rounding_mode +// We can only apply updates to the runtime rounding mode +// Return the current rounding mode to the user +// NOTE: This is only updated when we have the ability to make consteval branches, +// otherwise we don't update and still let the user know what the currently applied rounding mode is +BOOST_DECIMAL_EXPORT inline auto fesetround(BOOST_DECIMAL_ATTRIBUTE_UNUSED const rounding_mode round) noexcept -> rounding_mode { - _boost_decimal_global_rounding_mode = round; - return round; + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + _boost_decimal_global_runtime_rounding_mode = round; + #endif + + return _boost_decimal_global_runtime_rounding_mode; } } // namespace decimal diff --git a/include/boost/decimal/cfloat.hpp b/include/boost/decimal/cfloat.hpp index a51e93703..865ad5209 100644 --- a/include/boost/decimal/cfloat.hpp +++ b/include/boost/decimal/cfloat.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include diff --git a/include/boost/decimal/charconv.hpp b/include/boost/decimal/charconv.hpp index fbd5a7fe8..ac6dc708f 100644 --- a/include/boost/decimal/charconv.hpp +++ b/include/boost/decimal/charconv.hpp @@ -1,4 +1,4 @@ -// Copyright 2024 Matt Borland +// Copyright 2024 - 2025 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -41,65 +44,9 @@ namespace boost { namespace decimal { // --------------------------------------------------------------------------------------------------------------------- -// from_chars and implementation +// from_chars // --------------------------------------------------------------------------------------------------------------------- -namespace detail { - -template -constexpr auto from_chars_general_impl(const char* first, const char* last, TargetDecimalType& value, const chars_format fmt) noexcept -> from_chars_result -{ - using significand_type = std::conditional_t<(std::numeric_limits::digits > - std::numeric_limits::digits), - int128::uint128_t, std::uint64_t>; - - if (first >= last) - { - return {first, std::errc::invalid_argument}; - } - - bool sign {}; - significand_type significand {}; - std::int32_t expval {}; - - auto r {detail::parser(first, last, sign, significand, expval, fmt)}; - - if (!r) - { - if (r.ec == std::errc::not_supported) - { - if (significand) - { - value = std::numeric_limits::signaling_NaN(); - } - else - { - value = std::numeric_limits::quiet_NaN(); - } - - r.ec = std::errc(); - } - else if (r.ec == std::errc::value_too_large) - { - value = std::numeric_limits::infinity(); - r.ec = std::errc::result_out_of_range; - } - else - { - value = std::numeric_limits::signaling_NaN(); - errno = static_cast(r.ec); - } - } - else - { - value = TargetDecimalType(significand, expval, sign); - } - - return r; -} - -} //namespace detail - BOOST_DECIMAL_EXPORT template constexpr auto from_chars(const char* first, const char* last, TargetDecimalType& value, const chars_format fmt = chars_format::general) noexcept -> from_chars_result { @@ -168,7 +115,7 @@ constexpr auto from_chars(std::string_view str, DecimalType& value, std::chars_f namespace detail { template -BOOST_DECIMAL_CONSTEXPR auto to_chars_nonfinite(char* first, char* last, const TargetDecimalType& value, const int fp, const chars_format fmt, const int local_precision) noexcept -> to_chars_result +constexpr auto to_chars_nonfinite(char* first, char* last, const TargetDecimalType& value, const int fp, const chars_format fmt, const int local_precision) noexcept -> to_chars_result { const auto buffer_len = last - first; @@ -289,7 +236,7 @@ constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDec const auto real_precision {get_real_precision()}; // Dummy check the bounds - if (buffer_size < real_precision) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < real_precision)) { return {last, std::errc::value_too_large}; } @@ -306,7 +253,7 @@ constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDec // which we have already checked for if (BOOST_DECIMAL_UNLIKELY(!r)) { - return r; // LCOV_EXCL_LINE + return r; } auto current_digits {r.ptr - (first + 1)}; @@ -324,7 +271,7 @@ constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDec // Make sure the result will fit in the buffer before continuing progress const auto total_length {total_buffer_length(static_cast(current_digits), exp, is_neg)}; - if (total_length > buffer_size) + if (BOOST_DECIMAL_UNLIKELY(total_length > buffer_size)) { return {last, std::errc::value_too_large}; } @@ -362,14 +309,14 @@ constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDec if (BOOST_DECIMAL_UNLIKELY(!exp_r)) { - return exp_r; // LCOV_EXCL_LINE + return exp_r; } return {exp_r.ptr, std::errc{}}; } template -BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt, const int local_precision) noexcept -> to_chars_result +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt, const int local_precision) noexcept -> to_chars_result { if (signbit(value)) { @@ -407,7 +354,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c significand /= pow10(static_cast(digits_to_remove)); significand_digits -= digits_to_remove; const auto original_sig {significand}; - fenv_round(significand); + fenv_round(significand); if (remove_trailing_zeros(original_sig + 1U).trimmed_number == 1U) { ++exp; @@ -428,7 +375,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c else if (significand_digits > local_precision + 1) { const auto original_sig = significand; - fenv_round(significand); + fenv_round(significand); if (remove_trailing_zeros(original_sig + 1U).trimmed_number == 1U) { ++exp; @@ -459,7 +406,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c // Only real reason we will hit this is a buffer overflow if (BOOST_DECIMAL_UNLIKELY(!r)) { - return r; // LCOV_EXCL_LINE + return r; } const auto current_digits = r.ptr - (first + 1) - 1; @@ -531,7 +478,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c r = to_chars_integer_impl(first, last, abs_exp); if (BOOST_DECIMAL_UNLIKELY(!r)) { - return r; // LCOV_EXCL_LINE + return r; } return {r.ptr, std::errc()}; @@ -544,7 +491,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT const auto real_precision {get_real_precision()}; // Dummy check the bounds - if (buffer_size < real_precision) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < real_precision)) { return {last, std::errc::value_too_large}; } @@ -573,7 +520,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT if (BOOST_DECIMAL_UNLIKELY(!r)) { - return r; // LCOV_EXCL_LINE + return r; } const auto num_digits {r.ptr - current}; @@ -587,7 +534,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT if (exp >= 0) { - if (buffer_size < (current - first) + num_digits + exp) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < (current - first) + num_digits + exp)) { return {last, std::errc::value_too_large}; } @@ -597,7 +544,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT } else if (abs_exp < num_digits) { - if (buffer_size < (current - first) + num_digits + 1) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < (current - first) + num_digits + 1)) { return {last, std::errc::value_too_large}; } @@ -611,7 +558,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT else { const auto leading_zeros {abs_exp - num_digits}; - if (buffer_size < (current - first) + 2 + leading_zeros + num_digits) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < (current - first) + 2 + leading_zeros + num_digits)) { return {last, std::errc::value_too_large}; } @@ -628,7 +575,7 @@ constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalT } template -BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt, const int local_precision) noexcept -> to_chars_result +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt, const int local_precision) noexcept -> to_chars_result { using target_decimal_significand_type = typename TargetDecimalType::significand_type; @@ -636,7 +583,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const auto real_precision = get_real_precision(local_precision); // Dummy check the bounds - if (buffer_size < real_precision) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < real_precision)) { return {last, std::errc::value_too_large}; } @@ -738,9 +685,9 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const // Make sure the result will fit in the buffer const std::ptrdiff_t total_length = total_buffer_length(num_dig, exponent, is_neg) + num_leading_zeros; - if (total_length > buffer_size) + if (BOOST_DECIMAL_UNLIKELY(total_length > buffer_size)) { - return {last, std::errc::value_too_large}; + return {last, std::errc::value_too_large}; // LCOV_EXCL_LINE } // Insert the leading zeros and return if the answer is ~0 for current precision @@ -916,9 +863,9 @@ constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalTyp const auto real_precision {get_real_precision()}; // Dummy check the bounds - if (buffer_size < real_precision) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < real_precision)) { - return {last, std::errc::value_too_large}; + return {last, std::errc::value_too_large}; // LCOV_EXCL_LINE } const auto components {value.to_components()}; @@ -945,9 +892,9 @@ constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalTyp // Make sure the result will fit in the buffer before continuing progress const auto total_length {total_buffer_length(static_cast(current_digits), exp, is_neg)}; - if (total_length > buffer_size) + if (BOOST_DECIMAL_UNLIKELY(total_length > buffer_size)) { - return {last, std::errc::value_too_large}; + return {last, std::errc::value_too_large}; // LCOV_EXCL_LINE } // Insert our decimal point (or don't in the 1 digit case) @@ -982,7 +929,7 @@ constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalTyp } template -BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value, const int local_precision) noexcept -> to_chars_result +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value, const int local_precision) noexcept -> to_chars_result { using Unsigned_Integer = std::conditional_t<(std::numeric_limits::digits > std::numeric_limits::digits), @@ -1007,7 +954,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const Ta real_precision = local_precision; } - if (buffer_size < real_precision) + if (BOOST_DECIMAL_UNLIKELY(buffer_size < real_precision)) { return {last, std::errc::value_too_large}; } @@ -1022,7 +969,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const Ta // Calculate the number of bytes constexpr auto significand_bits = std::is_same::value ? 64 : 128; - auto significand_digits = static_cast((static_cast(significand_bits - countl_zero(significand) + 1) / 4)); + auto significand_digits = static_cast((static_cast(significand_bits - detail::countl_zero(significand) + 1) / 4)); bool append_zeros = false; if (local_precision != -1) @@ -1114,10 +1061,76 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const Ta #endif template -BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt = chars_format::general, const int local_precision = -1) noexcept -> to_chars_result +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result +{ + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_fast_type_v) + { + return {last, std::errc::invalid_argument}; + } + + using unsigned_integer = typename TargetDecimalType::significand_type; + + const auto fp = fpclassify(value); + if (!(fp == FP_NORMAL || fp == FP_SUBNORMAL)) + { + // Cohorts are irrelevant for non-finite values + return to_chars_nonfinite(first, last, value, fp, chars_format::scientific, -1); + } + + // First we print the significand of the number by decoding the value, + // and using our existing to_chars for integers + // + // We possibly offset the to_chars by one in the event that we know we will have a fraction + const auto components {value.to_components()}; + const auto significand {components.sig}; + auto exponent {static_cast(components.exp)}; + + if (components.sign) + { + *first++ = '-'; + } + + const bool fractional_piece {significand > 10U}; + const auto r {to_chars_integer_impl(first + static_cast(fractional_piece), last, significand)}; + + if (BOOST_DECIMAL_UNLIKELY(!r)) + { + return r; // LCOV_EXCL_LINE + } + + // If there is more than one digit in the significand then we are going to need to: + // First: insert a decimal point + // Second: figure out how many decimal points we are going to have to adjust the exponent accordingly + if (fractional_piece) + { + *first = *(first + 1); + *(first + 1) = '.'; + + const auto offset {num_digits(significand) - 1}; + exponent += offset; + } + + // Insert the exponent characters ensuring that there are always at least two digits after the "e", + // e.g. e+07 not e+7 + first = r.ptr; + *first++ = 'e'; + const bool negative_exp {exponent < 0}; + *first++ = negative_exp ? '-' : '+'; + + const auto abs_exp { static_cast(negative_exp ? -exponent : exponent) }; + if (abs_exp < 10U) + { + *first++ = '0'; + } + + return to_chars_integer_impl(first, last, abs_exp); +} + +template +constexpr auto to_chars_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt = chars_format::general, const int local_precision = -1) noexcept -> to_chars_result { // Sanity check our bounds - if (first >= last) + if (BOOST_DECIMAL_UNLIKELY(first >= last)) { return {last, std::errc::invalid_argument}; } @@ -1125,7 +1138,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const Target auto abs_value = abs(value); constexpr auto max_fractional_value = decimal_val_v < 64 ? TargetDecimalType{1, 7} : decimal_val_v < 128 ? TargetDecimalType{1, 16} : - TargetDecimalType{1, 34}; + TargetDecimalType{1, 34}; constexpr auto min_fractional_value = TargetDecimalType{1, -4}; @@ -1135,7 +1148,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const Target switch (fmt) { case chars_format::general: - if (abs_value >= 1 && abs_value < max_fractional_value) + if (abs_value >= min_fractional_value && abs_value < max_fractional_value) { return to_chars_fixed_impl(first, last, value, fmt); } @@ -1149,6 +1162,15 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const Target return to_chars_scientific_impl(first, last, value, fmt); case chars_format::hex: return to_chars_hex_impl(first, last, value); + case chars_format::cohort_preserving_scientific: + + if (local_precision != -1) + { + // Precision and cohort preservation are mutually exclusive options + return {last, std::errc::invalid_argument}; + } + + return to_chars_cohort_preserving_scientific(first, last, value); // LCOV_EXCL_START default: BOOST_DECIMAL_UNREACHABLE; @@ -1163,17 +1185,16 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const Target return to_chars_fixed_impl(first, last, value, fmt, local_precision); } - if (fmt == chars_format::fixed) - { - return to_chars_fixed_impl(first, last, value, fmt, local_precision); - } - else if (fmt == chars_format::hex) - { - return to_chars_hex_impl(first, last, value, local_precision); - } - else + switch (fmt) { - return to_chars_scientific_impl(first, last, value, fmt, local_precision); + case chars_format::fixed: + return to_chars_fixed_impl(first, last, value, fmt, local_precision); + case chars_format::hex: + return to_chars_hex_impl(first, last, value, local_precision); + case chars_format::cohort_preserving_scientific: + return {last, std::errc::invalid_argument}; + default: + return to_chars_scientific_impl(first, last, value, fmt, local_precision); } } @@ -1187,19 +1208,19 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, const Target } //namespace detail BOOST_DECIMAL_EXPORT template -BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result +constexpr auto to_chars(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result { return detail::to_chars_impl(first, last, value); } BOOST_DECIMAL_EXPORT template -BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result +constexpr auto to_chars(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result { return detail::to_chars_impl(first, last, value, fmt); } BOOST_DECIMAL_EXPORT template -BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, const TargetDecimalType& value, chars_format fmt, int precision) noexcept -> to_chars_result +constexpr auto to_chars(char* first, char* last, const TargetDecimalType& value, const chars_format fmt, int precision) noexcept -> to_chars_result { if (precision < 0) { @@ -1212,7 +1233,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, const TargetDecim #ifdef BOOST_DECIMAL_HAS_STD_CHARCONV BOOST_DECIMAL_EXPORT template -BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, DecimalType value, std::chars_format fmt) +constexpr auto to_chars(char* first, char* last, DecimalType value, std::chars_format fmt) BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::to_chars_result) { to_chars_result boost_r {}; @@ -1240,7 +1261,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, DecimalType value } BOOST_DECIMAL_EXPORT template -BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, DecimalType value, std::chars_format fmt, int precision) +constexpr auto to_chars(char* first, char* last, DecimalType value, std::chars_format fmt, int precision) BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::to_chars_result) { if (precision < 0) @@ -1274,18 +1295,6 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* last, DecimalType value #endif // BOOST_DECIMAL_HAS_STD_CHARCONV -BOOST_DECIMAL_EXPORT template -struct limits -{ - static constexpr int max_chars = boost::decimal::detail::max_string_length_v; -}; - -#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900) - -template constexpr int limits::max_chars; - -#endif - } //namespace decimal } //namespace boost diff --git a/include/boost/decimal/cmath.hpp b/include/boost/decimal/cmath.hpp index 9c86c7058..76e6fc110 100644 --- a/include/boost/decimal/cmath.hpp +++ b/include/boost/decimal/cmath.hpp @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -74,6 +78,7 @@ #include #include #include +#include #include // Macros from 3.6.2 @@ -220,6 +225,11 @@ BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal64_t x) noexcept -> int return quantexpd64(x); } +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal_fast64_t x) noexcept -> int +{ + return quantexpd64f(x); +} + BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal128_t x) noexcept -> int { return quantexpd128(x); diff --git a/include/boost/decimal/cstdio.hpp b/include/boost/decimal/cstdio.hpp index 79da4483d..addb47112 100644 --- a/include/boost/decimal/cstdio.hpp +++ b/include/boost/decimal/cstdio.hpp @@ -43,6 +43,12 @@ enum class decimal_type : unsigned decimal128_t = 1 << 2 }; +// Internal use only +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + struct parameters { int precision; @@ -51,6 +57,10 @@ struct parameters bool upper_case; }; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + inline auto parse_format(const char* format) -> parameters { // If the format is unspecified or incorrect, we will use this as the default values @@ -154,6 +164,12 @@ inline void make_uppercase(char* first, const char* last) noexcept } } +// Cast of return value avoids warning when sizeof(std::ptrdiff_t) > sizeof(int) e.g. when not in 32-bit +#if defined(__GNUC__) && defined(__i386__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wuseless-cast" +#endif + template inline auto snprintf_impl(char* buffer, const std::size_t buf_size, const char* format, const T... values) noexcept #ifndef BOOST_DECIMAL_HAS_CONCEPTS @@ -216,10 +232,8 @@ inline auto snprintf_impl(char* buffer, const std::size_t buf_size, const char* if (!r) { - // LCOV_EXCL_START errno = static_cast(r.ec); return -1; - // LCOV_EXCL_STOP } // Adjust the capitalization and locale @@ -227,9 +241,10 @@ inline auto snprintf_impl(char* buffer, const std::size_t buf_size, const char* { detail::make_uppercase(buffer, r.ptr); } - convert_pointer_pair_to_local_locale(buffer, r.ptr); + *r.ptr = '\0'; + const auto offset {convert_pointer_pair_to_local_locale(buffer, buffer + buf_size - byte_count)}; - buffer = r.ptr; + buffer = r.ptr + (offset == -1 ? 0 : offset); if (value_iter != values_list.end()) { @@ -241,6 +256,10 @@ inline auto snprintf_impl(char* buffer, const std::size_t buf_size, const char* return static_cast(buffer - buffer_begin); } +#if defined(__GNUC__) && defined(__i386__) +# pragma GCC diagnostic pop +#endif + } // namespace detail template @@ -276,7 +295,7 @@ inline auto fprintf(std::FILE* buffer, const char* format, const T... values) no int bytes {}; char char_buffer[1024]; - if (format_len + value_space <= 1024U) + if (format_len + value_space <= ((1024 * 2) / 3)) { bytes = detail::snprintf_impl(char_buffer, sizeof(char_buffer), format, values...); if (bytes) @@ -286,8 +305,8 @@ inline auto fprintf(std::FILE* buffer, const char* format, const T... values) no } else { - // LCOV_EXCL_START - std::unique_ptr longer_char_buffer(new(std::nothrow) char[format_len + value_space + 1]); + // Add 50% overage in case we need to do locale conversion + std::unique_ptr longer_char_buffer(new(std::nothrow) char[(3 * (format_len + value_space + 1)) / 2]); if (longer_char_buffer == nullptr) { errno = ENOMEM; @@ -299,7 +318,6 @@ inline auto fprintf(std::FILE* buffer, const char* format, const T... values) no { bytes += static_cast(std::fwrite(longer_char_buffer.get(), sizeof(char), static_cast(bytes), buffer)); } - // LCOV_EXCL_STOP } return bytes; diff --git a/include/boost/decimal/cstdlib.hpp b/include/boost/decimal/cstdlib.hpp index dc4003a52..937d717ba 100644 --- a/include/boost/decimal/cstdlib.hpp +++ b/include/boost/decimal/cstdlib.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -44,11 +45,26 @@ inline auto strtod_calculation(const char* str, char** endptr, char* buffer, con std::memcpy(buffer, str, str_length); convert_string_to_c_locale(buffer); + // Strtod allows leading whitespace characters + auto first {buffer}; + std::size_t first_pos {0}; + while (first_pos < str_length && *first <= static_cast(32)) + { + ++first; + ++first_pos; + } + + // The plus sign is also allowed before the value + if (first_pos < str_length && *first == '+') + { + ++first; + } + bool sign {}; significand_type significand {}; std::int32_t expval {}; - const auto r {detail::parser(buffer, buffer + str_length, sign, significand, expval)}; + const auto r {detail::parser(first, buffer + str_length, sign, significand, expval)}; TargetDecimalType d {}; if (r.ec != std::errc{}) @@ -109,11 +125,8 @@ inline auto strtod_impl(const char* str, char** endptr) noexcept -> TargetDecima std::unique_ptr buffer(new(std::nothrow) char[str_length + 1]); if (buffer == nullptr) { - // Hard to get coverage on memory exhaustion - // LCOV_EXCL_START errno = ENOMEM; return std::numeric_limits::quiet_NaN(); - // LCOV_EXCL_STOP } auto d = strtod_calculation(str, endptr, buffer.get(), str_length); @@ -132,7 +145,7 @@ inline auto wcstod_calculation(const wchar_t* str, wchar_t** endptr, char* buffe if (BOOST_DECIMAL_UNLIKELY(val > 255)) { // Character can not be converted - return std::numeric_limits::quiet_NaN(); // LCOV_EXCL_LINE + return std::numeric_limits::quiet_NaN(); } buffer[i] = static_cast(val); @@ -172,11 +185,8 @@ inline auto wcstod_impl(const wchar_t* str, wchar_t** endptr) noexcept -> Target std::unique_ptr buffer(new(std::nothrow) char[str_length + 1]); if (buffer == nullptr) { - // Hard to get coverage on memory exhaustion - // LCOV_EXCL_START errno = ENOMEM; return std::numeric_limits::quiet_NaN(); - // LCOV_EXCL_STOP } return wcstod_calculation(str, endptr, buffer.get(), str_length); diff --git a/include/boost/decimal/decimal128.hpp b/include/boost/decimal/decimal128.hpp deleted file mode 100644 index 619876a53..000000000 --- a/include/boost/decimal/decimal128.hpp +++ /dev/null @@ -1,2143 +0,0 @@ -// Copyright 2023 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal128_t_HPP -#define BOOST_DECIMAL_decimal128_t_HPP - -#include -#include -#include -#include -#include -#include "detail/int128.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "detail/int128.hpp" -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) -#include -#include -#include -#endif - -#endif //BOOST_DECIMAL_BUILD_MODULE - -namespace boost { -namespace decimal { - -namespace detail { - -// See IEEE 754 section 3.5.2 -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_inf_mask {UINT64_C(0x7800000000000000), UINT64_C(0)}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_nan_mask {UINT64_C(0x7C00000000000000), UINT64_C(0)}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_snan_mask {UINT64_C(0x7E00000000000000), UINT64_C(0)}; - -// Comb. Exponent Significand -// s eeeeeeeeeeeeee (0TTT) 110-bits -// s 11 eeeeeeeeeeeeee (100T) 110-bits - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_sign_mask {UINT64_C(0b1'00000'00000000'0000000000'0000000000'0000000000'0000000000'0000000000)}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_combination_field_mask = UINT64_C(0b0'11'00000000'000'0000000000'0000000000'0000000000'0000000000'0000000000); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_not_11_exp_mask = UINT64_C(0b0'11111111111111'000000000'0000000000'0000000000'0000000000'0000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_not_11_exp_high_word_shift {49U}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_11_exp_mask {UINT64_C(0b0'00'11111111111111'0000000'0000000000'0000000000'0000000000'0000000000)}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_11_exp_high_word_shift {47U}; - -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_not_11_significand_mask {UINT64_C(0b0'00000000000000'111111111'1111111111'1111111111'1111111111'1111111111), UINT64_MAX}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_11_significand_mask {UINT64_C(0b0'00'00000000000000'1111111'1111111111'1111111111'1111111111'1111111111), UINT64_MAX}; - -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_biggest_no_combination_significand {d128_not_11_significand_mask}; - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d128_max_biased_exponent {UINT64_C(12287)}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE int128::uint128_t d128_max_significand_value {UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}; - -template -constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -} //namespace detail - -BOOST_DECIMAL_EXPORT class decimal128_t final -{ -public: - using significand_type = boost::int128::uint128_t; - using exponent_type = std::uint64_t; - using biased_exponent_type = std::int32_t; - -private: - int128::uint128_t bits_ {}; - - #ifdef BOOST_DECIMAL_HAS_INT128 - - friend constexpr auto from_bits(detail::builtin_uint128_t rhs) noexcept -> decimal128_t; - friend constexpr auto to_bits(decimal128_t rhs) noexcept -> detail::builtin_uint128_t; - - #endif - - friend constexpr auto from_bits(int128::uint128_t rhs) noexcept -> decimal128_t; - - constexpr auto unbiased_exponent() const noexcept -> std::uint64_t; - constexpr auto biased_exponent() const noexcept -> std::int32_t; - constexpr auto full_significand() const noexcept -> int128::uint128_t; - constexpr auto isneg() const noexcept -> bool; - constexpr auto to_components() const noexcept -> detail::decimal128_t_components; - - // Allows direct editing of the exp - template , bool> = true> - constexpr auto edit_exponent(T exp) noexcept -> void; - constexpr auto edit_sign(bool sign) noexcept -> void; - - // Attempts conversion to integral type: - // If this is nan sets errno to EINVAL and returns 0 - // If this is not representable sets errno to ERANGE and returns 0 - template - friend constexpr auto to_integral_128(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - template - friend BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; - - // Equality template between any integer type and decimal128_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal128_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - friend constexpr auto d128_div_impl(const decimal128_t& lhs, const decimal128_t& rhs, decimal128_t& q, decimal128_t& r) noexcept -> void; - - friend constexpr auto d128_mod_impl(const decimal128_t& lhs, const decimal128_t& rhs, const decimal128_t& q, decimal128_t& r) noexcept -> void; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - friend constexpr auto not_finite(decimal128_t rhs) noexcept -> bool; - - friend constexpr auto to_bid_d128(decimal128_t val) noexcept -> int128::uint128_t; - - friend constexpr auto from_bid_d128(int128::uint128_t bits) noexcept -> decimal128_t; - - #ifdef BOOST_DECIMAL_HAS_INT128 - friend constexpr auto from_bid_d128(detail::builtin_uint128_t bits) noexcept -> decimal128_t; - #endif - - template - friend constexpr auto to_dpd_d128(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, int128::uint128_t); - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - // 3.2.4.1 construct/copy/destroy - constexpr decimal128_t() noexcept = default; - constexpr decimal128_t& operator=(const decimal128_t& rhs) noexcept = default; - constexpr decimal128_t& operator=(decimal128_t&& rhs) noexcept = default; - constexpr decimal128_t(const decimal128_t& rhs) noexcept = default; - constexpr decimal128_t(decimal128_t&& rhs) noexcept = default; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - #ifndef BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS - explicit - #endif - BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept; - - template - BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal128_t&); - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - explicit constexpr decimal128_t(Decimal val) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - constexpr decimal128_t(Integer val) noexcept; - - template - constexpr auto operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); - - // 3.2.5 initialization from coefficient and exponent: - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal128_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal128_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal128_t(bool value) noexcept; - - // 3.2.4.4 Conversion to integral type - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - explicit constexpr operator boost::int128::int128_t() const noexcept; - explicit constexpr operator boost::int128::uint128_t() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator detail::builtin_int128_t() const noexcept; - explicit constexpr operator detail::builtin_uint128_t() const noexcept; - #endif - - // 3.2.6 Conversion to floating-point type - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> - constexpr operator Decimal() const noexcept; - - template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> - explicit constexpr operator Decimal() const noexcept; - - // cmath functions that are easier as friends - friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; - - // 3.2.7 unary arithmetic operators: - friend constexpr auto operator+(decimal128_t rhs) noexcept -> decimal128_t; - friend constexpr auto operator-(decimal128_t rhs) noexcept -> decimal128_t; - - // 3.2.8 Binary arithmetic operators - friend constexpr auto operator+(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator+(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator+(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator-(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator-(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator-(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator*(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator*(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator*(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator/(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator/(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator/(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator%(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - // 3.2.4.5 Increment and Decrement - constexpr auto operator++() noexcept -> decimal128_t&; - constexpr auto operator++(int) noexcept -> decimal128_t; // NOLINT : C++14 so constexpr implies const - constexpr auto operator--() noexcept -> decimal128_t&; - constexpr auto operator--(int) noexcept -> decimal128_t; // NOLINT : C++14 so constexpr implies const - - // 3.2.4.6 Compound Assignment - constexpr auto operator+=(decimal128_t rhs) noexcept -> decimal128_t&; - - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); - - template - constexpr auto operator+=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); - - constexpr auto operator-=(decimal128_t rhs) noexcept -> decimal128_t&; - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); - - template - constexpr auto operator-=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); - - constexpr auto operator*=(decimal128_t rhs) noexcept -> decimal128_t&; - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); - - template - constexpr auto operator*=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); - - constexpr auto operator/=(decimal128_t rhs) noexcept -> decimal128_t&; - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); - - template - constexpr auto operator/=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); - - constexpr auto operator%=(decimal128_t rhs) noexcept -> decimal128_t&; - - // 3.2.9 Comparison operators: - // Equality - friend constexpr auto operator==(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator==(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Inequality - friend constexpr auto operator!=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator!=(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less - friend constexpr auto operator<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator<(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less equal - friend constexpr auto operator<=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator<=(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater - friend constexpr auto operator>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator>(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater equal - friend constexpr auto operator>=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - template - friend constexpr auto operator>=(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // C++20 spaceship - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - friend constexpr auto operator<=>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - #endif - - #if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) - friend inline std::string bit_string(decimal128_t rhs) noexcept; - #endif - - // 3.6.4 Same Quantum - friend constexpr auto samequantumd128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; - - // 3.6.5 Quantum exponent - friend constexpr auto quantexpd128(decimal128_t x) noexcept -> int; - - // 3.6.6 Quantize - friend constexpr auto quantized128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - // Bit-wise operators - friend constexpr auto operator&(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator&(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator&(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator|(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator|(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator|(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator^(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator^(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator^(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator<<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator<<(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator<<(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator>>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; - - template - friend constexpr auto operator>>(decimal128_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - template - friend constexpr auto operator>>(Integer lhs, decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); - - friend constexpr auto operator~(decimal128_t rhs) noexcept -> decimal128_t; - - // functions that need to be friends - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto copysignd128(decimal128_t mag, decimal128_t sgn) noexcept -> decimal128_t; - friend constexpr auto scalblnd128(decimal128_t num, long exp) noexcept -> decimal128_t; - friend constexpr auto scalbnd128(decimal128_t num, int exp) noexcept -> decimal128_t; - friend constexpr auto fmad128(decimal128_t x, decimal128_t y, decimal128_t z) noexcept -> decimal128_t; -}; - -BOOST_DECIMAL_EXPORT using decimal128 [[deprecated("Use re-named type decimal128_t instead of decimal128")]] = decimal128_t; - -#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) -inline std::string bit_string(decimal128_t rhs) noexcept -{ - std::stringstream ss; - ss << std::hex << rhs.bits_.high << rhs.bits_.low; - return ss.str(); -} -#endif - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr auto from_bits(const detail::builtin_uint128_t rhs) noexcept -> decimal128_t -{ - decimal128_t result; - result.bits_ = rhs; - - return result; -} - -constexpr auto to_bits(const decimal128_t rhs) noexcept -> detail::builtin_uint128_t -{ - return static_cast(rhs.bits_); -} - -#endif - -constexpr auto from_bits(const int128::uint128_t rhs) noexcept -> decimal128_t -{ - decimal128_t result; - result.bits_ = rhs; - - return result; -} - -constexpr auto decimal128_t::unbiased_exponent() const noexcept -> exponent_type -{ - exponent_type expval {}; - - if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) - { - expval = (bits_.high & detail::d128_11_exp_mask) >> detail::d128_11_exp_high_word_shift; - } - else - { - expval = (bits_.high & detail::d128_not_11_exp_mask) >> detail::d128_not_11_exp_high_word_shift; - } - - return expval; -} - -constexpr auto decimal128_t::biased_exponent() const noexcept -> biased_exponent_type -{ - return static_cast(unbiased_exponent()) - detail::bias_v; -} - -constexpr auto decimal128_t::full_significand() const noexcept -> significand_type -{ - significand_type significand {}; - - if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) - { - constexpr int128::uint128_t implied_bit {UINT64_C(0b10000000000000000000000000000000000000000000000000),0}; - significand = implied_bit | (bits_ & detail::d128_11_significand_mask); - } - else - { - significand = bits_ & detail::d128_not_11_significand_mask; - } - - return significand; -} - -constexpr auto decimal128_t::isneg() const noexcept -> bool -{ - return static_cast(bits_.high & detail::d128_sign_mask); -} - -constexpr auto decimal128_t::to_components() const noexcept -> detail::decimal128_t_components -{ - significand_type significand {}; - exponent_type expval {}; - - if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) - { - constexpr int128::uint128_t implied_bit {UINT64_C(0b10000000000000000000000000000000000000000000000000),0}; - significand = implied_bit | (bits_ & detail::d128_11_significand_mask); - expval = (bits_.high & detail::d128_11_exp_mask) >> detail::d128_11_exp_high_word_shift; - } - else - { - significand = bits_ & detail::d128_not_11_significand_mask; - expval = (bits_.high & detail::d128_not_11_exp_mask) >> detail::d128_not_11_exp_high_word_shift; - } - - const auto sign {static_cast(bits_.high & detail::d128_sign_mask)}; - - return detail::decimal128_t_components {significand, static_cast(expval) - detail::bias_v, sign}; -} - - -template , bool>> -constexpr auto decimal128_t::edit_exponent(const T expval) noexcept -> void -{ - *this = decimal128_t(this->full_significand(), expval, this->isneg()); -} - -constexpr auto decimal128_t::edit_sign(const bool sign) noexcept -> void -{ - if (sign) - { - bits_.high |= detail::d128_sign_mask; - } - else - { - constexpr auto not_sign_mask {~detail::d128_sign_mask}; - bits_.high &= not_sign_mask; - } -} - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wduplicated-branches" -# pragma GCC diagnostic ignored "-Wconversion" -#endif - - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4127) -#endif - -// e.g. for sign bits_.high |= detail::d128_sign_mask -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, bool sign) noexcept -{ - bits_.high = sign ? detail::d128_sign_mask : UINT64_C(0); - - // If the coeff is not in range make it so - // The coefficient needs at least 110 bits so there's a good chance we don't need to - // We use sizeof instead of std::numeric_limits since __int128 on GCC prior to 14 without GNU mode does not overload - // numeric_limits - int coeff_digits {-1}; - BOOST_DECIMAL_IF_CONSTEXPR (sizeof(T1) >= sizeof(significand_type)) - { - if (coeff > detail::d128_max_significand_value) - { - constexpr auto precision_plus_one {detail::precision_v + 1}; - coeff_digits = detail::d128_constructor_num_digits(coeff); - if (coeff_digits > precision_plus_one) - { - const auto digits_to_remove {coeff_digits - precision_plus_one}; - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic push - # pragma GCC diagnostic ignored "-Wconversion" - #endif - - coeff /= detail::pow10(static_cast(digits_to_remove)); - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic pop - #endif - - coeff_digits -= digits_to_remove; - exp += detail::fenv_round(coeff, sign) + digits_to_remove; - } - // Round as required - else - { - exp += detail::fenv_round(coeff, sign); - } - } - } - - constexpr int128::uint128_t zero {0, 0}; - auto reduced_coeff {static_cast(coeff)}; - - if (reduced_coeff == zero) - { - return; - } - - // The decimal128_t case is more straightforward than the others - // The precision of the type is 34, and 34x 9s fits into 113 bits, - // therefore we never need to use the combination field for additional space - - bits_ |= (reduced_coeff & detail::d128_not_11_significand_mask); - - // If the exponent fits we do not need to use the combination field - const auto biased_exp {static_cast(exp + detail::bias_v)}; - if (biased_exp <= detail::d128_max_biased_exponent) - { - bits_.high |= (biased_exp << detail::d128_not_11_exp_high_word_shift) & detail::d128_not_11_exp_mask; - } - else - { - // If we can fit the extra exponent in the significand, then we can construct the value - // If we can't, the value is either 0 or infinity depending on the sign of exp - - if (coeff_digits == -1) - { - coeff_digits = detail::num_digits(reduced_coeff); - } - - const auto exp_delta {biased_exp - detail::d128_max_biased_exponent}; - const auto digit_delta {coeff_digits - static_cast(exp_delta)}; - if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision_v) - { - exp -= digit_delta; - reduced_coeff *= detail::pow10(static_cast(digit_delta)); - *this = decimal128_t(reduced_coeff, exp, sign); - } - else - { - bits_ = exp < 0 ? zero : detail::d128_inf_mask; - } - } -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal128_t::decimal128_t(const T1 coeff, const T2 exp) noexcept : decimal128_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -constexpr decimal128_t::decimal128_t(const bool value) noexcept : decimal128_t(static_cast(value), 0, false) {} - - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic pop -#endif - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::decimal128_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - *this = from_bits(detail::d128_nan_mask); - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - *this = from_bits(detail::d128_inf_mask); - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "Mant: " << components.mantissa - << "\nExp: " << components.exponent - << "\nSign: " << components.sign << std::endl; - #endif - - if (components.exponent > detail::emax_v) - { - *this = from_bits(detail::d128_inf_mask); - } - else - { - *this = decimal128_t {components.mantissa, components.exponent, components.sign}; - } - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -template -BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal128_t::operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal128_t&) -{ - *this = decimal128_t{val}; - return *this; -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal128_t::decimal128_t(const Integer val) noexcept : decimal128_t{val, 0} {} - -template -constexpr auto decimal128_t::operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) -{ - using ConversionType = std::conditional_t::value, std::int32_t, Integer>; - *this = decimal128_t{static_cast(val), 0}; - return *this; -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal128_t::decimal128_t(const Decimal val) noexcept -{ - *this = to_decimal(val); -} - -constexpr decimal128_t::operator bool() const noexcept -{ - constexpr decimal128_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal128_t::operator int() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator unsigned() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator unsigned long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator long long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator unsigned long long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator boost::int128::int128_t() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator boost::int128::uint128_t() const noexcept -{ - return to_integral_128(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal128_t::operator detail::builtin_int128_t() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal128_t::operator detail::builtin_uint128_t() const noexcept -{ - return to_integral_128(*this); -} - -#endif //BOOST_DECIMAL_HAS_INT128 - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator long double() const noexcept -{ - return to_float(*this); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal128_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal128_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal128_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal128_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -template && (detail::decimal_val_v > detail::decimal_val_v), bool>> -constexpr decimal128_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> -constexpr decimal128_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - return rhs.bits_.high & detail::d128_sign_mask; -} - -constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_.high & detail::d128_nan_mask.high) == detail::d128_nan_mask.high; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_.high & detail::d128_nan_mask.high) == detail::d128_inf_mask.high; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_.high & detail::d128_snan_mask.high) == detail::d128_snan_mask.high; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check for de-normals - const auto sig {rhs.full_significand()}; - const auto exp {rhs.unbiased_exponent()}; - - if (exp <= detail::precision_v - 1) - { - return false; - } - - return (sig != 0U) && isfinite(rhs); - #else - return rhs.full_significand() != 0U; - #endif -} - -constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_.high & detail::d128_inf_mask.high) != detail::d128_inf_mask.high; - #else - static_cast(rhs); - return true; - #endif -} - -BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal128_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_.high & detail::d128_inf_mask.high) == detail::d128_inf_mask.high; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto operator+(const decimal128_t rhs) noexcept -> decimal128_t -{ - return rhs; -} - -constexpr auto operator-(decimal128_t rhs) noexcept-> decimal128_t -{ - rhs.bits_.high ^= detail::d128_sign_mask; - return rhs; -} - - -constexpr auto operator==(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - return equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -constexpr auto operator!=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -constexpr auto operator<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - if (isnan(lhs) || isnan(rhs) || - (!lhs.isneg() && rhs.isneg())) - { - return false; - } - if (lhs.isneg() && !rhs.isneg()) - { - return true; - } - if (isfinite(lhs) && isinf(rhs)) - { - return !rhs.isneg(); - } - } - #endif - - return less_parts_impl(lhs.full_significand(), lhs.biased_exponent(), lhs.isneg(), - rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()); -} - -template -constexpr auto operator<(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !less_impl(rhs, lhs) && lhs != rhs; -} - -constexpr auto operator<=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -constexpr auto operator>=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif - -#ifdef BOOST_DECIMAL_DEBUG_ADD_128 -static char* mini_to_chars( char (&buffer)[ 64 ], boost::decimal::detail::builtin_uint128_t v ) -{ - char* p = buffer + 64; - *--p = '\0'; - - do - { - *--p = "0123456789"[ v % 10 ]; - v /= 10; - } - while ( v != 0 ); - - return p; -} - -#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) -std::ostream& operator<<( std::ostream& os, boost::decimal::detail::builtin_uint128_t v ) -{ - char buffer[ 64 ]; - - os << mini_to_chars( buffer, v ); - return os; -} -#endif -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // If constexpr macro only works for C++17 and above -#endif - -constexpr auto d128_div_impl(const decimal128_t& lhs, const decimal128_t& rhs, decimal128_t& q, decimal128_t& r) noexcept -> void -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal128_t zero {0, 0}; - constexpr decimal128_t nan {boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask)}; - constexpr decimal128_t inf {boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask)}; - - const bool sign {lhs.isneg() != rhs.isneg()}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - #else - static_cast(r); - #endif - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - detail::decimal128_t_components lhs_components {sig_lhs, exp_lhs, lhs.isneg()}; - detail::decimal128_t_components rhs_components {sig_rhs, exp_rhs, rhs.isneg()}; - detail::decimal128_t_components q_components {}; - - detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); - - q = decimal128_t(q_components.sig, q_components.exp, q_components.sign); -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -constexpr auto d128_mod_impl(const decimal128_t& lhs, const decimal128_t& rhs, const decimal128_t& q, decimal128_t& r) noexcept -> void -{ - constexpr decimal128_t zero {0, 0}; - - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal128_t(q_trunc) * rhs); -} - -constexpr auto operator+(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_sig {lhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - detail::normalize(lhs_sig, lhs_exp); - - auto rhs_sig {rhs.full_significand()}; - auto rhs_exp {rhs.biased_exponent()}; - detail::normalize(rhs_sig, rhs_exp); - - return detail::d128_add_impl(lhs_sig, lhs_exp, lhs.isneg(), - rhs_sig, rhs_exp, rhs.isneg(), - abs(lhs) > abs(rhs)); -} - -template -constexpr auto operator+(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - using exp_type = decimal128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_add_impl(sig_lhs, exp_lhs, lhs.isneg(), - sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator+(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return rhs + lhs; -} - -// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa -constexpr auto operator-(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_sub_impl( - sig_lhs, exp_lhs, lhs.isneg(), - sig_rhs, exp_rhs, rhs.isneg(), - abs(lhs) > abs(rhs)); -} - -template -constexpr auto operator-(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - using exp_type = decimal128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - const bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_sub_impl( - sig_lhs, exp_lhs, lhs.isneg(), - sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator-(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - using exp_type = decimal128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - const bool abs_lhs_bigger {sig_lhs > abs(rhs)}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_sub_impl( - sig_lhs, exp_lhs, (lhs < 0), - sig_rhs, exp_rhs, rhs.isneg(), - abs_lhs_bigger); -} - -constexpr auto operator*(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - const auto lhs_sig {lhs.full_significand()}; - const auto lhs_exp {lhs.biased_exponent()}; - - const auto rhs_sig {rhs.full_significand()}; - const auto rhs_exp {rhs.biased_exponent()}; - - return detail::d128_mul_impl( - lhs_sig, lhs_exp, lhs.isneg(), - rhs_sig, rhs_exp, rhs.isneg()); -} - -template -constexpr auto operator*(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - using exp_type = decimal128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto lhs_sig {lhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - const auto lhs_zeros {detail::remove_trailing_zeros(lhs_sig)}; - lhs_sig = lhs_zeros.trimmed_number; - lhs_exp += static_cast(lhs_zeros.number_of_removed_zeros); - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - const auto rhs_zeros {detail::remove_trailing_zeros(rhs_sig)}; - rhs_sig = rhs_zeros.trimmed_number; - const auto rhs_exp = static_cast(rhs_zeros.number_of_removed_zeros); - - return detail::d128_mul_impl( - lhs_sig, lhs_exp, lhs.isneg(), - rhs_sig, rhs_exp, (rhs < 0)); - -} - -template -constexpr auto operator*(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return rhs * lhs; -} - -constexpr auto operator/(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - decimal128_t q {}; - decimal128_t r {}; - d128_div_impl(lhs, rhs, q, r); - - return q; -} - -template -constexpr auto operator/(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal128_t zero {0, 0}; - constexpr decimal128_t nan {boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask)}; - constexpr decimal128_t inf {boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask)}; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - auto lhs_sig {lhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - detail::normalize(lhs_sig, lhs_exp); - - const detail::decimal128_t_components lhs_components {lhs_sig, lhs_exp, lhs.isneg()}; - - const detail::decimal128_t_components rhs_components {detail::make_positive_unsigned(rhs), 0, rhs < 0}; - detail::decimal128_t_components q_components {}; - - detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); - - return decimal128_t(q_components.sig, q_components.exp, q_components.sign); -} - -template -constexpr auto operator/(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal128_t zero {0, 0}; - constexpr decimal128_t inf {boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask)}; - constexpr decimal128_t nan {boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask)}; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - const auto rhs_fp {fpclassify(rhs)}; - - if (rhs_fp == FP_NAN) - { - return nan; - } - - switch (rhs_fp) - { - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - auto rhs_sig {rhs.full_significand()}; - auto rhs_exp {rhs.biased_exponent()}; - detail::normalize(rhs_sig, rhs_exp); - - const detail::decimal128_t_components lhs_components {detail::make_positive_unsigned(lhs), 0, lhs < 0}; - const detail::decimal128_t_components rhs_components {rhs_sig, rhs_exp, rhs.isneg()}; - detail::decimal128_t_components q_components {}; - - detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); - - return decimal128_t(q_components.sig, q_components.exp, q_components.sign); -} - -constexpr auto operator%(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - decimal128_t q {}; - decimal128_t r {}; - d128_div_impl(lhs, rhs, q, r); - d128_mod_impl(lhs, rhs, q, r); - - return r; -} - -constexpr auto decimal128_t::operator++() noexcept -> decimal128_t& -{ - constexpr decimal128_t one{1, 0}; - *this = *this + one; - return *this; -} - -constexpr auto decimal128_t::operator++(int) noexcept -> decimal128_t -{ - return ++(*this); -} - -constexpr auto decimal128_t::operator--() noexcept -> decimal128_t& -{ - constexpr decimal128_t one{1, 0}; - *this = *this - one; - return *this; -} - -constexpr auto decimal128_t::operator--(int) noexcept -> decimal128_t -{ - return --(*this); -} - -constexpr auto decimal128_t::operator+=(const decimal128_t rhs) noexcept -> decimal128_t& -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator+=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) -{ - *this = *this + rhs; - return *this; -} - -constexpr auto decimal128_t::operator-=(const decimal128_t rhs) noexcept -> decimal128_t& -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator-=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) -{ - *this = *this - rhs; - return *this; -} - -constexpr auto decimal128_t::operator*=(const decimal128_t rhs) noexcept -> decimal128_t& -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator*=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) -{ - *this = *this * rhs; - return *this; -} - -constexpr auto decimal128_t::operator/=(const decimal128_t rhs) noexcept -> decimal128_t& -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal128_t::operator/=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr auto decimal128_t::operator%=(const decimal128_t rhs) noexcept -> decimal128_t& -{ - *this = *this % rhs; - return *this; -} - -// 3.6.4 -// Effects: determines if the quantum exponents of x and y are the same. -// If both x and y are NaN, or infinity, they have the same quantum exponents; -// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -// The samequantum functions raise no exception. -constexpr auto samequantumd128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) - { - return true; - } - if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) - { - return false; - } - #endif - - return lhs.unbiased_exponent() == rhs.unbiased_exponent(); -} - -// 3.6.5 -// Effects: if x is finite, returns its quantum exponent. -// Otherwise, a domain error occurs and INT_MIN is returned. -constexpr auto quantexpd128(const decimal128_t x) noexcept -> int -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(x)) - { - return INT_MIN; - } - #endif - - return static_cast(x.unbiased_exponent()); -} - -// 3.6.6 -// Returns: a number that is equal in value (except for any rounding) and sign to x, -// and which has an exponent set to be equal to the exponent of y. -// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; -// if the result does not have the same value as x, the "inexact" floating-point exception is raised. -// If the exponent is being decreased and the significand of the result has more digits than the type would allow, -// the "invalid" floating-point exception is raised and the result is NaN. -// If one or both operands are NaN the result is NaN. -// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. -// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. -// The quantize functions do not signal underflow. -constexpr auto quantized128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Return the correct type of nan - if (isnan(lhs)) - { - return lhs; - } - else if (isnan(rhs)) - { - return rhs; - } - - // If one is infinity then return a signaling NAN - if (isinf(lhs) != isinf(rhs)) - { - return boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask); - } - else if (isinf(lhs) && isinf(rhs)) - { - return lhs; - } - #endif - - return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; -} - -constexpr auto operator&(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - return from_bits(lhs.bits_ & rhs.bits_); -} - -template -constexpr auto operator&(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(lhs.bits_ & static_cast(rhs)); -} - -template -constexpr auto operator&(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(static_cast(lhs) & rhs.bits_); -} - -constexpr auto operator|(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - return from_bits(lhs.bits_ | rhs.bits_); -} - -template -constexpr auto operator|(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(lhs.bits_ | static_cast(rhs)); -} - -template -constexpr auto operator|(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(static_cast(lhs) | rhs.bits_); -} - -constexpr auto operator^(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - return from_bits(lhs.bits_ ^ rhs.bits_); -} - -template -constexpr auto operator^(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(lhs.bits_ ^ static_cast(rhs)); -} - -template -constexpr auto operator^(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(static_cast(lhs) ^ rhs.bits_); -} - -constexpr auto operator<<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - return from_bits(lhs.bits_ << static_cast(rhs.bits_)); -} - -template -constexpr auto operator<<(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(lhs.bits_ << static_cast(rhs)); -} - -template -constexpr auto operator<<(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(static_cast(lhs) << static_cast(rhs.bits_)); -} - -constexpr auto operator>>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t -{ - return from_bits(lhs.bits_ >> static_cast(rhs.bits_)); -} - -template -constexpr auto operator>>(const decimal128_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(lhs.bits_ >> static_cast(rhs)); -} - -template -constexpr auto operator>>(const Integer lhs, const decimal128_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) -{ - return from_bits(static_cast(lhs) >> static_cast(rhs.bits_)); -} - -constexpr auto operator~(const decimal128_t lhs) noexcept -> decimal128_t -{ - return from_bits(~lhs.bits_); -} - -constexpr auto copysignd128(decimal128_t mag, const decimal128_t sgn) noexcept -> decimal128_t -{ - mag.edit_sign(sgn.isneg()); - return mag; -} - -constexpr auto scalblnd128(decimal128_t num, const long exp) noexcept -> decimal128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal128_t zero {0, 0}; - - if (num == zero || exp == 0 || not_finite(num)) - { - return num; - } - #endif - - num.edit_exponent(num.biased_exponent() + exp); - - return num; -} - -constexpr auto scalbnd128(decimal128_t num, const int expval) noexcept -> decimal128_t -{ - return scalblnd128(num, static_cast(expval)); -} - -} //namespace decimal -} //namespace boost - -namespace std { - -template<> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ - -#ifdef _MSC_VER - public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_present; - static constexpr bool has_denorm_loss = true; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = true; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 34; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -6143; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 6144; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal128_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal128_t { return {boost::int128::uint128_t{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal128_t { return {boost::int128::uint128_t{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal128_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal128_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_nan_mask); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask); } - static constexpr auto denorm_min () -> boost::decimal::decimal128_t { return {1, boost::decimal::detail::etiny_v}; } -}; - -} //namespace std - -#endif //BOOST_DECIMAL_decimal128_t_HPP diff --git a/include/boost/decimal/decimal128_fast.hpp b/include/boost/decimal/decimal128_fast.hpp deleted file mode 100644 index 0c5c0a3d8..000000000 --- a/include/boost/decimal/decimal128_fast.hpp +++ /dev/null @@ -1,1443 +0,0 @@ -// Copyright 2024 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal_fast128_t_HPP -#define BOOST_DECIMAL_decimal_fast128_t_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE - -#include -#include - -#endif - -namespace boost { -namespace decimal { - -namespace detail { - -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_inf = boost::int128::uint128_t {UINT64_MAX - 2, UINT64_MAX}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_qnan = boost::int128::uint128_t {UINT64_MAX - 1, UINT64_MAX}; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_snan = boost::int128::uint128_t {UINT64_MAX, UINT64_MAX}; - -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_inf_high_bits = UINT64_MAX - 2; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_qnan_high_bits = UINT64_MAX - 1; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d128_fast_snan_high_bits = UINT64_MAX; - -} // namespace detail - -BOOST_DECIMAL_EXPORT class decimal_fast128_t final -{ -public: - using significand_type = int128::uint128_t; - using exponent_type = std::uint32_t; - using biased_exponent_type = std::int32_t; - -private: - // Instead of having to encode and decode at every operation - // we store the constituent pieces directly - - significand_type significand_ {}; - exponent_type exponent_ {}; - bool sign_ {}; - - constexpr auto isneg() const noexcept -> bool - { - return sign_; - } - - constexpr auto full_significand() const noexcept -> significand_type - { - return significand_; - } - - constexpr auto unbiased_exponent() const noexcept -> exponent_type - { - return exponent_; - } - - constexpr auto biased_exponent() const noexcept -> biased_exponent_type - { - return static_cast(exponent_) - detail::bias_v; - } - - constexpr auto to_components() const noexcept -> detail::decimal_fast128_t_components - { - return {full_significand(), biased_exponent(), isneg()}; - } - - template - friend constexpr auto to_integral_128(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - friend constexpr auto d128f_div_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, decimal_fast128_t& q, decimal_fast128_t& r) noexcept -> void; - - // Equality template between any integer type and decimal128_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal128_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - friend constexpr auto not_finite(const decimal_fast128_t& val) noexcept -> bool; - - template - friend constexpr auto to_dpd_d128(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, int128::uint128_t); - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - constexpr decimal_fast128_t() noexcept = default; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal_fast128_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal_fast128_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal_fast128_t(bool value) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - constexpr decimal_fast128_t(Integer val) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t(Float val) noexcept; - - friend constexpr auto direct_init_d128(significand_type significand, exponent_type exponent, bool sign) noexcept -> decimal_fast128_t; - - // Classification functions - friend constexpr auto signbit(const decimal_fast128_t& val) noexcept -> bool; - friend constexpr auto isinf(const decimal_fast128_t& val) noexcept -> bool; - friend constexpr auto isnan(const decimal_fast128_t& val) noexcept -> bool; - friend constexpr auto issignaling(const decimal_fast128_t& val) noexcept -> bool; - friend constexpr auto isnormal(const decimal_fast128_t& val) noexcept -> bool; - friend constexpr auto isfinite(const decimal_fast128_t& val) noexcept -> bool; - - // Comparison operators - friend constexpr auto operator==(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - friend constexpr auto operator!=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - friend constexpr auto operator<(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - friend constexpr auto operator<=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - friend constexpr auto operator>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - friend constexpr auto operator>=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - - // Mixed comparison operators - template - friend constexpr auto operator==(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - friend constexpr auto operator<=>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - #endif - - // Unary arithmetic operators - friend constexpr auto operator+(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - friend constexpr auto operator-(decimal_fast128_t rhs) noexcept -> decimal_fast128_t; - - // Binary arithmetic operators - friend constexpr auto operator+(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - friend constexpr auto operator-(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - friend constexpr auto operator*(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - friend constexpr auto operator/(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - friend constexpr auto operator%(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; - - // Mixed type binary arithmetic operators - template - friend constexpr auto operator+(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator+(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator-(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator-(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator*(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator*(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator/(const decimal_fast128_t& lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - template - friend constexpr auto operator/(Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); - - // Compound Arithmetic Operators - constexpr auto operator+=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; - - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); - - constexpr auto operator-=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); - - constexpr auto operator*=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); - - constexpr auto operator/=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); - - // Conversions - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator int128::int128_t() const noexcept; - explicit constexpr operator int128::uint128_t() const noexcept; - #endif - - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - template , bool> = true> - explicit constexpr operator Decimal() const noexcept; - - // functions that are better as friends - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto copysignd128f(decimal_fast128_t mag, decimal_fast128_t sgn) noexcept -> decimal_fast128_t; - friend constexpr auto scalblnd128f(decimal_fast128_t num, long exp) noexcept -> decimal_fast128_t; - friend constexpr auto scalbnd128f(decimal_fast128_t num, int exp) noexcept -> decimal_fast128_t; - friend constexpr auto fmad128f(decimal_fast128_t x, decimal_fast128_t y, decimal128_t z) noexcept -> decimal128_t; - - // Decimal functions - // 3.6.4 Same Quantum - friend constexpr auto samequantumd128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; - - // 3.6.5 Quantum exponent - friend constexpr auto quantexpd128f(const decimal_fast128_t& x) noexcept -> int; - - // 3.6.6 Quantize - friend constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; -}; - -BOOST_DECIMAL_EXPORT using decimal128_fast [[deprecated("Use re-named type decimal_fast128_t instead of decimal128_fast")]] = decimal_fast128_t; - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal_fast128_t::decimal_fast128_t(T1 coeff, T2 exp, bool sign) noexcept -{ - using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; - - minimum_coefficient_size min_coeff {coeff}; - - sign_ = sign; - - // Normalize the significand in the constructor, so we don't have - // to calculate the number of digits for operations - detail::normalize(min_coeff, exp, sign); - - significand_ = static_cast(min_coeff); - - const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias_v}; - - if (biased_exp > detail::max_biased_exp_v) - { - significand_ = detail::d128_fast_inf; - } - else if (biased_exp >= 0) - { - exponent_ = static_cast(biased_exp); - } - else - { - // Flush denorms to zero - significand_ = static_cast(0); - exponent_ = static_cast(detail::bias_v); - sign_ = false; - } -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal_fast128_t::decimal_fast128_t(const T1 coeff, const T2 exp) noexcept : decimal_fast128_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -constexpr decimal_fast128_t::decimal_fast128_t(const bool value) noexcept : decimal_fast128_t(static_cast(value), 0, false) {} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal_fast128_t::decimal_fast128_t(const Integer val) noexcept : decimal_fast128_t{val, 0} {} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::decimal_fast128_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - significand_ = detail::d128_fast_qnan; - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - significand_ = detail::d128_fast_inf; - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - *this = decimal_fast128_t {components.mantissa, components.exponent, components.sign}; - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -constexpr auto direct_init_d128(const decimal_fast128_t::significand_type significand, - const decimal_fast128_t::exponent_type exponent, - const bool sign) noexcept -> decimal_fast128_t -{ - decimal_fast128_t val {}; - val.significand_ = significand; - val.exponent_ = exponent; - val.sign_ = sign; - - return val; -} - -constexpr auto signbit(const decimal_fast128_t& val) noexcept -> bool -{ - return val.sign_; -} - -constexpr auto isinf(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_.high == detail::d128_fast_inf_high_bits; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnan(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_.high >= detail::d128_fast_qnan_high_bits; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto issignaling(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_.high == detail::d128_fast_snan_high_bits; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnormal(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val.exponent_ <= static_cast(detail::precision_v - 1)) - { - return false; - } - - return (val.significand_ != 0U) && isfinite(val); - #else - return val.significand_ != 0U; - #endif -} - -constexpr auto isfinite(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_.high < detail::d128_fast_inf_high_bits; - #else - static_cast(val); - return true; - #endif -} - -BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast128_t& val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_.high >= detail::d128_fast_inf_high_bits; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto operator==(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - return fast_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -constexpr auto operator!=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - return fast_inequality_impl(lhs, rhs); -} - -template -constexpr auto operator!=(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -constexpr auto operator<(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - return fast_less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !less_impl(rhs, lhs) && lhs != rhs; -} - -constexpr auto operator<=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -constexpr auto operator>=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const decimal_fast128_t& lhs, const Integer rhs) noexcept -BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const Integer lhs, const decimal_fast128_t& rhs) noexcept -BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif - -constexpr auto operator+(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - return rhs; -} - -constexpr auto operator-(decimal_fast128_t rhs) noexcept -> decimal_fast128_t -{ - rhs.sign_ = !rhs.sign_; - return rhs; -} - -constexpr auto operator+(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d128_add_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs.significand_, rhs.biased_exponent(), rhs.sign_, - (abs(lhs) > abs(rhs))); -}; - -template -constexpr auto operator+(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - using exp_type = decimal_fast128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_add_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator+(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - return rhs + lhs; -} - -constexpr auto operator-(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d128_sub_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs.significand_, rhs.biased_exponent(), rhs.sign_, - abs(lhs) > abs(rhs)); -} - -template -constexpr auto operator-(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - using exp_type = decimal_fast128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - const bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d128_sub_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator-(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - using exp_type = decimal_fast128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - const bool abs_lhs_bigger {sig_lhs > abs(rhs)}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - - return detail::d128_sub_impl( - sig_lhs, exp_lhs, (lhs < 0), - rhs.significand_, rhs.biased_exponent(), rhs.sign_, - abs_lhs_bigger); -} - -constexpr auto operator*(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d128_mul_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs.significand_, rhs.biased_exponent(), rhs.sign_); -} - -template -constexpr auto operator*(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - using exp_type = decimal_fast128_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type rhs_exp {0}; - detail::normalize(rhs_sig, rhs_exp); - - return detail::d128_fast_mul_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs_sig, rhs_exp, (rhs < 0)); -} - -template -constexpr auto operator*(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - return rhs * lhs; -} - -constexpr auto d128f_div_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, decimal_fast128_t& q, decimal_fast128_t& r) noexcept -> void -{ - const bool sign {lhs.isneg() != rhs.isneg()}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast128_t zero {0, 0}; - constexpr decimal_fast128_t nan {boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false)}; - constexpr decimal_fast128_t inf {boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_inf, 0, false)}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - // NAN has to come first - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - #else - static_cast(r); - #endif - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - constexpr auto ten_pow_precision {detail::pow10(int128::uint128_t(detail::precision_v))}; - const auto big_sig_lhs {detail::umul256(lhs.significand_, ten_pow_precision)}; - - const auto res_sig {big_sig_lhs / rhs.significand_}; - const auto res_exp {lhs.biased_exponent() - rhs.biased_exponent() - detail::precision_v}; - - q = decimal_fast128_t(static_cast(res_sig), res_exp, sign); -} - -constexpr auto d128f_mod_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, const decimal_fast128_t& q, decimal_fast128_t& r) -> void -{ - constexpr decimal_fast128_t zero {0, 0}; - - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal_fast128_t(q_trunc) * rhs); -}; - -constexpr auto operator/(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - decimal_fast128_t q {}; - decimal_fast128_t r {}; - d128f_div_impl(lhs, rhs, q, r); - - return q; -}; - -template -constexpr auto operator/(const decimal_fast128_t& lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast128_t zero {0, 0}; - constexpr decimal_fast128_t nan {direct_init_d128(detail::d128_fast_qnan, 0, false)}; - constexpr decimal_fast128_t inf {direct_init_d128(detail::d128_fast_inf, 0, false)}; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - const detail::decimal_fast128_t_components lhs_components {lhs.significand_, lhs.biased_exponent(), lhs.isneg()}; - - const auto rhs_sig {detail::make_positive_unsigned(rhs)}; - const detail::decimal_fast128_t_components rhs_components {rhs_sig, 0, rhs < 0}; - detail::decimal_fast128_t_components q_components {}; - - detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); - - return {q_components.sig, q_components.exp, q_components.sign}; -} - -template -constexpr auto operator/(const Integer lhs, const decimal_fast128_t& rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast128_t zero {0, 0}; - constexpr decimal_fast128_t nan {boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false)}; - constexpr decimal_fast128_t inf {boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_inf, 0, false)}; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - const auto rhs_fp {fpclassify(rhs)}; - - if (rhs_fp == FP_NAN) - { - return nan; - } - - switch (rhs_fp) - { - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - const detail::decimal_fast128_t_components lhs_components {detail::make_positive_unsigned(lhs), 0, lhs < 0}; - const detail::decimal_fast128_t_components rhs_components {rhs.significand_, rhs.biased_exponent(), rhs.isneg()}; - detail::decimal_fast128_t_components q_components {}; - - detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); - - return {q_components.sig, q_components.exp, q_components.sign}; -} - -constexpr auto operator%(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - decimal_fast128_t q {}; - decimal_fast128_t r {}; - d128f_div_impl(lhs, rhs, q, r); - d128f_mod_impl(lhs, rhs, q, r); - - return r; -}; - -constexpr auto decimal_fast128_t::operator+=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal_fast128_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) -{ - *this = *this + rhs; - return *this; -} - -constexpr auto decimal_fast128_t::operator-=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal_fast128_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) -{ - *this = *this - rhs; - return *this; -} - -constexpr auto decimal_fast128_t::operator*=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal_fast128_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) -{ - *this = *this * rhs; - return *this; -} - -constexpr auto decimal_fast128_t::operator/=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal_fast128_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr decimal_fast128_t::operator bool() const noexcept -{ - constexpr decimal_fast128_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal_fast128_t::operator int() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator unsigned() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator unsigned long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator long long() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator unsigned long long() const noexcept -{ - return to_integral_128(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal_fast128_t::operator boost::int128::int128_t() const noexcept -{ - return to_integral_128(*this); -} - -constexpr decimal_fast128_t::operator boost::int128::uint128_t() const noexcept -{ - return to_integral_128(*this); -} - -#endif // BOOST_DECIMAL_HAS_INT128 - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator long double() const noexcept -{ - return to_float(*this); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal_fast128_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal_fast128_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal_fast128_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal_fast128_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -template , bool>> -constexpr decimal_fast128_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -constexpr auto copysignd128f(decimal_fast128_t mag, const decimal_fast128_t sgn) noexcept -> decimal_fast128_t -{ - mag.sign_ = sgn.sign_; - return mag; -} - -constexpr auto scalblnd128f(decimal_fast128_t num, const long exp) noexcept -> decimal_fast128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal_fast128_t zero {0, 0}; - - if (num == zero || exp == 0 || not_finite(num)) - { - return num; - } - #endif - - num = decimal_fast128_t(num.significand_, num.biased_exponent() + exp, num.sign_); - - return num; -} - -constexpr auto scalbnd128f(const decimal_fast128_t num, const int exp) noexcept -> decimal_fast128_t -{ - return scalblnd128f(num, static_cast(exp)); -} - -// 3.6.4 -// Effects: determines if the quantum exponents of x and y are the same. -// If both x and y are NaN, or infinity, they have the same quantum exponents; -// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -// The samequantum functions raise no exception. -constexpr auto samequantumd128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) - { - return true; - } - if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) - { - return false; - } - #endif - - return lhs.unbiased_exponent() == rhs.unbiased_exponent(); -} - -// 3.6.5 -// Effects: if x is finite, returns its quantum exponent. -// Otherwise, a domain error occurs and INT_MIN is returned. -constexpr auto quantexpd128f(const decimal_fast128_t& x) noexcept -> int -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(x)) - { - return INT_MIN; - } - #endif - - return static_cast(x.unbiased_exponent()); -} - -// 3.6.6 -// Returns: a number that is equal in value (except for any rounding) and sign to x, -// and which has an exponent set to be equal to the exponent of y. -// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; -// if the result does not have the same value as x, the "inexact" floating-point exception is raised. -// If the exponent is being decreased and the significand of the result has more digits than the type would allow, -// the "invalid" floating-point exception is raised and the result is NaN. -// If one or both operands are NaN the result is NaN. -// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. -// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. -// The quantize functions do not signal underflow. -constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Return the correct type of nan - if (isnan(lhs)) - { - return lhs; - } - else if (isnan(rhs)) - { - return rhs; - } - - // If one is infinity then return a signaling NAN - if (isinf(lhs) != isinf(rhs)) - { - return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false); - } - else if (isinf(lhs) && isinf(rhs)) - { - return lhs; - } - #endif - - return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; -} - -} // namespace decimal -} // namespace boost - -namespace std { - -template<> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ - -#ifdef _MSC_VER - public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_present; - static constexpr bool has_denorm_loss = true; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 34; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -6143; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 6144; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal_fast128_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal_fast128_t { return {boost::int128::uint128_t{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal_fast128_t { return {boost::int128::uint128_t{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal_fast128_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal_fast128_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_inf, 0, false); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_snan, 0, false); } - static constexpr auto denorm_min () -> boost::decimal::decimal_fast128_t { return min(); } -}; - -} // namspace std - -#endif //BOOST_DECIMAL_decimal_fast128_t_HPP diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index fca55e8e9..5048f455a 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -1,10 +1,2196 @@ -// Copyright 2025 Matt Borland +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL128_T_HPP -#define BOOST_DECIMAL_DECIMAL128_T_HPP +#ifndef BOOST_DECIMAL_decimal128_t_HPP +#define BOOST_DECIMAL_decimal128_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL128_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) +#include +#include +#include +#endif + +#endif //BOOST_DECIMAL_BUILD_MODULE + +namespace boost { +namespace decimal { + +namespace detail { + +// See IEEE 754 section 3.5.2 +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_inf_mask {UINT64_C(0x7800000000000000), UINT64_C(0)}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_nan_mask {UINT64_C(0x7C00000000000000), UINT64_C(0)}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_snan_mask {UINT64_C(0x7E00000000000000), UINT64_C(0)}; + +// Comb. Exponent Significand +// s eeeeeeeeeeeeee (0TTT) 110-bits +// s 11 eeeeeeeeeeeeee (100T) 110-bits + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_sign_mask {UINT64_C(0x8000000000000000)}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_combination_field_mask = UINT64_C(0x6000000000000000); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_not_11_exp_mask = UINT64_C(0x7FFE000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_not_11_exp_high_word_shift {49U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_11_exp_mask {UINT64_C(0x1FFF800000000000)}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_11_exp_high_word_shift {47U}; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_not_11_significand_mask {UINT64_C(0x1FFFFFFFFFFFF), UINT64_MAX}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_11_significand_mask {UINT64_C(0x7FFFFFFFFFFF), UINT64_MAX}; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_biggest_no_combination_significand {d128_not_11_significand_mask}; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d128_max_biased_exponent {UINT64_C(12287)}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int128::uint128_t d128_max_significand_value {UINT64_C(0x1ED09BEAD87C0), UINT64_C(0x378D8E63FFFFFFFF)}; + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +} //namespace detail + +BOOST_DECIMAL_EXPORT class decimal128_t final +{ +public: + using significand_type = boost::int128::uint128_t; + using exponent_type = std::uint64_t; + using biased_exponent_type = std::int32_t; + +private: + int128::uint128_t bits_ {}; + + #ifdef BOOST_DECIMAL_HAS_INT128 + + friend constexpr auto from_bits(detail::builtin_uint128_t rhs) noexcept -> decimal128_t; + friend constexpr auto to_bits(decimal128_t rhs) noexcept -> detail::builtin_uint128_t; + + #endif + + friend constexpr auto from_bits(int128::uint128_t rhs) noexcept -> decimal128_t; + + constexpr auto unbiased_exponent() const noexcept -> std::uint64_t; + constexpr auto biased_exponent() const noexcept -> std::int32_t; + constexpr auto full_significand() const noexcept -> int128::uint128_t; + constexpr auto isneg() const noexcept -> bool; + constexpr auto to_components() const noexcept -> detail::decimal128_t_components; + + // Allows direct editing of the exp + template , bool> = true> + constexpr auto edit_exponent(T exp) noexcept -> void; + constexpr auto edit_sign(bool sign) noexcept -> void; + + // Attempts conversion to integral type: + // If this is nan sets errno to EINVAL and returns 0 + // If this is not representable sets errno to ERANGE and returns 0 + template + friend constexpr auto to_integral_128(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + template + friend BOOST_DECIMAL_FORCE_INLINE constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; + + // Equality template between any integer type and decimal128_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal128_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + friend constexpr auto d128_div_impl(const decimal128_t& lhs, const decimal128_t& rhs, decimal128_t& q, decimal128_t& r) noexcept -> void; + + friend constexpr auto d128_mod_impl(const decimal128_t& lhs, const decimal128_t& rhs, const decimal128_t& q, decimal128_t& r) noexcept -> void; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + friend constexpr auto not_finite(decimal128_t rhs) noexcept -> bool; + + friend constexpr auto to_bid_d128(decimal128_t val) noexcept -> int128::uint128_t; + + friend constexpr auto from_bid_d128(int128::uint128_t bits) noexcept -> decimal128_t; + + #ifdef BOOST_DECIMAL_HAS_INT128 + friend constexpr auto from_bid_d128(detail::builtin_uint128_t bits) noexcept -> decimal128_t; + #endif + + template + friend constexpr auto to_dpd_d128(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, int128::uint128_t); + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal128_t(const char* str, std::size_t len); + #endif + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_ieee_type_v, T, typename T::significand_type); + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_ieee_type_v, TargetDecimalType); + + friend constexpr auto nan_conversion(const decimal128_t value) noexcept -> decimal128_t + { + constexpr auto convert_nan_mask {detail::d128_snan_mask ^ detail::d128_nan_mask}; + + decimal128_t return_value; + return_value.bits_ = value.bits_ ^ convert_nan_mask; + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + +public: + // 3.2.4.1 construct/copy/destroy + constexpr decimal128_t() noexcept = default; + constexpr decimal128_t& operator=(const decimal128_t& rhs) noexcept = default; + constexpr decimal128_t& operator=(decimal128_t&& rhs) noexcept = default; + constexpr decimal128_t(const decimal128_t& rhs) noexcept = default; + constexpr decimal128_t(decimal128_t&& rhs) noexcept = default; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit constexpr decimal128_t(long double val) noexcept = delete; + #endif + + template + BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal128_t&); + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + explicit constexpr decimal128_t(Decimal val) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal128_t(Integer val) noexcept; + + template + constexpr auto operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); + + // 3.2.5 initialization from coefficient and exponent: + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal128_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal128_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal128_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal128_t(bool value) noexcept; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + explicit constexpr decimal128_t(const char* str); + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal128_t(const std::string& str); + #else + explicit constexpr decimal128_t(std::string_view str); + #endif + + #endif + + // 3.2.4.4 Conversion to integral type + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + explicit constexpr operator boost::int128::int128_t() const noexcept; + explicit constexpr operator boost::int128::uint128_t() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator detail::builtin_int128_t() const noexcept; + explicit constexpr operator detail::builtin_uint128_t() const noexcept; + #endif + + // 3.2.6 Conversion to floating-point type + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> + constexpr operator Decimal() const noexcept; + + template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> + explicit constexpr operator Decimal() const noexcept; + + // cmath functions that are easier as friends + friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128_t rhs) noexcept -> bool; + + // 3.2.7 unary arithmetic operators: + friend constexpr auto operator+(decimal128_t rhs) noexcept -> decimal128_t; + friend constexpr auto operator-(decimal128_t rhs) noexcept -> decimal128_t; + + // 3.2.8 Binary arithmetic operators + friend constexpr auto operator+(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + template + friend constexpr auto operator+(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + template + friend constexpr auto operator+(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + friend constexpr auto operator-(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + template + friend constexpr auto operator-(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + template + friend constexpr auto operator-(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + friend constexpr auto operator*(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + template + friend constexpr auto operator*(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + template + friend constexpr auto operator*(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + friend constexpr auto operator/(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + template + friend constexpr auto operator/(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + template + friend constexpr auto operator/(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t); + + friend constexpr auto operator%(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + // 3.2.4.5 Increment and Decrement + constexpr auto operator++() noexcept -> decimal128_t&; + constexpr auto operator++(int) noexcept -> decimal128_t; // NOLINT : C++14 so constexpr implies const + constexpr auto operator--() noexcept -> decimal128_t&; + constexpr auto operator--(int) noexcept -> decimal128_t; // NOLINT : C++14 so constexpr implies const + + // 3.2.4.6 Compound Assignment + constexpr auto operator+=(decimal128_t rhs) noexcept -> decimal128_t&; + + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); + + template + constexpr auto operator+=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); + + constexpr auto operator-=(decimal128_t rhs) noexcept -> decimal128_t&; + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); + + template + constexpr auto operator-=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); + + constexpr auto operator*=(decimal128_t rhs) noexcept -> decimal128_t&; + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); + + template + constexpr auto operator*=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); + + constexpr auto operator/=(decimal128_t rhs) noexcept -> decimal128_t&; + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&); + + template + constexpr auto operator/=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&); + + constexpr auto operator%=(decimal128_t rhs) noexcept -> decimal128_t&; + + // 3.2.9 Comparison operators: + // Equality + friend constexpr auto operator==(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator==(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Inequality + friend constexpr auto operator!=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator!=(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less + friend constexpr auto operator<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator<(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less equal + friend constexpr auto operator<=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator<=(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater + friend constexpr auto operator>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator>(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater equal + friend constexpr auto operator>=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + template + friend constexpr auto operator>=(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // C++20 spaceship + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + friend constexpr auto operator<=>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(decimal128_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + #endif + + // 3.6.4 Same Quantum + friend constexpr auto samequantumd128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool; + + // 3.6.5 Quantum exponent + friend constexpr auto quantexpd128(decimal128_t x) noexcept -> int; + + // 3.6.6 Quantize + friend constexpr auto quantized128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t; + + // functions that need to be friends + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto copysignd128(decimal128_t mag, decimal128_t sgn) noexcept -> decimal128_t; + friend constexpr auto scalblnd128(decimal128_t num, long exp) noexcept -> decimal128_t; + friend constexpr auto scalbnd128(decimal128_t num, int exp) noexcept -> decimal128_t; + friend constexpr auto fmad128(decimal128_t x, decimal128_t y, decimal128_t z) noexcept -> decimal128_t; +}; + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr auto from_bits(const detail::builtin_uint128_t rhs) noexcept -> decimal128_t +{ + decimal128_t result; + result.bits_ = rhs; + + return result; +} + +constexpr auto to_bits(const decimal128_t rhs) noexcept -> detail::builtin_uint128_t +{ + return static_cast(rhs.bits_); +} + +#endif + +constexpr auto from_bits(const int128::uint128_t rhs) noexcept -> decimal128_t +{ + decimal128_t result; + result.bits_ = rhs; + + return result; +} + +constexpr auto decimal128_t::unbiased_exponent() const noexcept -> exponent_type +{ + exponent_type expval {}; + + if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) + { + expval = (bits_.high & detail::d128_11_exp_mask) >> detail::d128_11_exp_high_word_shift; + } + else + { + expval = (bits_.high & detail::d128_not_11_exp_mask) >> detail::d128_not_11_exp_high_word_shift; + } + + return expval; +} + +constexpr auto decimal128_t::biased_exponent() const noexcept -> biased_exponent_type +{ + return static_cast(unbiased_exponent()) - detail::bias_v; +} + +constexpr auto decimal128_t::full_significand() const noexcept -> significand_type +{ + significand_type significand {}; + + if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) + { + constexpr int128::uint128_t implied_bit {UINT64_C(0x2000000000000),0}; + significand = implied_bit | (bits_ & detail::d128_11_significand_mask); + } + else + { + significand = bits_ & detail::d128_not_11_significand_mask; + } + + return significand; +} + +constexpr auto decimal128_t::isneg() const noexcept -> bool +{ + return static_cast(bits_.high & detail::d128_sign_mask); +} + +constexpr auto decimal128_t::to_components() const noexcept -> detail::decimal128_t_components +{ + significand_type significand {}; + exponent_type expval {}; + + if ((bits_.high & detail::d128_combination_field_mask) == detail::d128_combination_field_mask) + { + constexpr int128::uint128_t implied_bit {UINT64_C(0x2000000000000),0}; + significand = implied_bit | (bits_ & detail::d128_11_significand_mask); + expval = (bits_.high & detail::d128_11_exp_mask) >> detail::d128_11_exp_high_word_shift; + } + else + { + significand = bits_ & detail::d128_not_11_significand_mask; + expval = (bits_.high & detail::d128_not_11_exp_mask) >> detail::d128_not_11_exp_high_word_shift; + } + + const auto sign {static_cast(bits_.high & detail::d128_sign_mask)}; + + return detail::decimal128_t_components {significand, static_cast(expval) - detail::bias_v, sign}; +} + + +template , bool>> +constexpr auto decimal128_t::edit_exponent(const T expval) noexcept -> void +{ + *this = decimal128_t(this->full_significand(), expval, this->isneg()); +} + +constexpr auto decimal128_t::edit_sign(const bool sign) noexcept -> void +{ + if (sign) + { + bits_.high |= detail::d128_sign_mask; + } + else + { + constexpr auto not_sign_mask {~detail::d128_sign_mask}; + bits_.high &= not_sign_mask; + } +} + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wduplicated-branches" +# pragma GCC diagnostic ignored "-Wconversion" +#endif + + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) +#endif + +// e.g. for sign bits_.high |= detail::d128_sign_mask +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal128_t::decimal128_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept +{ + const auto is_negative {static_cast(resultant_sign)}; + bits_.high = is_negative ? detail::d128_sign_mask : UINT64_C(0); + + // If the coeff is not in range make it so + // The coefficient needs at least 110 bits so there's a good chance we don't need to + // We use sizeof instead of std::numeric_limits since __int128 on GCC prior to 14 without GNU mode does not overload + // numeric_limits + int coeff_digits {-1}; + auto biased_exp {static_cast(exp + detail::bias_v)}; + BOOST_DECIMAL_IF_CONSTEXPR (sizeof(T1) >= sizeof(significand_type)) + { + if (coeff > detail::d128_max_significand_value || biased_exp < -(detail::precision_v - 1)) + { + coeff_digits = detail::coefficient_rounding(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff)); + } + } + + constexpr int128::uint128_t zero {0, 0}; + auto reduced_coeff {static_cast(coeff)}; + + if (reduced_coeff == zero) + { + return; + } + + // The decimal128_t case is more straightforward than the others + // The precision of the type is 34, and 34x 9s fits into 113 bits, + // therefore we never need to use the combination field for additional space + + bits_ |= (reduced_coeff & detail::d128_not_11_significand_mask); + + // If the exponent fits we do not need to use the combination field + if (BOOST_DECIMAL_LIKELY(biased_exp >= 0 && biased_exp <= static_cast(detail::d128_max_biased_exponent))) + { + bits_.high |= (static_cast(biased_exp) << detail::d128_not_11_exp_high_word_shift) & detail::d128_not_11_exp_mask; + } + else + { + // If we can fit the extra exponent in the significand, then we can construct the value + // If we can't, the value is either 0 or infinity depending on the sign of exp + + if (coeff_digits == -1) + { + coeff_digits = detail::num_digits(reduced_coeff); + } + + const auto exp_delta {biased_exp - static_cast(detail::d128_max_biased_exponent)}; + const auto digit_delta {coeff_digits - exp_delta}; + if (biased_exp < 0 && coeff_digits == 1) + { + // This needs to be flushed to 0 or rounded to subnormal min + rounding_mode current_round_mode {_boost_decimal_global_rounding_mode}; + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(coeff)) + { + current_round_mode = _boost_decimal_global_runtime_rounding_mode; + } + + #endif + + bool round {false}; + if (biased_exp == -1) + { + switch (current_round_mode) + { + case rounding_mode::fe_dec_to_nearest_from_zero: + BOOST_DECIMAL_FALLTHROUGH + case rounding_mode::fe_dec_to_nearest: + if (reduced_coeff >= 5U) + { + round = true; + } + break; + case rounding_mode::fe_dec_upward: + if (!is_negative && reduced_coeff != 0U) + { + round = true; + } + break; + default: + round = false; + break; + } + } + + if (round) + { + // Subnormal min is just 1 + bits_ = UINT64_C(1); + } + else + { + bits_ = UINT64_C(0); + } + + bits_.high |= is_negative ? detail::d128_sign_mask : UINT64_C(0); + } + else if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision_v) + { + exp -= digit_delta; + reduced_coeff *= detail::pow10(static_cast(digit_delta)); + *this = decimal128_t(reduced_coeff, exp, is_negative); + } + else if (coeff_digits + biased_exp <= detail::precision_v) + { + // Handle the case of sub-normals that don't need further rounding + bits_ = {0u, 0u}; + const auto zeros {detail::remove_trailing_zeros(reduced_coeff)}; + biased_exp += static_cast(zeros.number_of_removed_zeros); + reduced_coeff = zeros.trimmed_number; + if (biased_exp > 0) + { + reduced_coeff *= detail::pow10(static_cast(biased_exp)); + } + bits_ = reduced_coeff; + bits_.high |= is_negative ? detail::d128_sign_mask : UINT64_C(0); // Reset the sign bit + } + else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision_v) + { + const auto offset {detail::precision_v - coeff_digits}; + exp -= offset; + reduced_coeff *= detail::pow10(static_cast(offset)); + *this = decimal128_t(reduced_coeff, exp, is_negative); + } + else + { + bits_ = exp < 0 ? zero : detail::d128_inf_mask; + bits_.high |= is_negative ? detail::d128_sign_mask : UINT64_C(0); + } + } +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal128_t::decimal128_t(const T1 coeff, const T2 exp) noexcept : decimal128_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +constexpr decimal128_t::decimal128_t(const bool value) noexcept : decimal128_t(static_cast(value), 0, false) {} + + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic pop +#endif + +namespace detail { + +template +class numeric_limits_impl128 +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = true; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 34; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -6143; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 6144; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal128_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal128_t { return {d128_max_significand_value, max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal128_t { return {d128_max_significand_value, max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal128_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal128_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_nan_mask); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal128_t { return boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask); } + static constexpr auto denorm_min () -> boost::decimal::decimal128_t { return {1, boost::decimal::detail::etiny_v}; } +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl128::is_specialized; +template constexpr bool numeric_limits_impl128::is_signed; +template constexpr bool numeric_limits_impl128::is_integer; +template constexpr bool numeric_limits_impl128::is_exact; +template constexpr bool numeric_limits_impl128::has_infinity; +template constexpr bool numeric_limits_impl128::has_quiet_NaN; +template constexpr bool numeric_limits_impl128::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl128::has_denorm; +template constexpr bool numeric_limits_impl128::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl128::round_style; +template constexpr bool numeric_limits_impl128::is_iec559; +template constexpr bool numeric_limits_impl128::is_bounded; +template constexpr bool numeric_limits_impl128::is_modulo; +template constexpr int numeric_limits_impl128::digits; +template constexpr int numeric_limits_impl128::digits10; +template constexpr int numeric_limits_impl128::max_digits10; +template constexpr int numeric_limits_impl128::radix; +template constexpr int numeric_limits_impl128::min_exponent; +template constexpr int numeric_limits_impl128::min_exponent10; +template constexpr int numeric_limits_impl128::max_exponent; +template constexpr int numeric_limits_impl128::max_exponent10; +template constexpr bool numeric_limits_impl128::traps; +template constexpr bool numeric_limits_impl128::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} //namespace decimal +} //namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl128 {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} //namespace std + +namespace boost { +namespace decimal { + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::decimal128_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + *this = from_bits(detail::d128_nan_mask); + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + *this = from_bits(detail::d128_inf_mask); + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "Mant: " << components.mantissa + << "\nExp: " << components.exponent + << "\nSign: " << components.sign << std::endl; + #endif + + if (components.exponent > detail::emax_v) + { + *this = from_bits(detail::d128_inf_mask); + } + else + { + *this = decimal128_t {components.mantissa, components.exponent, components.sign}; + } + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +template +BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal128_t::operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal128_t&) +{ + *this = decimal128_t{val}; + return *this; +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal128_t::decimal128_t(const Integer val) noexcept : decimal128_t{val, 0} {} + +template +constexpr auto decimal128_t::operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) +{ + using ConversionType = std::conditional_t::value, std::int32_t, Integer>; + *this = decimal128_t{static_cast(val), 0}; + return *this; +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal128_t::decimal128_t(const Decimal val) noexcept +{ + *this = to_decimal(val); +} + +constexpr decimal128_t::operator bool() const noexcept +{ + constexpr decimal128_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal128_t::operator int() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator unsigned() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator unsigned long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator long long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator unsigned long long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator boost::int128::int128_t() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator boost::int128::uint128_t() const noexcept +{ + return to_integral_128(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal128_t::operator detail::builtin_int128_t() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal128_t::operator detail::builtin_uint128_t() const noexcept +{ + return to_integral_128(*this); +} + +#endif //BOOST_DECIMAL_HAS_INT128 + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::operator long double() const noexcept +{ + return to_float(*this); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal128_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal128_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal128_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal128_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +template && (detail::decimal_val_v > detail::decimal_val_v), bool>> +constexpr decimal128_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> +constexpr decimal128_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + return rhs.bits_.high & detail::d128_sign_mask; +} + +constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_.high & detail::d128_nan_mask.high) == detail::d128_nan_mask.high; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_.high & detail::d128_nan_mask.high) == detail::d128_inf_mask.high; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_.high & detail::d128_snan_mask.high) == detail::d128_snan_mask.high; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check for de-normals + const auto sig {rhs.full_significand()}; + const auto exp {rhs.unbiased_exponent()}; + + if (exp <= detail::precision_v - 1) + { + return false; + } + + return (sig != 0U) && isfinite(rhs); + #else + return rhs.full_significand() != 0U; + #endif +} + +constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_.high & detail::d128_inf_mask.high) != detail::d128_inf_mask.high; + #else + static_cast(rhs); + return true; + #endif +} + +BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal128_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_.high & detail::d128_inf_mask.high) == detail::d128_inf_mask.high; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto operator+(const decimal128_t rhs) noexcept -> decimal128_t +{ + return rhs; +} + +constexpr auto operator-(decimal128_t rhs) noexcept-> decimal128_t +{ + rhs.bits_.high ^= detail::d128_sign_mask; + return rhs; +} + + +constexpr auto operator==(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + return equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +constexpr auto operator!=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +constexpr auto operator<(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isnan(lhs) || isnan(rhs) || + (!lhs.isneg() && rhs.isneg())) + { + return false; + } + if (lhs.isneg() && !rhs.isneg()) + { + return true; + } + if (isfinite(lhs) && isinf(rhs)) + { + return !rhs.isneg(); + } + } + #endif + + return less_parts_impl(lhs.full_significand(), lhs.biased_exponent(), lhs.isneg(), + rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()); +} + +template +constexpr auto operator<(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !less_impl(rhs, lhs) && lhs != rhs; +} + +constexpr auto operator<=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +constexpr auto operator>=(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif + +#ifdef BOOST_DECIMAL_DEBUG_ADD_128 +static char* mini_to_chars( char (&buffer)[ 64 ], boost::decimal::detail::builtin_uint128_t v ) +{ + char* p = buffer + 64; + *--p = '\0'; + + do + { + *--p = "0123456789"[ v % 10 ]; + v /= 10; + } + while ( v != 0 ); + + return p; +} + +#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) +std::ostream& operator<<( std::ostream& os, boost::decimal::detail::builtin_uint128_t v ) +{ + char buffer[ 64 ]; + + os << mini_to_chars( buffer, v ); + return os; +} +#endif +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) // If constexpr macro only works for C++17 and above +#endif + +constexpr auto d128_div_impl(const decimal128_t& lhs, const decimal128_t& rhs, decimal128_t& q, decimal128_t& r) noexcept -> void +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal128_t zero {0, 0}; + constexpr decimal128_t nan {from_bits(detail::d128_nan_mask)}; + constexpr decimal128_t inf {from_bits(detail::d128_inf_mask)}; + + const bool sign {lhs.isneg() != rhs.isneg()}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal128_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + #else + static_cast(r); + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "sig lhs: " << sig_lhs + << "\nexp lhs: " << exp_lhs + << "\nsig rhs: " << sig_rhs + << "\nexp rhs: " << exp_rhs << std::endl; + #endif + + detail::decimal128_t_components q_components {}; + + detail::d128_generic_div_impl(lhs_components, rhs.to_components(), q_components); + + q = decimal128_t(q_components.sig, q_components.exp, q_components.sign); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +constexpr auto d128_mod_impl(const decimal128_t& lhs, const decimal128_t& rhs, const decimal128_t& q, decimal128_t& r) noexcept -> void +{ + constexpr decimal128_t zero {0, 0}; + + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator+(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return from_bits(detail::d128_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + return detail::d128_add_impl_new(lhs_components, rhs_components); +} + +template +constexpr auto operator+(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + using exp_type = decimal128_t::biased_exponent_type; + using sig_type = decimal128_t::significand_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + auto positive_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(positive_rhs, exp_rhs); + const detail::decimal128_t_components rhs_components {positive_rhs, exp_rhs, rhs < 0}; + + return detail::d128_add_impl_new(lhs_components, rhs_components); +} + +template +constexpr auto operator+(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + return rhs + lhs; +} + +// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa +constexpr auto operator-(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return from_bits(detail::d128_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + rhs_components.sign = !rhs_components.sign; + + return detail::d128_add_impl_new(lhs_components, rhs_components); +} + +template +constexpr auto operator-(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + using exp_type = decimal128_t::biased_exponent_type; + using sig_type = decimal128_t::significand_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const detail::decimal128_t_components rhs_components {sig_rhs, exp_rhs, !(rhs < 0)}; + + return detail::d128_add_impl_new(lhs_components, rhs_components); +} + +template +constexpr auto operator-(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + return -rhs + lhs; +} + +constexpr auto operator*(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return from_bits(detail::d128_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + const auto lhs_components {lhs.to_components()}; + const auto rhs_components {rhs.to_components()}; + + return detail::d128_mul_impl( + lhs_components.sig, lhs_components.exp, lhs_components.sign, + rhs_components.sig, rhs_components.exp, rhs_components.sign); +} + +template +constexpr auto operator*(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + using exp_type = decimal128_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto lhs_sig {lhs.full_significand()}; + auto lhs_exp {lhs.biased_exponent()}; + const auto lhs_zeros {detail::remove_trailing_zeros(lhs_sig)}; + lhs_sig = lhs_zeros.trimmed_number; + lhs_exp += static_cast(lhs_zeros.number_of_removed_zeros); + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + const auto rhs_zeros {detail::remove_trailing_zeros(rhs_sig)}; + rhs_sig = rhs_zeros.trimmed_number; + const auto rhs_exp = static_cast(rhs_zeros.number_of_removed_zeros); + + return detail::d128_mul_impl( + lhs_sig, lhs_exp, lhs.isneg(), + rhs_sig, rhs_exp, (rhs < 0)); + +} + +template +constexpr auto operator*(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + return rhs * lhs; +} + +constexpr auto operator/(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + decimal128_t q {}; + decimal128_t r {}; + d128_div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal128_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal128_t zero {0, 0}; + constexpr decimal128_t inf {from_bits(detail::d128_inf_mask)}; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + const detail::decimal128_t_components rhs_components {detail::make_positive_unsigned(rhs), 0, rhs < 0}; + detail::decimal128_t_components q_components {}; + + detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); + + return decimal128_t(q_components.sig, q_components.exp, q_components.sign); +} + +template +constexpr auto operator/(const Integer lhs, const decimal128_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal128_t zero {0, 0}; + constexpr decimal128_t inf {from_bits(detail::d128_inf_mask)}; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + const detail::decimal128_t_components lhs_components {detail::make_positive_unsigned(lhs), 0, lhs < 0}; + detail::decimal128_t_components q_components {}; + + detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); + + return decimal128_t(q_components.sig, q_components.exp, q_components.sign); +} + +constexpr auto operator%(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + decimal128_t q {}; + decimal128_t r {}; + d128_div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + d128_mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal128_t::operator++() noexcept -> decimal128_t& +{ + constexpr decimal128_t one{1, 0}; + *this = *this + one; + return *this; +} + +constexpr auto decimal128_t::operator++(int) noexcept -> decimal128_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal128_t::operator--() noexcept -> decimal128_t& +{ + constexpr decimal128_t one{1, 0}; + *this = *this - one; + return *this; +} + +constexpr auto decimal128_t::operator--(int) noexcept -> decimal128_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +constexpr auto decimal128_t::operator+=(const decimal128_t rhs) noexcept -> decimal128_t& +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator+=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) +{ + *this = *this + rhs; + return *this; +} + +constexpr auto decimal128_t::operator-=(const decimal128_t rhs) noexcept -> decimal128_t& +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator-=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) +{ + *this = *this - rhs; + return *this; +} + +constexpr auto decimal128_t::operator*=(const decimal128_t rhs) noexcept -> decimal128_t& +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator*=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) +{ + *this = *this * rhs; + return *this; +} + +constexpr auto decimal128_t::operator/=(const decimal128_t rhs) noexcept -> decimal128_t& +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal128_t&) +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal128_t::operator/=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal128_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto decimal128_t::operator%=(const decimal128_t rhs) noexcept -> decimal128_t& +{ + *this = *this % rhs; + return *this; +} + +// 3.6.4 +// Effects: determines if the quantum exponents of x and y are the same. +// If both x and y are NaN, or infinity, they have the same quantum exponents; +// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. +// The samequantum functions raise no exception. +constexpr auto samequantumd128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) + { + return true; + } + if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) + { + return false; + } + #endif + + return lhs.unbiased_exponent() == rhs.unbiased_exponent(); +} + +// 3.6.5 +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd128(const decimal128_t x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +// 3.6.6 +// Returns: a number that is equal in value (except for any rounding) and sign to x, +// and which has an exponent set to be equal to the exponent of y. +// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; +// if the result does not have the same value as x, the "inexact" floating-point exception is raised. +// If the exponent is being decreased and the significand of the result has more digits than the type would allow, +// the "invalid" floating-point exception is raised and the result is NaN. +// If one or both operands are NaN the result is NaN. +// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. +// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. +// The quantize functions do not signal underflow. +constexpr auto quantized128(const decimal128_t& lhs, const decimal128_t& rhs) noexcept -> decimal128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Return the correct type of nan + if (isnan(lhs)) + { + return lhs; + } + else if (isnan(rhs)) + { + return rhs; + } + + // If one is infinity then return a signaling NAN + if (isinf(lhs) != isinf(rhs)) + { + return boost::decimal::from_bits(boost::decimal::detail::d128_snan_mask); + } + else if (isinf(lhs) && isinf(rhs)) + { + return lhs; + } + #endif + + return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; +} + +constexpr auto copysignd128(decimal128_t mag, const decimal128_t sgn) noexcept -> decimal128_t +{ + mag.edit_sign(sgn.isneg()); + return mag; +} + +constexpr auto scalblnd128(decimal128_t num, const long exp) noexcept -> decimal128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal128_t zero {0, 0}; + + if (num == zero || exp == 0 || not_finite(num)) + { + return num; + } + #endif + + num.edit_exponent(num.biased_exponent() + exp); + + return num; +} + +constexpr auto scalbnd128(decimal128_t num, const int expval) noexcept -> decimal128_t +{ + return scalblnd128(num, static_cast(expval)); +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal128_t::decimal128_t(const char* str, std::size_t len) +{ + if (str == nullptr || len == 0) + { + bits_ = detail::d128_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal128_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + bits_ = detail::d128_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal128_t::decimal128_t(const char* str) : decimal128_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal128_t::decimal128_t(const std::string& str) : decimal128_t(str.c_str(), str.size()) {} +#else +constexpr decimal128_t::decimal128_t(std::string_view str) : decimal128_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif //BOOST_DECIMAL_decimal128_t_HPP diff --git a/include/boost/decimal/decimal32.hpp b/include/boost/decimal/decimal32.hpp deleted file mode 100644 index 896011f1f..000000000 --- a/include/boost/decimal/decimal32.hpp +++ /dev/null @@ -1,2169 +0,0 @@ -// Copyright 2023 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal32_t_HPP -#define BOOST_DECIMAL_decimal32_t_HPP - -#include -#include -#include -#include -#include -#include "detail/int128.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) -#include -#include -#endif - -#endif // BOOST_DECIMAL_BUILD_MODULE - -namespace boost { -namespace decimal { - -namespace detail { - -// See IEEE 754 section 3.5.2 -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_inf_mask = UINT32_C(0x78000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_nan_mask = UINT32_C(0x7C000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_snan_mask = UINT32_C(0x7E000000); - -// Comb. Exponent Significand -// s eeeeeeee ttttttttttttttttttttttt - sign + 2 steering bits concatenate to 6 bits of exponent (8 total) + 23 bits of significand like float -// s 11 eeeeeeee [100] + ttttttttttttttttttttt - sign + 2 steering bits + 8 bits of exponent + 21 bits of significand (0b100 + 21 bits) -// -// Only is the type different in steering 11 which yields significand 100 + 21 bits giving us our 24 total bits of precision - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_sign_mask = UINT32_C(0b10000000000000000000000000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_combination_field_mask = UINT32_C(0b01100000000000000000000000000000); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_comb_11_mask = UINT32_C(0b0'11000'000000'0000000000'0000000000); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_exp_mask = UINT32_C(0b01111111100000000000000000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_exp_shift = UINT32_C(23); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_11_exp_mask = UINT32_C(0b00011111111000000000000000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_11_exp_shift = UINT32_C(21); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_significand_mask = UINT32_C(0b00000000011111111111111111111111); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_11_significand_mask = UINT32_C(0b00000000000111111111111111111111); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_biggest_no_combination_significand = UINT32_C(0b11111111111111111111111); // 23 bits - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_max_biased_exponent = UINT32_C(191); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t d32_max_significand_value = UINT32_C(9'999'999); - -template -constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -} // namespace detail - -#if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wclass-memaccess" -#endif - - -// ISO/IEC DTR 24733 -// 3.2.2 class decimal32_t -BOOST_DECIMAL_EXPORT class decimal32_t final // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) -{ -public: - using significand_type = std::uint32_t; - using exponent_type = std::uint32_t; - using biased_exponent_type = std::int32_t; - -private: - - std::uint32_t bits_ {}; - - // Returns the un-biased (quantum) exponent - constexpr auto unbiased_exponent() const noexcept -> exponent_type ; - - // Returns the biased exponent - constexpr auto biased_exponent() const noexcept -> biased_exponent_type; - - // Returns the significand complete with the bits implied from the combination field - constexpr auto full_significand() const noexcept -> significand_type ; - constexpr auto isneg() const noexcept -> bool; - - // Returns a complete struct so we don't have to decode the number multiple times if we need everything - constexpr auto to_components() const noexcept -> detail::decimal32_t_components; - - // Attempts conversion to integral type: - // If this is nan sets errno to EINVAL and returns 0 - // If this is not representable sets errno to ERANGE and returns 0 - template - friend constexpr auto to_integral(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - friend constexpr auto div_impl(decimal32_t lhs, decimal32_t rhs, decimal32_t& q, decimal32_t& r) noexcept -> void; - friend constexpr auto mod_impl(decimal32_t lhs, decimal32_t rhs, const decimal32_t& q, decimal32_t& r) noexcept -> void; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - // Debug bit pattern - friend constexpr auto from_bits(std::uint32_t bits) noexcept -> decimal32_t; - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_bits(decimal32_t rhs) noexcept -> std::uint32_t; - friend inline auto debug_pattern(decimal32_t rhs) noexcept -> void; - - // Equality template between any integer type and decimal32_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal32_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - template - friend constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; - - template - friend constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; - - friend constexpr auto to_bid_d32(decimal32_t val) noexcept -> std::uint32_t; - - friend constexpr auto from_bid_d32(std::uint32_t bits) noexcept -> decimal32_t; - - template - friend constexpr auto to_dpd_d32(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint32_t); - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - // 3.2.2.1 construct/copy/destroy: - constexpr decimal32_t() noexcept = default; - - // 3.2.2.2 Conversion from a floating-point type - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - #ifndef BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS - explicit - #endif - BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t(Float val) noexcept; - - template - BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal32_t&); - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - explicit constexpr decimal32_t(Decimal val) noexcept; - - // 3.2.2.3 Conversion from integral type - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - constexpr decimal32_t(Integer val) noexcept; - - template - constexpr auto operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); - - // 3.2.2.4 Conversion to integral type - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator detail::builtin_int128_t() const noexcept; - explicit constexpr operator detail::builtin_uint128_t() const noexcept; - #endif - - // We allow implict promotions to and decimal type with greater or equal precision (e.g. decimal_fast32_t) - template , bool> = true> - constexpr operator Decimal() const noexcept; - - // 3.2.5 initialization from coefficient and exponent: - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal32_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal32_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal32_t(bool value) noexcept; - - constexpr decimal32_t(const decimal32_t& val) noexcept = default; - constexpr decimal32_t(decimal32_t&& val) noexcept = default; - constexpr auto operator=(const decimal32_t& val) noexcept -> decimal32_t& = default; - constexpr auto operator=(decimal32_t&& val) noexcept -> decimal32_t& = default; - - // 3.2.6 Conversion to floating-point type - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - // cmath functions that are easier as friends - friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; - - // 3.2.7 unary arithmetic operators: - friend constexpr auto operator+(decimal32_t rhs) noexcept -> decimal32_t; - friend constexpr auto operator-(decimal32_t rhs) noexcept -> decimal32_t; - - // 3.2.8 binary arithmetic operators: - friend constexpr auto operator+(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator+(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator+(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator-(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator-(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator-(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator*(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator*(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator*(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator/(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator/(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator/(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator%(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - // 3.2.2.5 Increment and Decrement - constexpr auto operator++() noexcept -> decimal32_t&; - constexpr auto operator++(int) noexcept -> decimal32_t; // NOLINT : C++14 so constexpr implies const - constexpr auto operator--() noexcept -> decimal32_t&; - constexpr auto operator--(int) noexcept -> decimal32_t; // NOLINT : C++14 so constexpr implies const - - // 3.2.2.6 Compound assignment - constexpr auto operator+=(decimal32_t rhs) noexcept -> decimal32_t&; - - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); - - template - constexpr auto operator+=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); - - constexpr auto operator-=(decimal32_t rhs) noexcept -> decimal32_t&; - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); - - template - constexpr auto operator-=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); - - constexpr auto operator*=(decimal32_t rhs) noexcept -> decimal32_t&; - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); - - template - constexpr auto operator*=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); - - constexpr auto operator/=(decimal32_t rhs) noexcept -> decimal32_t&; - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); - - template - constexpr auto operator/=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); - - constexpr auto operator%=(decimal32_t rhs) noexcept -> decimal32_t&; - - // 3.2.9 comparison operators: - // Equality - friend constexpr auto operator==(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator==(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Inequality - friend constexpr auto operator!=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator!=(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less - friend constexpr auto operator<(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator<(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less equal - friend constexpr auto operator<=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator<=(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater - friend constexpr auto operator>(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator>(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater equal - friend constexpr auto operator>=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - template - friend constexpr auto operator>=(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - friend constexpr auto operator<=>(decimal32_t lhs, decimal32_t rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - #endif - - // Bitwise operators - friend constexpr auto operator&(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator&(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator&(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator|(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator|(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator|(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator^(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator^(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator^(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator<<(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator<<(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator<<(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator>>(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - template - friend constexpr auto operator>>(decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - template - friend constexpr auto operator>>(Integer lhs, decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); - - friend constexpr auto operator~(decimal32_t lhs) noexcept -> decimal32_t; - - // extensions - // 3.6.4 Same Quantum - friend constexpr auto samequantumd32(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; - - // 3.6.5 Quantum exponent - friend constexpr auto quantexpd32(decimal32_t x) noexcept -> int; - - // 3.6.6 Quantize - friend constexpr auto quantized32(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; - - // functions that need to be friends - friend constexpr auto copysignd32(decimal32_t mag, decimal32_t sgn) noexcept -> decimal32_t; - friend constexpr auto fmad32(decimal32_t x, decimal32_t y, decimal32_t z) noexcept -> decimal32_t; - - // Related to - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto scalbnd32(decimal32_t num, int exp) noexcept -> decimal32_t; - friend constexpr auto scalblnd32(decimal32_t num, long exp) noexcept -> decimal32_t; - - // These can be made public only for debugging matters -#ifndef BOOST_DECIMAL_DEBUG_MEMBERS -private: -#endif - // Replaces the biased exponent with the value of exp - template - constexpr auto edit_exponent(T exp) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); - - // Replaces the value of the significand with sig - template - constexpr auto edit_significand(T sig) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); - - // Replaces the current sign with the one provided - constexpr auto edit_sign(bool sign) noexcept -> void; -}; - -BOOST_DECIMAL_EXPORT using decimal32 [[deprecated("Use the renamed decimal32_t instead of decimal32")]] = decimal32_t; - -#if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic pop -#endif - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wduplicated-branches" -# pragma GCC diagnostic ignored "-Wbool-compare" -# pragma GCC diagnostic ignored "-Wconversion" -#endif - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, bool sign) noexcept // NOLINT(readability-function-cognitive-complexity,misc-no-recursion) -{ - static_assert(detail::is_integral_v, "Coefficient must be an integer"); - static_assert(detail::is_integral_v, "Exponent must be an integer"); - - bits_ = sign ? detail::d32_sign_mask : UINT32_C(0); - - // If the coeff is not in range, make it so - // Only count the number of digits if we absolutely have to - int coeff_digits {-1}; - if (coeff > detail::d32_max_significand_value) - { - // Since we know that the unsigned coeff is >= 10'000'000 we can use this information to traverse pruned trees - coeff_digits = detail::d32_constructor_num_digits(coeff); - if (coeff_digits > detail::precision + 1) - { - const auto digits_to_remove {coeff_digits - (detail::precision + 1)}; - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic push - # pragma GCC diagnostic ignored "-Wconversion" - #endif - - coeff /= detail::pow10(static_cast(digits_to_remove)); - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic pop - #endif - - coeff_digits -= digits_to_remove; - exp += static_cast(detail::fenv_round(coeff, sign)) + digits_to_remove; - } - else - { - exp += static_cast(detail::fenv_round(coeff, sign)); - } - } - - auto reduced_coeff {static_cast(coeff)}; - bool big_combination {false}; - - if (reduced_coeff == 0U) - { - // Normalize our handling of zeros - return; - } - - if (reduced_coeff <= detail::d32_biggest_no_combination_significand) - { - // If the coefficient fits directly, we don't need to use the combination field - // bits_.significand = reduced_coeff; - bits_ |= (reduced_coeff & detail::d32_not_11_significand_mask); - } - else - { - // Have to use the full combination field - bits_ |= (detail::d32_comb_11_mask | (reduced_coeff & detail::d32_11_significand_mask)); - big_combination = true; - } - - // If the exponent fits we do not need to use the combination field - const auto biased_exp {static_cast(exp + detail::bias)}; - if (biased_exp <= detail::d32_max_biased_exponent) - { - if (big_combination) - { - bits_ |= (biased_exp << detail::d32_11_exp_shift) & detail::d32_11_exp_mask; - } - else - { - bits_ |= (biased_exp << detail::d32_not_11_exp_shift) & detail::d32_not_11_exp_mask; - } - } - else - { - // If we can fit the extra exponent in the significand, then we can construct the value - // If we can't, the value is either 0 or infinity depending on the sign of exp - - if (coeff_digits == -1) - { - coeff_digits = detail::num_digits(reduced_coeff); - } - - const auto exp_delta {biased_exp - detail::d32_max_biased_exponent}; - const auto digit_delta {coeff_digits - static_cast(exp_delta)}; - if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision) - { - exp -= digit_delta; - reduced_coeff *= detail::pow10(static_cast(digit_delta)); - *this = decimal32_t(reduced_coeff, exp, sign); - } - else - { - bits_ = exp < 0 ? UINT32_C(0) : detail::d32_inf_mask; - } - } -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal32_t::decimal32_t(const T1 coeff, const T2 exp) noexcept : decimal32_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic pop -#endif - -constexpr decimal32_t::decimal32_t(const bool value) noexcept : decimal32_t(static_cast(value), 0, false) {} - -constexpr auto from_bits(const std::uint32_t bits) noexcept -> decimal32_t -{ - decimal32_t result; - result.bits_ = bits; - - return result; -} - -constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - return rhs.bits_ & detail::d32_sign_mask; -} - -constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_ & detail::d32_nan_mask) == detail::d32_nan_mask; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_ & detail::d32_snan_mask) == detail::d32_snan_mask; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return ((rhs.bits_ & detail::d32_nan_mask) == detail::d32_inf_mask); - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return ((rhs.bits_ & detail::d32_inf_mask) != detail::d32_inf_mask); - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check for de-normals - const auto sig {rhs.full_significand()}; - const auto exp {rhs.unbiased_exponent()}; - - if (exp <= detail::precision - 1) - { - return false; - } - - return (sig != 0) && isfinite(rhs); - #else - return rhs.full_significand() != 0; - #endif -} - -constexpr auto operator+(const decimal32_t rhs) noexcept -> decimal32_t -{ - return rhs; -} - -constexpr auto operator-(decimal32_t rhs) noexcept-> decimal32_t -{ - rhs.bits_ ^= detail::d32_sign_mask; - return rhs; -} - -// We use kahan summation here where applicable -// https://en.wikipedia.org/wiki/Kahan_summation_algorithm -// NOLINTNEXTLINE: If addition is actually subtraction than change operator and vice versa -constexpr auto operator+(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - - return detail::d32_add_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator+(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - // Make the significand type wide enough that it won't overflow during normalization - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - // Now that the rhs has been normalized, it is guaranteed to fit into the decimal32_t significand type - const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; - - return detail::d32_add_impl(sig_lhs, exp_lhs, lhs.isneg(), - final_sig_rhs, exp_rhs, (rhs < 0)); -} - -template -constexpr auto operator+(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return rhs + lhs; -} - -constexpr auto decimal32_t::operator++() noexcept -> decimal32_t& -{ - constexpr decimal32_t one(1, 0); - *this = *this + one; - return *this; -} - -constexpr auto decimal32_t::operator++(int) noexcept -> decimal32_t -{ - return ++(*this); -} - -constexpr auto decimal32_t::operator+=(const decimal32_t rhs) noexcept -> decimal32_t& -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator+=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) -{ - *this = *this + rhs; - return *this; -} - -// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa -constexpr auto operator-(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - - // a - b = a + (-b) - rhs_components.sign = !rhs_components.sign; - return detail::d32_add_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator-(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::d32_add_impl(sig_lhs, exp_lhs, lhs.isneg(), - final_sig_rhs, exp_rhs, !(rhs < 0)); -} - -template -constexpr auto operator-(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - const auto final_sig_lhs {static_cast(sig_lhs)}; - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d32_add_impl(final_sig_lhs, exp_lhs, (lhs < 0), - sig_rhs, exp_rhs, !rhs.isneg()); -} - -constexpr auto decimal32_t::operator--() noexcept -> decimal32_t& -{ - constexpr decimal32_t one(1, 0); - *this = *this - one; - return *this; -} - -constexpr auto decimal32_t::operator--(int) noexcept -> decimal32_t -{ - return --(*this); -} - -constexpr auto decimal32_t::operator-=(const decimal32_t rhs) noexcept -> decimal32_t& -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator-=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) -{ - *this = *this - rhs; - return *this; -} - -constexpr auto operator==(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - return equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -constexpr auto operator!=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -constexpr auto operator<(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - else if (isfinite(lhs) && isinf(rhs)) - { - return !rhs.isneg(); - } - } - #endif - - return sequential_less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !less_impl(rhs, lhs) && lhs != rhs; -} - -constexpr auto operator<=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - if (isinf(lhs)) - { - return signbit(lhs); - } - if (isinf(rhs)) - { - return !signbit(rhs); - } - } - #endif - - return !sequential_less_impl(rhs, lhs); -} - -template -constexpr auto operator<=(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - if (isnan(lhs)) - { - return false; - } - if (isinf(lhs)) - { - return signbit(lhs); - } - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(rhs)) - { - if (isnan(rhs)) - { - return false; - } - if (isinf(rhs)) - { - return !signbit(rhs); - } - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - if (isinf(lhs)) - { - return !signbit(lhs); - } - if (isinf(rhs)) - { - return signbit(rhs); - } - } - #endif - - return sequential_less_impl(rhs, lhs); -} - -template -constexpr auto operator>(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return rhs < lhs; -} - -template -constexpr auto operator>(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return rhs < lhs; -} - -constexpr auto operator>=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !sequential_less_impl(lhs, rhs); -} - -template -constexpr auto operator>=(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal32_t lhs, const decimal32_t rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif - -constexpr auto decimal32_t::unbiased_exponent() const noexcept -> exponent_type -{ - exponent_type expval {}; - - if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) - { - expval = (bits_ & detail::d32_11_exp_mask) >> detail::d32_11_exp_shift; - } - else - { - expval = (bits_ & detail::d32_not_11_exp_mask) >> detail::d32_not_11_exp_shift; - } - - return expval; -} - -constexpr auto decimal32_t::biased_exponent() const noexcept -> biased_exponent_type -{ - return static_cast(unbiased_exponent()) - detail::bias; -} - -template -constexpr auto decimal32_t::edit_exponent(T expval) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) -{ - *this = decimal32_t(this->full_significand(), expval, this->isneg()); -} - -constexpr auto decimal32_t::full_significand() const noexcept -> significand_type -{ - significand_type significand {}; - - if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) - { - constexpr std::uint32_t implied_bit {UINT32_C(0b100000000000000000000000)}; - significand = implied_bit | (bits_ & detail::d32_11_significand_mask); - } - else - { - significand = bits_ & detail::d32_not_11_significand_mask; - } - - return significand; -} - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4127) -#endif - -template -constexpr auto decimal32_t::edit_significand(const T sig) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) -{ - const auto unsigned_sig {detail::make_positive_unsigned(sig)}; - BOOST_DECIMAL_IF_CONSTEXPR (detail::is_signed_v) - { - *this = decimal32_t(unsigned_sig, this->biased_exponent(), this->isneg() || sig < 0); - } - else - { - *this = decimal32_t(unsigned_sig, this->biased_exponent(), this->isneg()); - } -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -constexpr auto decimal32_t::isneg() const noexcept -> bool -{ - return static_cast(bits_ & detail::d32_sign_mask); -} - -// Allows changing the sign even on nans and infs -constexpr auto decimal32_t::edit_sign(const bool sign) noexcept -> void -{ - if (sign) - { - bits_ |= detail::d32_sign_mask; - } - else - { - bits_ &= ~detail::d32_sign_mask; - } -} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -constexpr auto decimal32_t::to_components() const noexcept -> detail::decimal32_t_components -{ - detail::decimal32_t_components components {}; - - exponent_type expval {}; - significand_type significand {}; - - if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) - { - constexpr std::uint32_t implied_bit {UINT32_C(0b100000000000000000000000)}; - significand = implied_bit | (bits_ & detail::d32_11_significand_mask); - expval = (bits_ & detail::d32_11_exp_mask) >> detail::d32_11_exp_shift; - } - else - { - significand = bits_ & detail::d32_not_11_significand_mask; - expval = (bits_ & detail::d32_not_11_exp_mask) >> detail::d32_not_11_exp_shift; - } - - components.sig = significand; - components.exp = static_cast(expval) - detail::bias_v; - components.sign = bits_ & detail::d32_sign_mask; - - return components; -} - - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::decimal32_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - *this = boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - *this = boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "Mant: " << components.mantissa - << "\nExp: " << components.exponent - << "\nSign: " << components.sign << std::endl; - #endif - - #ifndef BOOST_DECIMAL_FAST_MATH - if (components.exponent > detail::emax) - { - *this = boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); - } - else - #endif - { - *this = decimal32_t {components.mantissa, components.exponent, components.sign}; - } - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -template -BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal32_t::operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal32_t&) -{ - *this = decimal32_t{val}; - return *this; -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal32_t::decimal32_t(const Decimal val) noexcept -{ - *this = to_decimal(val); -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal32_t::decimal32_t(const Integer val) noexcept : decimal32_t{val, 0}// NOLINT : Incorrect parameter is never used -{ -} - -template -constexpr auto decimal32_t::operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) -{ - using ConversionType = std::conditional_t::value, std::int32_t, Integer>; - *this = decimal32_t{static_cast(val), 0}; - return *this; -} - -constexpr decimal32_t::operator bool() const noexcept -{ - constexpr decimal32_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal32_t::operator int() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator unsigned() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator unsigned long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator long long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator unsigned long long() const noexcept -{ - return to_integral(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal32_t::operator detail::builtin_int128_t() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal32_t::operator detail::builtin_uint128_t() const noexcept -{ - return to_integral(*this); -} - -#endif - -template , bool>> -constexpr decimal32_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR auto to_bits(const decimal32_t rhs) noexcept -> std::uint32_t -{ - const auto bits {detail::bit_cast(rhs.bits_)}; - return bits; -} - -constexpr auto operator*(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - const auto lhs_components {lhs.to_components()}; - const auto rhs_components {rhs.to_components()}; - - return detail::mul_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator*(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::mul_impl(sig_lhs, exp_lhs, lhs.isneg(), - final_sig_rhs, exp_rhs, (rhs < 0)); -} - -template -constexpr auto operator*(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return rhs * lhs; -} - -constexpr auto decimal32_t::operator*=(const decimal32_t rhs) noexcept -> decimal32_t& -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator*=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) -{ - *this = *this * rhs; - return *this; -} - -constexpr auto div_impl(const decimal32_t lhs, const decimal32_t rhs, decimal32_t& q, decimal32_t& r) noexcept -> void -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal32_t zero {0, 0}; - constexpr decimal32_t nan {boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask)}; - constexpr decimal32_t inf {boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask)}; - - const bool sign {lhs.isneg() != rhs.isneg()}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - #else - static_cast(r); - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - q = detail::generic_div_impl(lhs_components, rhs_components); -} - -constexpr auto mod_impl(const decimal32_t lhs, const decimal32_t rhs, const decimal32_t& q, decimal32_t& r) noexcept -> void -{ - constexpr decimal32_t zero {0, 0}; - - // https://en.cppreference.com/w/cpp/numeric/math/fmod - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal32_t(q_trunc) * rhs); -} - -constexpr auto operator/(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - decimal32_t q {}; - decimal32_t r {}; - div_impl(lhs, rhs, q, r); - - return q; -} - -template -constexpr auto operator/(const decimal32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using exp_type = decimal32_t::biased_exponent_type; - using sig_type = decimal32_t::significand_type; - using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal32_t zero {0, 0}; - constexpr decimal32_t nan {boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask)}; - constexpr decimal32_t inf {boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask)}; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - detail::decimal32_t_components lhs_components {sig_lhs, exp_lhs, lhs.isneg()}; - - exp_type exp_rhs {}; - auto unsigned_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - detail::normalize(unsigned_rhs, exp_rhs); - detail::decimal32_t_components rhs_components {static_cast(unsigned_rhs), exp_rhs, rhs < 0}; - - return detail::generic_div_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator/(Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - using exp_type = decimal32_t::biased_exponent_type; - using sig_type = decimal32_t::significand_type; - using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal32_t zero {0, 0}; - constexpr decimal32_t nan {boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask)}; - constexpr decimal32_t inf {boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask)}; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - const auto rhs_fp {fpclassify(rhs)}; - - if (rhs_fp == FP_NAN) - { - return nan; - } - - switch (rhs_fp) - { - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - exp_type lhs_exp {}; - auto unsigned_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - detail::normalize(unsigned_lhs, lhs_exp); - detail::decimal32_t_components lhs_components {static_cast(unsigned_lhs), lhs_exp, lhs < 0}; - detail::decimal32_t_components rhs_components {sig_rhs, exp_rhs, rhs.isneg()}; - - return detail::generic_div_impl(lhs_components, rhs_components); -} - -constexpr auto decimal32_t::operator/=(const decimal32_t rhs) noexcept -> decimal32_t& -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal32_t::operator/=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr auto operator%(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - decimal32_t q {}; - decimal32_t r {}; - div_impl(lhs, rhs, q, r); - mod_impl(lhs, rhs, q, r); - - return r; -} - -constexpr auto decimal32_t::operator%=(const decimal32_t rhs) noexcept -> decimal32_t& -{ - *this = *this % rhs; - return *this; -} - -// LCOV_EXCL_START -inline auto debug_pattern(const decimal32_t rhs) noexcept -> void -{ - #if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) - std::cerr << "Sig: " << rhs.full_significand() - << "\nExp: " << rhs.biased_exponent() - << "\nNeg: " << rhs.isneg() << std::endl; - #else - static_cast(rhs); - #endif -} -// LCOV_EXCL_STOP - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator long double() const noexcept -{ - // Double already has more range and precision than a decimal32_t will ever be able to provide - return static_cast(to_float(*this)); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal32_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal32_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal32_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal32_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -constexpr auto operator&(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - return from_bits(lhs.bits_ & rhs.bits_); -} - -template -constexpr auto operator&(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(lhs.bits_ & static_cast(rhs)); -} - -template -constexpr auto operator&(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(static_cast(lhs) & rhs.bits_); -} - -constexpr auto operator|(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - return from_bits(lhs.bits_ | rhs.bits_); -} - -template -constexpr auto operator|(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(lhs.bits_ | static_cast(rhs)); -} - -template -constexpr auto operator|(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(static_cast(lhs) | rhs.bits_); -} - -constexpr auto operator^(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - return from_bits(lhs.bits_ ^ rhs.bits_); -} - -template -constexpr auto operator^(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(lhs.bits_ ^ static_cast(rhs)); -} - -template -constexpr auto operator^(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(static_cast(lhs) ^ rhs.bits_); -} - -constexpr auto operator<<(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - return from_bits(lhs.bits_ << rhs.bits_); -} - -template -constexpr auto operator<<(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(lhs.bits_ << static_cast(rhs)); -} - -template -constexpr auto operator<<(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(static_cast(lhs) << rhs.bits_); -} - -constexpr auto operator>>(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - return from_bits(lhs.bits_ >> rhs.bits_); -} - -template -constexpr auto operator>>(const decimal32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(lhs.bits_ >> static_cast(rhs)); -} - -template -constexpr auto operator>>(const Integer lhs, const decimal32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) -{ - return from_bits(static_cast(lhs) >> rhs.bits_); -} - -constexpr auto operator~(const decimal32_t lhs) noexcept -> decimal32_t -{ - return from_bits(~lhs.bits_); -} - -// 3.6.4 -// Effects: determines if the quantum exponents of x and y are the same. -// If both x and y are NaN, or infinity, they have the same quantum exponents; -// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -// The samequantum functions raise no exception. -constexpr auto samequantumd32(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) - { - return true; - } - if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) - { - return false; - } - #endif - - return lhs.unbiased_exponent() == rhs.unbiased_exponent(); -} - -// 3.6.5 -// Effects: if x is finite, returns its quantum exponent. -// Otherwise, a domain error occurs and INT_MIN is returned. -constexpr auto quantexpd32(const decimal32_t x) noexcept -> int -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(x)) - { - return INT_MIN; - } - #endif - - return static_cast(x.unbiased_exponent()); -} - -// 3.6.6 -// Returns: a number that is equal in value (except for any rounding) and sign to x, -// and which has an exponent set to be equal to the exponent of y. -// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; -// if the result does not have the same value as x, the "inexact" floating-point exception is raised. -// If the exponent is being decreased and the significand of the result has more digits than the type would allow, -// the "invalid" floating-point exception is raised and the result is NaN. -// If one or both operands are NaN the result is NaN. -// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. -// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. -// The quantize functions do not signal underflow. -constexpr auto quantized32(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Return the correct type of nan - if (isnan(lhs)) - { - return lhs; - } - if (isnan(rhs)) - { - return rhs; - } - - // If one is infinity then return a signaling NAN - if (isinf(lhs) != isinf(rhs)) - { - return from_bits(detail::d32_snan_mask); - } - if (isinf(lhs) && isinf(rhs)) - { - return lhs; - } - #endif - - return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; -} - -constexpr auto scalblnd32(decimal32_t num, const long exp) noexcept -> decimal32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal32_t zero {0, 0}; - - if (num == zero || exp == 0 || !isfinite(num)) - { - return num; - } - #endif - - num.edit_exponent(num.biased_exponent() + exp); - - return num; -} - -constexpr auto scalbnd32(const decimal32_t num, const int expval) noexcept -> decimal32_t -{ - return scalblnd32(num, static_cast(expval)); -} - -constexpr auto copysignd32(decimal32_t mag, const decimal32_t sgn) noexcept -> decimal32_t -{ - mag.edit_sign(sgn.isneg()); - return mag; -} - -} // namespace decimal -} // namespace boost - -namespace std { - -template <> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ - -#ifdef _MSC_VER -public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_present; - static constexpr bool has_denorm_loss = true; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = true; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 7; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -95; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 96; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal32_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal32_t { return {boost::decimal::detail::d32_max_significand_value, max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal32_t { return {boost::decimal::detail::d32_max_significand_value, max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal32_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal32_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask); } - static constexpr auto denorm_min () -> boost::decimal::decimal32_t { return {1, boost::decimal::detail::etiny}; } -}; - -} // Namespace std - -#endif // BOOST_DECIMAL_decimal32_t_HPP diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp deleted file mode 100644 index fe7311633..000000000 --- a/include/boost/decimal/decimal32_fast.hpp +++ /dev/null @@ -1,1510 +0,0 @@ -// Copyright 2023 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal_fast32_t_HPP -#define BOOST_DECIMAL_decimal_fast32_t_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE -#include -#include -#endif - -namespace boost { -namespace decimal { - -namespace detail { - -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_inf = std::numeric_limits::max() - 3; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_qnan = std::numeric_limits::max() - 2; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d32_fast_snan = std::numeric_limits::max() - 1; - -} - -BOOST_DECIMAL_EXPORT class decimal_fast32_t final -{ -public: - using significand_type = std::uint32_t; - using exponent_type = std::uint8_t; - using biased_exponent_type = std::int32_t; - -private: - // In regular decimal32_t we have to decode the 24 bits of the significand and the 8 bits of the exp - // Here we just use them directly at the cost of at least 2 extra bytes of internal state - // since the fast integer types will be at least 32 and 8 bits respectively - - significand_type significand_ {}; - exponent_type exponent_ {}; - bool sign_ {}; - - constexpr auto isneg() const noexcept -> bool - { - return sign_; - } - - constexpr auto full_significand() const noexcept -> significand_type - { - return significand_; - } - - constexpr auto unbiased_exponent() const noexcept -> exponent_type - { - return exponent_; - } - - constexpr auto biased_exponent() const noexcept -> biased_exponent_type - { - return static_cast(exponent_) - detail::bias_v; - } - - constexpr auto to_components() const noexcept -> detail::decimal_fast32_t_components - { - return {full_significand(), biased_exponent(), isneg()}; - } - - friend constexpr auto div_impl(decimal_fast32_t lhs, decimal_fast32_t rhs, decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void; - - friend constexpr auto mod_impl(decimal_fast32_t lhs, decimal_fast32_t rhs, const decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void; - - // Attempts conversion to integral type: - // If this is nan sets errno to EINVAL and returns 0 - // If this is not representable sets errno to ERANGE and returns 0 - template - friend constexpr auto to_integral(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - // Equality template between any integer type and decimal32_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal32_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - template - friend constexpr auto to_dpd_d32(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint32_t); - - template - friend constexpr auto detail::d32_add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; - - template - friend constexpr auto detail::d32_fast_add_only_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - friend constexpr auto not_finite(const decimal_fast32_t& val) noexcept -> bool; - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - constexpr decimal_fast32_t() noexcept = default; - - template && detail::is_integral_v, bool> = true> - constexpr decimal_fast32_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - template && detail::is_integral_v, bool> = true> - constexpr decimal_fast32_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal_fast32_t(bool value) noexcept; - - template , bool> = true> - constexpr decimal_fast32_t(Integer coeff) noexcept; - - template , bool> = true> - explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t(Float val) noexcept; - - constexpr decimal_fast32_t(const decimal_fast32_t& val) noexcept = default; - constexpr decimal_fast32_t(decimal_fast32_t&& val) noexcept = default; - constexpr auto operator=(const decimal_fast32_t& val) noexcept -> decimal_fast32_t& = default; - constexpr auto operator=(decimal_fast32_t&& val) noexcept -> decimal_fast32_t& = default; - - // cmath functions that are easier as friends - friend constexpr auto signbit(decimal_fast32_t val) noexcept -> bool; - friend constexpr auto isinf(decimal_fast32_t val) noexcept -> bool; - friend constexpr auto isnan(decimal_fast32_t val) noexcept -> bool; - friend constexpr auto issignaling(decimal_fast32_t val) noexcept -> bool; - friend constexpr auto isnormal(decimal_fast32_t val) noexcept -> bool; - friend constexpr auto isfinite(decimal_fast32_t val) noexcept -> bool; - - // Comparison operators - friend constexpr auto operator==(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto operator!=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto operator<(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto operator<=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto operator>(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto operator>=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - - // Mixed comparisons - template - friend constexpr auto operator==(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - - friend constexpr auto operator<=>(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - #endif - - // Unary operators - friend constexpr auto operator+(decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - friend constexpr auto operator-(decimal_fast32_t lhs) noexcept -> decimal_fast32_t; - - // Binary arithmetic - friend constexpr auto operator+(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - friend constexpr auto operator-(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - friend constexpr auto operator*(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - friend constexpr auto operator/(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - friend constexpr auto operator%(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; - - // Mixed type binary arithmetic - template - friend constexpr auto operator+(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator+(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator-(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator-(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator*(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator*(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator/(decimal_fast32_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - template - friend constexpr auto operator/(Integer lhs, decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); - - // Compound operators - constexpr auto operator+=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; - constexpr auto operator-=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; - constexpr auto operator*=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; - constexpr auto operator/=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; - constexpr auto operator%=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; - - // Mixed type compound operators - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); - - // Increment and decrement - constexpr auto operator++() noexcept -> decimal_fast32_t&; - constexpr auto operator++(int) noexcept -> decimal_fast32_t&; - constexpr auto operator--() noexcept -> decimal_fast32_t&; - constexpr auto operator--(int) noexcept -> decimal_fast32_t&; - - // 3.2.2.4 Conversion to integral type - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator detail::builtin_int128_t() const noexcept; - explicit constexpr operator detail::builtin_uint128_t() const noexcept; - #endif - - // 3.2.6 Conversion to a floating-point type - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - - // Conversion to another decimal type - template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> - constexpr operator Decimal() const noexcept; - - template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> - explicit constexpr operator Decimal() const noexcept; - - friend constexpr auto direct_init(significand_type significand, exponent_type exponent, bool sign) noexcept -> decimal_fast32_t; - friend constexpr auto direct_init(const detail::decimal_fast32_t_components& x) noexcept -> decimal_fast32_t; - - // or extensions that need to be friends - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto copysignd32f(decimal_fast32_t mag, decimal_fast32_t sgn) noexcept -> decimal_fast32_t; - friend constexpr auto scalbnd32f(decimal_fast32_t num, int exp) noexcept -> decimal_fast32_t; - friend constexpr auto scalblnd32f(decimal_fast32_t num, long exp) noexcept -> decimal_fast32_t; - friend constexpr auto fmad32f(decimal_fast32_t x, decimal_fast32_t y, decimal_fast32_t z) noexcept -> decimal_fast32_t; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - // Specific decimal functionality - friend constexpr auto samequantumd32f(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; - friend constexpr auto quantexpd32f(decimal_fast32_t x) noexcept -> int; - friend constexpr auto quantized32f(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; -}; - -BOOST_DECIMAL_EXPORT using decimal32_fast [[deprecated("Use re-named type decimal_fast32_t instead of decimal_fast32_t")]] = decimal_fast32_t; - -template && detail::is_integral_v, bool>> -constexpr decimal_fast32_t::decimal_fast32_t(T1 coeff, T2 exp, bool sign) noexcept -{ - using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; - - minimum_coefficient_size min_coeff {coeff}; - - sign_ = sign; - - // Normalize in the constructor, so we never have to worry about it again - detail::normalize(min_coeff, exp, sign); - - significand_ = static_cast(min_coeff); - - const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias}; - - // decimal32_t exponent holds 8 bits - if (biased_exp > detail::max_biased_exp_v) - { - significand_ = detail::d32_fast_inf; - } - else if (biased_exp >= 0) - { - exponent_ = static_cast(biased_exp); - } - else - { - // Flush denorms to zero - significand_ = static_cast(0); - exponent_ = static_cast(detail::bias); - sign_ = false; - } -} - -template && detail::is_integral_v, bool>> -constexpr decimal_fast32_t::decimal_fast32_t(const T1 coeff, const T2 exp) noexcept : decimal_fast32_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -constexpr decimal_fast32_t::decimal_fast32_t(const bool value) noexcept : decimal_fast32_t(static_cast(value), 0, false) {} - -template , bool>> -constexpr decimal_fast32_t::decimal_fast32_t(const Integer val) noexcept : decimal_fast32_t{val, 0} {} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -template , bool>> -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::decimal_fast32_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - significand_ = detail::d32_fast_qnan; - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - significand_ = detail::d32_fast_inf; - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - *this = decimal_fast32_t {components.mantissa, components.exponent, components.sign}; - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -constexpr auto direct_init(const decimal_fast32_t::significand_type significand, const decimal_fast32_t::exponent_type exponent, const bool sign = false) noexcept -> decimal_fast32_t -{ - decimal_fast32_t val; - val.significand_ = significand; - val.exponent_ = exponent; - val.sign_ = sign; - - return val; -} - -constexpr auto direct_init(const detail::decimal_fast32_t_components& x) noexcept -> decimal_fast32_t -{ - decimal_fast32_t val; - val.significand_ = x.sig; - val.exponent_ = static_cast(static_cast(x.exp) + detail::bias_v); - val.sign_ = x.sign; - - return val; -} - -constexpr auto signbit(const decimal_fast32_t val) noexcept -> bool -{ - return val.sign_; -} - -constexpr auto isinf(const decimal_fast32_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ == detail::d32_fast_inf; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnan(const decimal_fast32_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ >= detail::d32_fast_qnan; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto issignaling(const decimal_fast32_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ == detail::d32_fast_snan; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnormal(const decimal_fast32_t val) noexcept -> bool -{ - return (val.significand_ != 0) - #ifndef BOOST_DECIMAL_FAST_MATH - && isfinite(val) && (val.exponent_ > static_cast(detail::precision_v - 1)) - #endif - ; -} - -constexpr auto isfinite(const decimal_fast32_t val) noexcept -> bool -{ - return val.significand_ < detail::d32_fast_inf; -} - -BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast32_t& val) noexcept -> bool -{ - return val.significand_ >= detail::d32_fast_inf; -} - -constexpr auto operator==(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - return fast_equality_impl(lhs, rhs); -} - -constexpr auto operator!=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - return fast_inequality_impl(lhs, rhs); -} - -constexpr auto operator<(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - return fast_less_impl(lhs, rhs); -} - -constexpr auto operator<=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - return rhs < lhs; -} - -constexpr auto operator>=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator==(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -template -constexpr auto operator!=(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator<(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(rhs) ? false : !less_impl(rhs, lhs) && lhs != rhs; - #else - return !less_impl(rhs, lhs) && lhs != rhs; - #endif -} - -template -constexpr auto operator<=(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(lhs) ? false : !(rhs < lhs); - #else - return !(rhs < lhs); - #endif -} - -template -constexpr auto operator<=(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(rhs) ? false : !(rhs < lhs); - #else - return !(rhs < lhs); - #endif -} - -template -constexpr auto operator>(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(lhs) ? false : rhs < lhs; - #else - return rhs < lhs; - #endif -} - -template -constexpr auto operator>(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(rhs) ? false : rhs < lhs; - #else - return rhs < lhs; - #endif -} - -template -constexpr auto operator>=(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(lhs) ? false : !(lhs < rhs); - #else - return !(lhs < rhs); - #endif -} - -template -constexpr auto operator>=(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return isnan(rhs) ? false : !(lhs < rhs); - #else - return !(lhs < rhs); - #endif -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif - -constexpr auto operator+(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - return rhs; -} - -constexpr auto operator-(decimal_fast32_t lhs) noexcept -> decimal_fast32_t -{ - lhs.sign_ = !lhs.sign_; - return lhs; -} - -constexpr auto operator+(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - if (lhs.isneg() || rhs.isneg()) - { - return detail::d32_add_impl(lhs, rhs); - } - else - { - const auto res {detail::d32_fast_add_only_impl(lhs, rhs)}; - return direct_init(res); - } -} - -template -constexpr auto operator+(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; - - return detail::d32_add_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_sig_rhs, exp_rhs, (rhs < 0)); -} - -template -constexpr auto operator+(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - return rhs + lhs; -} - -constexpr auto operator-(const decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - rhs.sign_ = !rhs.sign_; - - if (lhs.sign_ || rhs.sign_) - { - return detail::d32_add_impl(lhs, rhs); - } - else - { - const auto res {detail::d32_fast_add_only_impl(lhs, rhs)}; - return direct_init(res); - } -} - -template -constexpr auto operator-(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; - - return detail::d32_add_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_sig_rhs, exp_rhs, !(rhs < 0)); -} - -template -constexpr auto operator-(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - auto final_sig_lhs {static_cast(detail::make_positive_unsigned(sig_lhs))}; - - return detail::d32_add_impl( - final_sig_lhs, exp_lhs, (lhs < 0), - rhs.significand_, rhs.biased_exponent(), !rhs.sign_ - ); -} - -constexpr auto operator*(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs) || !isfinite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - using mul_type = std::uint_fast64_t; - - const auto isneg {lhs.sign_ != rhs.sign_}; - constexpr auto ten_pow_seven {detail::pow10(static_cast(6))}; - constexpr auto ten_pow_seven_exp_offset {95}; - constexpr auto ten_pow_six {detail::pow10(static_cast(5))}; - constexpr auto ten_pow_six_exp_offset {96}; - - auto res_sig {(static_cast(lhs.significand_) * static_cast(rhs.significand_))}; - const bool res_sig_14_dig {res_sig > UINT64_C(10000000000000)}; - res_sig /= res_sig_14_dig ? ten_pow_seven : ten_pow_six; - auto res_exp {lhs.exponent_ + rhs.exponent_}; - res_exp -= res_sig_14_dig ? ten_pow_seven_exp_offset : ten_pow_six_exp_offset; - - res_exp += detail::fenv_round(res_sig, isneg); - - BOOST_DECIMAL_ASSERT(res_sig >= 1'000'000 || res_sig == 0U); - BOOST_DECIMAL_ASSERT(res_exp <= 9'999'999 || res_sig == 0U); - - return direct_init(static_cast(res_sig), static_cast(res_exp) , isneg); -} - -template -constexpr auto operator*(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - - // We don't know if the original value of rhs fits into the decimal_fast32_t significand type - // but once it's normalized it's guaranteed to fit - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::mul_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_sig_rhs, exp_rhs, (rhs < 0)); -} - -template -constexpr auto operator*(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - return rhs * lhs; -} - -constexpr auto div_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs, decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void -{ - constexpr decimal_fast32_t zero {0, 0}; - - #ifndef BOOST_DECIMAL_FAST_MATH - const bool sign {lhs.isneg() != rhs.isneg()}; - constexpr decimal_fast32_t nan {direct_init(detail::d32_fast_qnan, UINT8_C(0), false)}; - constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - #else - static_cast(r); - #endif - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - using local_signed_exponent_type = std::common_type_t; - - static_assert(sizeof(local_signed_exponent_type) >= 4, "Error in local exponent type definition"); - - // We promote to uint64 since the significands are currently 32-bits - // By appending enough zeros to the LHS we end up finding what we need anyway - constexpr auto ten_pow_precision {detail::pow10(static_cast(detail::precision_v))}; - const auto big_sig_lhs {static_cast(lhs.significand_) * ten_pow_precision}; - auto res_sig {big_sig_lhs / static_cast(rhs.significand_)}; - local_signed_exponent_type res_exp {static_cast(lhs.exponent_) - static_cast(rhs.exponent_) + 94}; - const auto isneg {lhs.sign_ != rhs.sign_}; - - // If we have 8 figures round it down to 7 - if (res_sig >= UINT64_C(10'000'000)) - { - res_exp += detail::fenv_round(res_sig, isneg); - } - - BOOST_DECIMAL_ASSERT(res_sig >= 1'000'000 || res_sig == 0U); - BOOST_DECIMAL_ASSERT(res_exp <= 9'999'999 || res_sig == 0U); - - if (BOOST_DECIMAL_LIKELY(res_exp >= 0)) - { - q = direct_init(static_cast(res_sig), static_cast(res_exp), isneg); - } - else - { - // Flush to zero - q = zero; - } -} - -constexpr auto mod_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs, const decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void -{ - constexpr decimal_fast32_t zero {0, 0}; - - // https://en.cppreference.com/w/cpp/numeric/math/fmod - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal_fast32_t(q_trunc) * rhs); -} - -constexpr auto operator/(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - decimal_fast32_t q {}; - decimal_fast32_t r {}; - div_impl(lhs, rhs, q, r); - - return q; -} - -template -constexpr auto operator/(const decimal_fast32_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast32_t zero {0, 0}; - constexpr decimal_fast32_t nan {direct_init(detail::d32_fast_qnan, UINT8_C(0), false)}; - constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - const detail::decimal_fast32_t_components lhs_components {lhs.significand_, lhs.biased_exponent(), lhs.sign_}; - exp_type exp_rhs {}; - const detail::decimal_fast32_t_components rhs_components {detail::shrink_significand(detail::make_positive_unsigned(rhs), exp_rhs), exp_rhs, rhs < 0}; - - return detail::generic_div_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator/(const Integer lhs, const decimal_fast32_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) -{ - using exp_type = decimal_fast32_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast32_t zero {0, 0}; - constexpr decimal_fast32_t nan {direct_init(detail::d32_fast_qnan, UINT8_C(0), false)}; - constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - const auto rhs_fp {fpclassify(rhs)}; - - if (rhs_fp == FP_NAN) - { - return nan; - } - - switch (rhs_fp) - { - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - exp_type lhs_exp {}; - const auto lhs_sig {detail::make_positive_unsigned(detail::shrink_significand(lhs, lhs_exp))}; - const detail::decimal_fast32_t_components lhs_components {lhs_sig, lhs_exp, lhs < 0}; - const detail::decimal_fast32_t_components rhs_components {rhs.significand_, rhs.biased_exponent(), rhs.isneg()}; - - return detail::generic_div_impl(lhs_components, rhs_components); -} - -constexpr auto operator%(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - decimal_fast32_t q {}; - decimal_fast32_t r {}; - div_impl(lhs, rhs, q, r); - mod_impl(lhs, rhs, q, r); - - return r; -} - -constexpr auto decimal_fast32_t::operator%=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& -{ - *this = *this % rhs; - return *this; -} - -constexpr auto decimal_fast32_t::operator+=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& -{ - *this = *this + rhs; - return *this; -} - -constexpr auto decimal_fast32_t::operator-=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& -{ - *this = *this - rhs; - return *this; -} - -constexpr auto decimal_fast32_t::operator*=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& -{ - *this = *this * rhs; - return *this; -} - -constexpr auto decimal_fast32_t::operator/=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal_fast32_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal_fast32_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal_fast32_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal_fast32_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr auto decimal_fast32_t::operator++() noexcept -> decimal_fast32_t& -{ - constexpr decimal_fast32_t one(1, 0); - *this = *this + one; - return *this; -} - -constexpr auto decimal_fast32_t::operator++(int) noexcept -> decimal_fast32_t& -{ - return ++(*this); -} - -constexpr auto decimal_fast32_t::operator--() noexcept -> decimal_fast32_t& -{ - constexpr decimal_fast32_t one(1, 0); - *this = *this - one; - return *this; -} - -constexpr auto decimal_fast32_t::operator--(int) noexcept -> decimal_fast32_t& -{ - return --(*this); -} - -constexpr decimal_fast32_t::operator bool() const noexcept -{ - constexpr decimal_fast32_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal_fast32_t::operator int() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator unsigned() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator unsigned long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator long long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator unsigned long long() const noexcept -{ - return to_integral(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal_fast32_t::operator detail::builtin_int128_t() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast32_t::operator detail::builtin_uint128_t() const noexcept -{ - return to_integral(*this); -} - -#endif - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator long double() const noexcept -{ - // The precision and range of double already exceeds what decimal_fast32_t can provide - return static_cast(to_float(*this)); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal_fast32_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal_fast32_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal_fast32_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal_fast32_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -template && (detail::decimal_val_v > detail::decimal_val_v), bool>> -constexpr decimal_fast32_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> -constexpr decimal_fast32_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -constexpr auto scalblnd32f(const decimal_fast32_t num, const long exp) noexcept -> decimal_fast32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal_fast32_t zero {0, 0}; - - if (num == zero || exp == 0 || !isfinite(num)) - { - return num; - } - #endif - - const auto res {decimal_fast32_t(num.significand_, num.biased_exponent() + exp, num.sign_)}; - - return res; -} - -constexpr auto scalbnd32f(const decimal_fast32_t num, const int expval) noexcept -> decimal_fast32_t -{ - return scalblnd32f(num, static_cast(expval)); -} - -constexpr auto copysignd32f(decimal_fast32_t mag, const decimal_fast32_t sgn) noexcept -> decimal_fast32_t -{ - mag.sign_ = sgn.sign_; - return mag; -} - -// Effects: determines if the quantum exponents of x and y are the same. -// If both x and y are NaN, or infinity, they have the same quantum exponents; -// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -// The samequantum functions raise no exception. -constexpr auto samequantumd32f(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) - { - return true; - } - if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) - { - return false; - } - #endif - - return lhs.unbiased_exponent() == rhs.unbiased_exponent(); -} - -// Effects: if x is finite, returns its quantum exponent. -// Otherwise, a domain error occurs and INT_MIN is returned. -constexpr auto quantexpd32f(const decimal_fast32_t x) noexcept -> int -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (!isfinite(x)) - { - return INT_MIN; - } - #endif - - return static_cast(x.unbiased_exponent()); -} - -// Returns: a number that is equal in value (except for any rounding) and sign to x, -// and which has an exponent set to be equal to the exponent of y. -// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; -// if the result does not have the same value, as x, the "inexact" floating-point exception is raised. -// If the exponent is being decreased and the significand of the result has more digits than the type would allow, -// the "invalid" floating-point exception is raised and the result is NaN. -// If one or both operands are NaN, the result is NaN. -// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. -// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. -// The quantize functions do not signal underflow. -constexpr auto quantized32f(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Return the correct type of nan - if (isnan(lhs)) - { - return lhs; - } - else if (isnan(rhs)) - { - return rhs; - } - - // If one is infinity then return a signaling NAN - if (isinf(lhs) != isinf(rhs)) - { - return direct_init(detail::d32_fast_snan, UINT8_C(0)); - } - else if (isinf(lhs) && isinf(rhs)) - { - return lhs; - } - #endif - - return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; -} - -} // namespace decimal -} // namespace boost - -namespace std { - -template <> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ - -#ifdef _MSC_VER - public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_absent; - static constexpr bool has_denorm_loss = false; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 7; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -95; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 96; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal_fast32_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal_fast32_t { return {UINT32_C(9'999'999), max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal_fast32_t { return {UINT32_C(9'999'999), max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal_fast32_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal_fast32_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_inf, UINT8_C((0))); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_qnan, UINT8_C((0))); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_snan, UINT8_C((0))); } - - // With denorm absent returns the same value as min - static constexpr auto denorm_min () -> boost::decimal::decimal_fast32_t { return min(); } -}; - -} // Namespace std - -#endif //BOOST_DECIMAL_decimal_fast32_t_HPP diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index e3e7bbfd2..8eea6240c 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -1,10 +1,2297 @@ -// Copyright 2025 Matt Borland +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL32_T_HPP -#define BOOST_DECIMAL_DECIMAL32_T_HPP +#ifndef BOOST_DECIMAL_decimal32_t_HPP +#define BOOST_DECIMAL_decimal32_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL32_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) +#include +#include +#endif + +#endif // BOOST_DECIMAL_BUILD_MODULE + +namespace boost { +namespace decimal { + +namespace detail { + +// See IEEE 754 section 3.5.2 +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_inf_mask = UINT32_C(0x78000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_nan_mask = UINT32_C(0x7C000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_snan_mask = UINT32_C(0x7E000000); + +// Comb. Exponent Significand +// s eeeeeeee ttttttttttttttttttttttt - sign + 2 steering bits concatenate to 6 bits of exponent (8 total) + 23 bits of significand like float +// s 11 eeeeeeee [100] + ttttttttttttttttttttt - sign + 2 steering bits + 8 bits of exponent + 21 bits of significand (0b100 + 21 bits) +// +// Only is the type different in steering 11 which yields significand 100 + 21 bits giving us our 24 total bits of precision + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_sign_mask = UINT32_C(0x80000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_combination_field_mask = UINT32_C(0x60000000); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_comb_11_mask = d32_combination_field_mask; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_exp_mask = UINT32_C(0x7F800000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_exp_shift = UINT32_C(23); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_11_exp_mask = UINT32_C(0x1FE00000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_11_exp_shift = UINT32_C(21); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_not_11_significand_mask = UINT32_C(0x7FFFFF); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_11_significand_mask = UINT32_C(0x1FFFFF); // 21 bits + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_biggest_no_combination_significand = d32_not_11_significand_mask; // 23 bits + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_max_biased_exponent = UINT32_C(191); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t d32_max_significand_value = UINT32_C(9'999'999); + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto d32_fma_impl(T x, T y, T z) noexcept -> T; + +} // namespace detail + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + + +// ISO/IEC DTR 24733 +// 3.2.2 class decimal32_t +BOOST_DECIMAL_EXPORT class decimal32_t final // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) +{ +public: + using significand_type = std::uint32_t; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + +private: + + std::uint32_t bits_ {}; + + // Returns the un-biased (quantum) exponent + constexpr auto unbiased_exponent() const noexcept -> exponent_type ; + + // Returns the biased exponent + constexpr auto biased_exponent() const noexcept -> biased_exponent_type; + + // Returns the significand complete with the bits implied from the combination field + constexpr auto full_significand() const noexcept -> significand_type ; + constexpr auto isneg() const noexcept -> bool; + + // Returns a complete struct so we don't have to decode the number multiple times if we need everything + constexpr auto to_components() const noexcept -> detail::decimal32_t_components; + + // Attempts conversion to integral type: + // If this is nan sets errno to EINVAL and returns 0 + // If this is not representable sets errno to ERANGE and returns 0 + template + friend constexpr auto to_integral(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + friend constexpr auto div_impl(decimal32_t lhs, decimal32_t rhs, decimal32_t& q, decimal32_t& r) noexcept -> void; + friend constexpr auto mod_impl(decimal32_t lhs, decimal32_t rhs, const decimal32_t& q, decimal32_t& r) noexcept -> void; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + // Debug bit pattern + friend constexpr auto from_bits(std::uint32_t bits) noexcept -> decimal32_t; + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_bits(decimal32_t rhs) noexcept -> std::uint32_t; + + // Equality template between any integer type and decimal32_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal32_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + template + friend constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; + + template + friend constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; + + friend constexpr auto to_bid_d32(decimal32_t val) noexcept -> std::uint32_t; + + friend constexpr auto from_bid_d32(std::uint32_t bits) noexcept -> decimal32_t; + + template + friend constexpr auto to_dpd_d32(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint32_t); + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal32_t(const char* str, std::size_t len); + #endif + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_ieee_type_v, T, typename T::significand_type); + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_ieee_type_v, TargetDecimalType); + + friend constexpr auto nan_conversion(const decimal32_t value) noexcept -> decimal32_t + { + constexpr auto convert_nan_mask {detail::d32_snan_mask ^ detail::d32_nan_mask}; + + decimal32_t return_value; + return_value.bits_ = value.bits_ ^ convert_nan_mask; + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + +public: + // 3.2.2.1 construct/copy/destroy: + constexpr decimal32_t() noexcept = default; + + // 3.2.2.2 Conversion from a floating-point type + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit constexpr decimal32_t(long double val) noexcept = delete; + #endif + + template + BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal32_t&); + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + explicit constexpr decimal32_t(Decimal val) noexcept; + + // 3.2.2.3 Conversion from integral type + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal32_t(Integer val) noexcept; + + template + constexpr auto operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); + + // 3.2.2.4 Conversion to integral type + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator detail::builtin_int128_t() const noexcept; + explicit constexpr operator detail::builtin_uint128_t() const noexcept; + #endif + + // We allow implict promotions to and decimal type with greater or equal precision (e.g. decimal_fast32_t) + template , bool> = true> + constexpr operator Decimal() const noexcept; + + // 3.2.5 initialization from coefficient and exponent: + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal32_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal32_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal32_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal32_t(bool value) noexcept; + + explicit constexpr decimal32_t(const char* str); + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal32_t(const std::string& str); + #else + explicit constexpr decimal32_t(std::string_view str); + #endif + + #endif + + constexpr decimal32_t(const decimal32_t& val) noexcept = default; + constexpr decimal32_t(decimal32_t&& val) noexcept = default; + constexpr auto operator=(const decimal32_t& val) noexcept -> decimal32_t& = default; + constexpr auto operator=(decimal32_t&& val) noexcept -> decimal32_t& = default; + + // 3.2.6 Conversion to floating-point type + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + // cmath functions that are easier as friends + friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32_t rhs) noexcept -> bool; + + // 3.2.7 unary arithmetic operators: + friend constexpr auto operator+(decimal32_t rhs) noexcept -> decimal32_t; + friend constexpr auto operator-(decimal32_t rhs) noexcept -> decimal32_t; + + // 3.2.8 binary arithmetic operators: + friend constexpr auto operator+(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + template + friend constexpr auto operator+(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + template + friend constexpr auto operator+(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + friend constexpr auto operator-(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + template + friend constexpr auto operator-(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + template + friend constexpr auto operator-(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + friend constexpr auto operator*(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + template + friend constexpr auto operator*(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + template + friend constexpr auto operator*(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + friend constexpr auto operator/(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + template + friend constexpr auto operator/(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + template + friend constexpr auto operator/(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t); + + friend constexpr auto operator%(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + // 3.2.2.5 Increment and Decrement + constexpr auto operator++() noexcept -> decimal32_t&; + constexpr auto operator++(int) noexcept -> decimal32_t; // NOLINT : C++14 so constexpr implies const + constexpr auto operator--() noexcept -> decimal32_t&; + constexpr auto operator--(int) noexcept -> decimal32_t; // NOLINT : C++14 so constexpr implies const + + // 3.2.2.6 Compound assignment + constexpr auto operator+=(decimal32_t rhs) noexcept -> decimal32_t&; + + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); + + template + constexpr auto operator+=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); + + constexpr auto operator-=(decimal32_t rhs) noexcept -> decimal32_t&; + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); + + template + constexpr auto operator-=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); + + constexpr auto operator*=(decimal32_t rhs) noexcept -> decimal32_t&; + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); + + template + constexpr auto operator*=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); + + constexpr auto operator/=(decimal32_t rhs) noexcept -> decimal32_t&; + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&); + + template + constexpr auto operator/=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&); + + constexpr auto operator%=(decimal32_t rhs) noexcept -> decimal32_t&; + + // 3.2.9 comparison operators: + // Equality + friend constexpr auto operator==(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator==(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Inequality + friend constexpr auto operator!=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator!=(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less + friend constexpr auto operator<(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator<(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less equal + friend constexpr auto operator<=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator<=(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater + friend constexpr auto operator>(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator>(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater equal + friend constexpr auto operator>=(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + template + friend constexpr auto operator>=(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + friend constexpr auto operator<=>(decimal32_t lhs, decimal32_t rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + #endif + + // extensions + // 3.6.4 Same Quantum + friend constexpr auto samequantumd32(decimal32_t lhs, decimal32_t rhs) noexcept -> bool; + + // 3.6.5 Quantum exponent + friend constexpr auto quantexpd32(decimal32_t x) noexcept -> int; + + // 3.6.6 Quantize + friend constexpr auto quantized32(decimal32_t lhs, decimal32_t rhs) noexcept -> decimal32_t; + + // functions that need to be friends + friend constexpr auto copysignd32(decimal32_t mag, decimal32_t sgn) noexcept -> decimal32_t; + + template + friend constexpr auto detail::d32_fma_impl(T x, T y, T z) noexcept -> T; + + // Related to + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto scalbnd32(decimal32_t num, int exp) noexcept -> decimal32_t; + friend constexpr auto scalblnd32(decimal32_t num, long exp) noexcept -> decimal32_t; + + // These can be made public only for debugging matters +#ifndef BOOST_DECIMAL_DEBUG_MEMBERS +private: +#endif + // Replaces the biased exponent with the value of exp + template + constexpr auto edit_exponent(T exp) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); + + // Replaces the value of the significand with sig + template + constexpr auto edit_significand(T sig) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); + + // Replaces the current sign with the one provided + constexpr auto edit_sign(bool sign) noexcept -> void; +}; + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) +#endif + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic pop +#endif + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wduplicated-branches" +# pragma GCC diagnostic ignored "-Wbool-compare" +# pragma GCC diagnostic ignored "-Wconversion" +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal32_t::decimal32_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept // NOLINT(readability-function-cognitive-complexity,misc-no-recursion) +{ + static_assert(detail::is_integral_v, "Coefficient must be an integer"); + static_assert(detail::is_integral_v, "Exponent must be an integer"); + + const auto is_negative {static_cast(resultant_sign)}; + bits_ = is_negative ? detail::d32_sign_mask : UINT32_C(0); + + // If the coeff is not in range, make it so + // Only count the number of digits if we absolutely have to + int coeff_digits {-1}; + auto biased_exp {static_cast(exp + detail::bias)}; + if (coeff > detail::d32_max_significand_value || biased_exp < -(detail::precision_v - 1)) + { + coeff_digits = detail::coefficient_rounding(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff)); + } + + auto reduced_coeff {static_cast(coeff)}; + bool big_combination {false}; + + if (reduced_coeff == 0U) + { + // Normalize our handling of zeros + return; + } + + if (reduced_coeff <= detail::d32_biggest_no_combination_significand) + { + // If the coefficient fits directly, we don't need to use the combination field + // bits_.significand = reduced_coeff; + bits_ |= (reduced_coeff & detail::d32_not_11_significand_mask); + } + else + { + // Have to use the full combination field + bits_ |= (detail::d32_comb_11_mask | (reduced_coeff & detail::d32_11_significand_mask)); + big_combination = true; + } + + // If the exponent fits we do not need to use the combination field + if (BOOST_DECIMAL_LIKELY(biased_exp >= 0 && biased_exp <= static_cast(detail::d32_max_biased_exponent))) + { + if (big_combination) + { + bits_ |= (static_cast(biased_exp) << detail::d32_11_exp_shift) & detail::d32_11_exp_mask; + } + else + { + bits_ |= (static_cast(biased_exp) << detail::d32_not_11_exp_shift) & detail::d32_not_11_exp_mask; + } + } + else + { + // If we can fit the extra exponent in the significand, then we can construct the value + // If we can't, the value is either 0 or infinity depending on the sign of exp + + if (coeff_digits == -1) + { + coeff_digits = detail::num_digits(reduced_coeff); + } + + const auto exp_delta {biased_exp - static_cast(detail::d32_max_biased_exponent)}; + const auto digit_delta {coeff_digits - exp_delta}; + if (biased_exp < 0 && coeff_digits == 1) + { + // This needs to be flushed to 0 or rounded to subnormal min + rounding_mode current_round_mode {_boost_decimal_global_rounding_mode}; + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(coeff)) + { + current_round_mode = _boost_decimal_global_runtime_rounding_mode; + } + + #endif + + bool round {false}; + if (biased_exp == -1) + { + switch (current_round_mode) + { + case rounding_mode::fe_dec_to_nearest_from_zero: + BOOST_DECIMAL_FALLTHROUGH + case rounding_mode::fe_dec_to_nearest: + if (reduced_coeff >= 5U) + { + round = true; + } + break; + case rounding_mode::fe_dec_upward: + if (!is_negative && reduced_coeff != 0) + { + round = true; + } + break; + default: + round = false; + break; + } + } + + if (round) + { + // Subnormal min is just 1 + bits_ = UINT32_C(1); + } + else + { + bits_ = UINT32_C(0); + } + + bits_ |= is_negative ? detail::d32_sign_mask : UINT32_C(0); + } + else if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision) + { + exp -= digit_delta; + reduced_coeff *= detail::pow10(static_cast(digit_delta)); + *this = decimal32_t(reduced_coeff, exp, is_negative); + } + else if (coeff_digits + biased_exp <= detail::precision) + { + // Handle the case of sub-normals that don't need further rounding + bits_ = is_negative ? detail::d32_sign_mask : UINT32_C(0); // Reset the sign bit + const auto zeros {detail::remove_trailing_zeros(reduced_coeff)}; + biased_exp += static_cast(zeros.number_of_removed_zeros); + reduced_coeff = zeros.trimmed_number; + if (biased_exp > 0) + { + reduced_coeff *= detail::pow10(static_cast(biased_exp)); + } + bits_ |= reduced_coeff; + } + else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision) + { + // We can expand the coefficient to use the maximum number of digits + const auto offset {detail::precision - coeff_digits}; + exp -= offset; + reduced_coeff *= detail::pow10(static_cast(offset)); + *this = decimal32_t(reduced_coeff, exp, is_negative); + } + else + { + // Reset the value and make sure to preserve the sign of 0/inf + bits_ = exp < 0 ? UINT32_C(0) : detail::d32_inf_mask; + bits_ |= is_negative ? detail::d32_sign_mask : UINT32_C(0); + } + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal32_t::decimal32_t(const T1 coeff, const T2 exp) noexcept : decimal32_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic pop +#endif + +constexpr decimal32_t::decimal32_t(const bool value) noexcept : decimal32_t(static_cast(value), 0, false) {} + +constexpr auto from_bits(const std::uint32_t bits) noexcept -> decimal32_t +{ + decimal32_t result; + result.bits_ = bits; + + return result; +} + +namespace detail { + +template +class numeric_limits_impl32 +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = true; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 7; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -95; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 96; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal32_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal32_t { return {boost::decimal::detail::d32_max_significand_value, max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal32_t { return {boost::decimal::detail::d32_max_significand_value, max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal32_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal32_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask); } + static constexpr auto denorm_min () -> boost::decimal::decimal32_t { return {1, boost::decimal::detail::etiny}; } + +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl32::is_specialized; +template constexpr bool numeric_limits_impl32::is_signed; +template constexpr bool numeric_limits_impl32::is_integer; +template constexpr bool numeric_limits_impl32::is_exact; +template constexpr bool numeric_limits_impl32::has_infinity; +template constexpr bool numeric_limits_impl32::has_quiet_NaN; +template constexpr bool numeric_limits_impl32::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl32::has_denorm; +template constexpr bool numeric_limits_impl32::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl32::round_style; +template constexpr bool numeric_limits_impl32::is_iec559; +template constexpr bool numeric_limits_impl32::is_bounded; +template constexpr bool numeric_limits_impl32::is_modulo; +template constexpr int numeric_limits_impl32::digits; +template constexpr int numeric_limits_impl32::digits10; +template constexpr int numeric_limits_impl32::max_digits10; +template constexpr int numeric_limits_impl32::radix; +template constexpr int numeric_limits_impl32::min_exponent; +template constexpr int numeric_limits_impl32::min_exponent10; +template constexpr int numeric_limits_impl32::max_exponent; +template constexpr int numeric_limits_impl32::max_exponent10; +template constexpr bool numeric_limits_impl32::traps; +template constexpr bool numeric_limits_impl32::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl32 {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // Namespace std + +namespace boost { +namespace decimal { + +constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + return rhs.bits_ & detail::d32_sign_mask; +} + +constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_ & detail::d32_nan_mask) == detail::d32_nan_mask; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_ & detail::d32_snan_mask) == detail::d32_snan_mask; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return ((rhs.bits_ & detail::d32_nan_mask) == detail::d32_inf_mask); + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return ((rhs.bits_ & detail::d32_inf_mask) != detail::d32_inf_mask); + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check for de-normals + const auto sig {rhs.full_significand()}; + const auto exp {rhs.unbiased_exponent()}; + + if (exp <= detail::precision - 1) + { + return false; + } + + return (sig != 0) && isfinite(rhs); + #else + return rhs.full_significand() != 0; + #endif +} + +constexpr auto operator+(const decimal32_t rhs) noexcept -> decimal32_t +{ + return rhs; +} + +constexpr auto operator-(decimal32_t rhs) noexcept-> decimal32_t +{ + rhs.bits_ ^= detail::d32_sign_mask; + return rhs; +} + +// We use kahan summation here where applicable +// https://en.wikipedia.org/wiki/Kahan_summation_algorithm +// NOLINTNEXTLINE: If addition is actually subtraction than change operator and vice versa +constexpr auto operator+(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + // Case from 7.2.d + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return from_bits(detail::d32_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + return detail::add_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator+(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + // Make the significand type wide enough that it won't overflow during normalization + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + const auto components {lhs.to_components()}; + auto sig_lhs {components.sig}; + auto exp_lhs {components.exp}; + detail::expand_significand(sig_lhs, exp_lhs); + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + + // Now that the rhs has been normalized, it is guaranteed to fit into the decimal32_t significand type + const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; + + return detail::add_impl( + detail::decimal32_t_components{sig_lhs, exp_lhs, components.sign}, + detail::decimal32_t_components{final_sig_rhs, exp_rhs, (rhs < 0)} + ); +} + +template +constexpr auto operator+(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + return rhs + lhs; +} + +constexpr auto decimal32_t::operator++() noexcept -> decimal32_t& +{ + constexpr decimal32_t one(1, 0); + *this = *this + one; + return *this; +} + +constexpr auto decimal32_t::operator++(int) noexcept -> decimal32_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal32_t::operator+=(const decimal32_t rhs) noexcept -> decimal32_t& +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator+=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) +{ + *this = *this + rhs; + return *this; +} + +// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa +constexpr auto operator-(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + // Case from 7.2.d + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return from_bits(detail::d32_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + // a - b = a + (-b) + rhs_components.sign = !rhs_components.sign; + return detail::add_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator-(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + const auto components {lhs.to_components()}; + auto sig_lhs {components.sig}; + auto exp_lhs {components.exp}; + detail::expand_significand(sig_lhs, exp_lhs); + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::add_impl( + detail::decimal32_t_components{sig_lhs, exp_lhs, components.sign}, + detail::decimal32_t_components{final_sig_rhs, exp_rhs, !(rhs < 0)} + ); +} + +template +constexpr auto operator-(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; + + exp_type exp_lhs {0}; + detail::normalize(sig_lhs, exp_lhs); + const auto final_sig_lhs {static_cast(sig_lhs)}; + + const auto components {rhs.to_components()}; + auto sig_rhs {components.sig}; + auto exp_rhs {components.exp}; + detail::expand_significand(sig_rhs, exp_rhs); + + return detail::add_impl( + detail::decimal32_t_components{final_sig_lhs, exp_lhs, (lhs < 0)}, + detail::decimal32_t_components{sig_rhs, exp_rhs, !components.sign} + ); +} + +constexpr auto decimal32_t::operator--() noexcept -> decimal32_t& +{ + constexpr decimal32_t one(1, 0); + *this = *this - one; + return *this; +} + +constexpr auto decimal32_t::operator--(int) noexcept -> decimal32_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +constexpr auto decimal32_t::operator-=(const decimal32_t rhs) noexcept -> decimal32_t& +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator-=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) +{ + *this = *this - rhs; + return *this; +} + +constexpr auto operator==(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + return equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +constexpr auto operator!=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +constexpr auto operator<(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + else if (isfinite(lhs) && isinf(rhs)) + { + return !rhs.isneg(); + } + } + #endif + + return sequential_less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !less_impl(rhs, lhs) && lhs != rhs; +} + +constexpr auto operator<=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + if (isinf(lhs)) + { + return signbit(lhs); + } + if (isinf(rhs)) + { + return !signbit(rhs); + } + } + #endif + + return !sequential_less_impl(rhs, lhs); +} + +template +constexpr auto operator<=(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + if (isnan(lhs)) + { + return false; + } + if (isinf(lhs)) + { + return signbit(lhs); + } + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(rhs)) + { + if (isnan(rhs)) + { + return false; + } + if (isinf(rhs)) + { + return !signbit(rhs); + } + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + if (isinf(lhs)) + { + return !signbit(lhs); + } + if (isinf(rhs)) + { + return signbit(rhs); + } + } + #endif + + return sequential_less_impl(rhs, lhs); +} + +template +constexpr auto operator>(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return rhs < lhs; +} + +template +constexpr auto operator>(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return rhs < lhs; +} + +constexpr auto operator>=(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !sequential_less_impl(lhs, rhs); +} + +template +constexpr auto operator>=(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal32_t lhs, const decimal32_t rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif + +constexpr auto decimal32_t::unbiased_exponent() const noexcept -> exponent_type +{ + exponent_type expval {}; + + if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) + { + expval = (bits_ & detail::d32_11_exp_mask) >> detail::d32_11_exp_shift; + } + else + { + expval = (bits_ & detail::d32_not_11_exp_mask) >> detail::d32_not_11_exp_shift; + } + + return expval; +} + +constexpr auto decimal32_t::biased_exponent() const noexcept -> biased_exponent_type +{ + return static_cast(unbiased_exponent()) - detail::bias; +} + +template +constexpr auto decimal32_t::edit_exponent(T expval) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) +{ + *this = decimal32_t(this->full_significand(), expval, this->isneg()); +} + +constexpr auto decimal32_t::full_significand() const noexcept -> significand_type +{ + significand_type significand {}; + + if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) + { + constexpr std::uint32_t implied_bit {UINT32_C(0x800000)}; + significand = implied_bit | (bits_ & detail::d32_11_significand_mask); + } + else + { + significand = bits_ & detail::d32_not_11_significand_mask; + } + + return significand; +} + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) +#endif + +template +constexpr auto decimal32_t::edit_significand(const T sig) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) +{ + const auto unsigned_sig {detail::make_positive_unsigned(sig)}; + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_signed_v) + { + *this = decimal32_t(unsigned_sig, this->biased_exponent(), this->isneg() || sig < 0); + } + else + { + *this = decimal32_t(unsigned_sig, this->biased_exponent(), this->isneg()); + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +constexpr auto decimal32_t::isneg() const noexcept -> bool +{ + return static_cast(bits_ & detail::d32_sign_mask); +} + +// Allows changing the sign even on nans and infs +constexpr auto decimal32_t::edit_sign(const bool sign) noexcept -> void +{ + if (sign) + { + bits_ |= detail::d32_sign_mask; + } + else + { + bits_ &= ~detail::d32_sign_mask; + } +} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +constexpr auto decimal32_t::to_components() const noexcept -> detail::decimal32_t_components +{ + detail::decimal32_t_components components {}; + + exponent_type expval {}; + significand_type significand {}; + + if ((bits_ & detail::d32_comb_11_mask) == detail::d32_comb_11_mask) + { + constexpr std::uint32_t implied_bit {UINT32_C(0x800000)}; + significand = implied_bit | (bits_ & detail::d32_11_significand_mask); + expval = (bits_ & detail::d32_11_exp_mask) >> detail::d32_11_exp_shift; + } + else + { + significand = bits_ & detail::d32_not_11_significand_mask; + expval = (bits_ & detail::d32_not_11_exp_mask) >> detail::d32_not_11_exp_shift; + } + + components.sig = significand; + components.exp = static_cast(expval) - detail::bias_v; + components.sign = bits_ & detail::d32_sign_mask; + + return components; +} + + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::decimal32_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + *this = boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + *this = boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "Mant: " << components.mantissa + << "\nExp: " << components.exponent + << "\nSign: " << components.sign << std::endl; + #endif + + #ifndef BOOST_DECIMAL_FAST_MATH + if (components.exponent > detail::emax) + { + *this = boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); + } + else + #endif + { + *this = decimal32_t {components.mantissa, components.exponent, components.sign}; + } + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +template +BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal32_t::operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal32_t&) +{ + *this = decimal32_t{val}; + return *this; +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal32_t::decimal32_t(const Decimal val) noexcept +{ + *this = to_decimal(val); +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal32_t::decimal32_t(const Integer val) noexcept : decimal32_t{val, 0}// NOLINT : Incorrect parameter is never used +{ +} + +template +constexpr auto decimal32_t::operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) +{ + using ConversionType = std::conditional_t::value, std::int32_t, Integer>; + *this = decimal32_t{static_cast(val), 0}; + return *this; +} + +constexpr decimal32_t::operator bool() const noexcept +{ + constexpr decimal32_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal32_t::operator int() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator unsigned() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator unsigned long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator long long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator unsigned long long() const noexcept +{ + return to_integral(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal32_t::operator detail::builtin_int128_t() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal32_t::operator detail::builtin_uint128_t() const noexcept +{ + return to_integral(*this); +} + +#endif + +template , bool>> +constexpr decimal32_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR auto to_bits(const decimal32_t rhs) noexcept -> std::uint32_t +{ + const auto bits {detail::bit_cast(rhs.bits_)}; + return bits; +} + +constexpr auto operator*(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return from_bits(detail::d32_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + const auto lhs_components {lhs.to_components()}; + const auto rhs_components {rhs.to_components()}; + + return detail::mul_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator*(const decimal32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_lhs {lhs.full_significand()}; + auto exp_lhs {lhs.biased_exponent()}; + detail::expand_significand(sig_lhs, exp_lhs); + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::mul_impl(sig_lhs, exp_lhs, lhs.isneg(), + final_sig_rhs, exp_rhs, (rhs < 0)); +} + +template +constexpr auto operator*(const Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + return rhs * lhs; +} + +constexpr auto decimal32_t::operator*=(const decimal32_t rhs) noexcept -> decimal32_t& +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator*=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) +{ + *this = *this * rhs; + return *this; +} + +constexpr auto div_impl(const decimal32_t lhs, const decimal32_t rhs, decimal32_t& q, decimal32_t& r) noexcept -> void +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal32_t zero {0, 0}; + constexpr decimal32_t nan {from_bits(detail::d32_nan_mask)}; + constexpr decimal32_t inf {from_bits(detail::d32_inf_mask)}; + + const bool sign {lhs.isneg() != rhs.isneg()}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal32_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + #else + static_cast(r); + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "sig lhs: " << sig_lhs + << "\nexp lhs: " << exp_lhs + << "\nsig rhs: " << sig_rhs + << "\nexp rhs: " << exp_rhs << std::endl; + #endif + + q = detail::generic_div_impl(lhs_components, rhs_components); +} + +constexpr auto mod_impl(const decimal32_t lhs, const decimal32_t rhs, const decimal32_t& q, decimal32_t& r) noexcept -> void +{ + constexpr decimal32_t zero {0, 0}; + + // https://en.cppreference.com/w/cpp/numeric/math/fmod + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator/(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + decimal32_t q {}; + decimal32_t r {}; + div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using exp_type = decimal32_t::biased_exponent_type; + using sig_type = decimal32_t::significand_type; + using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal32_t zero {0, 0}; + constexpr decimal32_t inf {boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask)}; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + auto sig_lhs {lhs.full_significand()}; + auto exp_lhs {lhs.biased_exponent()}; + detail::expand_significand(sig_lhs, exp_lhs); + detail::decimal32_t_components lhs_components {sig_lhs, exp_lhs, lhs.isneg()}; + + exp_type exp_rhs {}; + auto unsigned_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + detail::normalize(unsigned_rhs, exp_rhs); + detail::decimal32_t_components rhs_components {static_cast(unsigned_rhs), exp_rhs, rhs < 0}; + + return detail::generic_div_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator/(Integer lhs, const decimal32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t) +{ + using exp_type = decimal32_t::biased_exponent_type; + using sig_type = decimal32_t::significand_type; + using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal32_t zero {0, 0}; + constexpr decimal32_t inf {boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask)}; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return detail::check_non_finite(rhs); + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + auto sig_rhs {rhs.full_significand()}; + auto exp_rhs {rhs.biased_exponent()}; + detail::expand_significand(sig_rhs, exp_rhs); + + exp_type lhs_exp {}; + auto unsigned_lhs {static_cast(detail::make_positive_unsigned(lhs))}; + detail::normalize(unsigned_lhs, lhs_exp); + detail::decimal32_t_components lhs_components {static_cast(unsigned_lhs), lhs_exp, lhs < 0}; + detail::decimal32_t_components rhs_components {sig_rhs, exp_rhs, rhs.isneg()}; + + return detail::generic_div_impl(lhs_components, rhs_components); +} + +constexpr auto decimal32_t::operator/=(const decimal32_t rhs) noexcept -> decimal32_t& +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32_t&) +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal32_t::operator/=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal32_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto operator%(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + decimal32_t q {}; + decimal32_t r {}; + div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal32_t::operator%=(const decimal32_t rhs) noexcept -> decimal32_t& +{ + *this = *this % rhs; + return *this; +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::operator long double() const noexcept +{ + // Double already has more range and precision than a decimal32_t will ever be able to provide + return static_cast(to_float(*this)); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal32_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal32_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal32_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal32_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +// 3.6.4 +// Effects: determines if the quantum exponents of x and y are the same. +// If both x and y are NaN, or infinity, they have the same quantum exponents; +// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. +// The samequantum functions raise no exception. +constexpr auto samequantumd32(const decimal32_t lhs, const decimal32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) + { + return true; + } + if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) + { + return false; + } + #endif + + return lhs.unbiased_exponent() == rhs.unbiased_exponent(); +} + +// 3.6.5 +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd32(const decimal32_t x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +// 3.6.6 +// Returns: a number that is equal in value (except for any rounding) and sign to x, +// and which has an exponent set to be equal to the exponent of y. +// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; +// if the result does not have the same value as x, the "inexact" floating-point exception is raised. +// If the exponent is being decreased and the significand of the result has more digits than the type would allow, +// the "invalid" floating-point exception is raised and the result is NaN. +// If one or both operands are NaN the result is NaN. +// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. +// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. +// The quantize functions do not signal underflow. +constexpr auto quantized32(const decimal32_t lhs, const decimal32_t rhs) noexcept -> decimal32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Return the correct type of nan + if (isnan(lhs)) + { + return lhs; + } + if (isnan(rhs)) + { + return rhs; + } + + // If one is infinity then return a signaling NAN + if (isinf(lhs) != isinf(rhs)) + { + return from_bits(detail::d32_snan_mask); + } + if (isinf(lhs) && isinf(rhs)) + { + return lhs; + } + #endif + + return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; +} + +constexpr auto scalblnd32(decimal32_t num, const long exp) noexcept -> decimal32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal32_t zero {0, 0}; + + if (num == zero || exp == 0 || !isfinite(num)) + { + return num; + } + #endif + + num.edit_exponent(num.biased_exponent() + exp); + + return num; +} + +constexpr auto scalbnd32(const decimal32_t num, const int expval) noexcept -> decimal32_t +{ + return scalblnd32(num, static_cast(expval)); +} + +constexpr auto copysignd32(decimal32_t mag, const decimal32_t sgn) noexcept -> decimal32_t +{ + mag.edit_sign(sgn.isneg()); + return mag; +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal32_t::decimal32_t(const char* str, const std::size_t len) +{ + if (str == nullptr || len == 0) + { + bits_ = detail::d32_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal32_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + bits_ = detail::d32_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal32_t::decimal32_t(const char* str) : decimal32_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal32_t::decimal32_t(const std::string& str) : decimal32_t(str.c_str(), str.size()) {} +#else +constexpr decimal32_t::decimal32_t(std::string_view str) : decimal32_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_decimal32_t_HPP diff --git a/include/boost/decimal/decimal64.hpp b/include/boost/decimal/decimal64.hpp deleted file mode 100644 index 9f0d82857..000000000 --- a/include/boost/decimal/decimal64.hpp +++ /dev/null @@ -1,2073 +0,0 @@ -// Copyright 2023 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal64_t_HPP -#define BOOST_DECIMAL_decimal64_t_HPP - -#include -#include -#include -#include -#include -#include "detail/int128.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE - -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) -#include -#include -#endif - -#endif // BOOST_DECIMAL_BUILD_MODULE - -namespace boost { -namespace decimal { -namespace detail { - -// See IEEE 754 section 3.5.2 -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_inf_mask = UINT64_C(0x7800000000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_nan_mask = UINT64_C(0x7C00000000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_snan_mask = UINT64_C(0x7E00000000000000); - -// Comb. Exponent Significand -// s eeeeeeeeee [ttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt] -// s 11 eeeeeeeeee [100t][tttttttttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt] - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_sign_mask = UINT64_C(0b1'00000'00000000'0000000000'0000000000'0000000000'0000000000'0000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_combination_field_mask = UINT64_C(0b0'11'00000000'000'0000000000'0000000000'0000000000'0000000000'0000000000); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_exp_mask = UINT64_C(0b0'11'11111111'000'0000000000'0000000000'0000000000'0000000000'0000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_exp_shift = UINT64_C(53); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_11_exp_mask = UINT64_C(0b0'00'1111111111'0'0000000000'0000000000'0000000000'0000000000'0000000000); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_11_exp_shift = UINT64_C(51); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_significand_mask = UINT64_C(0b0'00'00000000'111'1111111111'1111111111'1111111111'1111111111'1111111111); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_11_significand_mask = UINT64_C(0b0'00'0000000000'1'1111111111'1111111111'1111111111'1111111111'1111111111); - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_biggest_no_combination_significand = d64_not_11_significand_mask; - -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_max_biased_exponent = UINT64_C(767); -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t d64_max_significand_value = UINT64_C(9'999'999'999'999'999); - - -template -constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - -template -constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -} //namespace detail - -#if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wclass-memaccess" -#endif - -BOOST_DECIMAL_EXPORT class decimal64_t final -{ -public: - using significand_type = std::uint64_t; - using exponent_type = std::uint64_t; - using biased_exponent_type = std::int32_t; - -private: - - std::uint64_t bits_ {}; - - // Returns the un-biased (quantum) exponent - constexpr auto unbiased_exponent() const noexcept -> exponent_type; - - // Returns the biased exponent - constexpr auto biased_exponent() const noexcept -> biased_exponent_type; - - // Allows direct editing of the exp - template - constexpr auto edit_exponent(T exp) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); - - // Returns the significand complete with the bits implied from the combination field - constexpr auto full_significand() const noexcept -> significand_type; - constexpr auto isneg() const noexcept -> bool; - constexpr auto edit_sign(bool sign) noexcept -> void; - - constexpr auto to_components() const noexcept -> detail::decimal64_t_components; - - // Attempts conversion to integral type: - // If this is nan sets errno to EINVAL and returns 0 - // If this is not representable sets errno to ERANGE and returns 0 - template - friend constexpr auto to_integral(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - // Debug bit pattern - friend constexpr auto from_bits(std::uint64_t bits) noexcept -> decimal64_t; - friend constexpr auto to_bits(decimal64_t rhs) noexcept -> std::uint64_t; - - // Equality template between any integer type and decimal64_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal64_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - friend constexpr auto d64_div_impl(decimal64_t lhs, decimal64_t rhs, decimal64_t& q, decimal64_t& r) noexcept -> void; - - friend constexpr auto d64_mod_impl(decimal64_t lhs, decimal64_t rhs, const decimal64_t& q, decimal64_t& r) noexcept -> void; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - // Micro-optimization: Nearly every call to isfinite in the basic operators is !isfinite. - // We can super easily combine this into a single operation - friend constexpr auto not_finite(decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; - - template - friend constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; - - friend constexpr auto to_bid_d64(decimal64_t val) noexcept -> std::uint64_t; - - friend constexpr auto from_bid_d64(std::uint64_t bits) noexcept -> decimal64_t; - - template - friend constexpr auto to_dpd_d64(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t); - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - // 3.2.3.1 construct/copy/destroy - constexpr decimal64_t() noexcept = default; - constexpr decimal64_t& operator=(const decimal64_t& rhs) noexcept = default; - constexpr decimal64_t& operator=(decimal64_t&& rhs) noexcept = default; - constexpr decimal64_t(const decimal64_t& rhs) noexcept = default; - constexpr decimal64_t(decimal64_t&& rhs) noexcept = default; - - // 3.2.2.2 Conversion form floating-point type - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - #ifndef BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS - explicit - #endif - BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t(Float val) noexcept; - - template - BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal64_t&); - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - explicit constexpr decimal64_t(Decimal val) noexcept; - - // 3.2.3.3 Conversion from integral type - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - constexpr decimal64_t(Integer val) noexcept; - - template - constexpr auto operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); - - // 3.2.3.4 Conversion to integral type - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator detail::builtin_int128_t() const noexcept; - explicit constexpr operator detail::builtin_uint128_t() const noexcept; - #endif - - - // Conversion to another decimal type - template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> - constexpr operator Decimal() const noexcept; - - template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> - explicit constexpr operator Decimal() const noexcept; - - // 3.2.6 Conversion to a floating-point type - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - // 3.2.5 initialization from coefficient and exponent: - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal64_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal64_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal64_t(bool value) noexcept; - - // cmath functions that are easier as friends - friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; - - // 3.2.7 unary arithmetic operators: - friend constexpr auto operator+(decimal64_t rhs) noexcept -> decimal64_t; - friend constexpr auto operator-(decimal64_t rhs) noexcept -> decimal64_t; - - // 3.2.8 Binary arithmetic operators - friend constexpr auto operator+(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator+(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator+(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator-(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator-(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator-(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator*(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator*(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator*(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator/(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator/(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator/(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator%(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - // 3.2.3.5 Increment and Decrement - constexpr auto operator++() noexcept -> decimal64_t&; - constexpr auto operator++(int) noexcept -> decimal64_t; // NOLINT : C++14 so constexpr implies const - constexpr auto operator--() noexcept -> decimal64_t&; - constexpr auto operator--(int) noexcept -> decimal64_t; // NOLINT : C++14 so constexpr implies const - - // 3.2.3.6 Compound assignment - constexpr auto operator+=(decimal64_t rhs) noexcept -> decimal64_t&; - - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); - - template - constexpr auto operator+=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); - - constexpr auto operator-=(decimal64_t rhs) noexcept -> decimal64_t&; - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); - - template - constexpr auto operator-=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); - - constexpr auto operator*=(decimal64_t rhs) noexcept -> decimal64_t&; - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); - - template - constexpr auto operator*=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); - - constexpr auto operator/=(decimal64_t rhs) noexcept -> decimal64_t&; - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); - - template - constexpr auto operator/=(Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); - - constexpr auto operator%=(decimal64_t rhs) noexcept -> decimal64_t&; - - // 3.2.9 Comparison operators: - // Equality - friend constexpr auto operator==(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator==(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Inequality - friend constexpr auto operator!=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator!=(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less - friend constexpr auto operator<(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator<(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Less equal - friend constexpr auto operator<=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator<=(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater - friend constexpr auto operator>(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator>(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // Greater equal - friend constexpr auto operator>=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - template - friend constexpr auto operator>=(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // C++20 spaceship - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - friend constexpr auto operator<=>(decimal64_t lhs, decimal64_t rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - #endif - - // 3.6.4 Same Quantum - friend constexpr auto samequantumd64(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; - - // 3.6.5 Quantum exponent - friend constexpr auto quantexpd64(decimal64_t x) noexcept -> int; - - // 3.6.6 Quantize - friend constexpr auto quantized64(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - // Bit-wise operators - friend constexpr auto operator&(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator&(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator&(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator|(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator|(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator|(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator^(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator^(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator^(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator<<(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator<<(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator<<(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator>>(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; - - template - friend constexpr auto operator>>(decimal64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - template - friend constexpr auto operator>>(Integer lhs, decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); - - friend constexpr auto operator~(decimal64_t lhs) noexcept -> decimal64_t; - - // functions that need to be friends - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto copysignd64(decimal64_t mag, decimal64_t sgn) noexcept -> decimal64_t; - friend constexpr auto fmad64(decimal64_t x, decimal64_t y, decimal64_t z) noexcept -> decimal64_t; - friend constexpr auto scalbnd64(decimal64_t num, int exp) noexcept -> decimal64_t; - friend constexpr auto scalblnd64(decimal64_t num, long exp) noexcept -> decimal64_t; -}; - -BOOST_DECIMAL_EXPORT using decimal64 [[deprecated("Use re-named type decimal64_t instead of decimal64")]] = decimal64_t; - -#if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic pop -#endif - -constexpr auto from_bits(std::uint64_t bits) noexcept -> decimal64_t -{ - decimal64_t result; - result.bits_ = bits; - - return result; -} - -constexpr auto to_bits(decimal64_t rhs) noexcept -> std::uint64_t -{ - return rhs.bits_; -} - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wduplicated-branches" -# pragma GCC diagnostic ignored "-Wbool-compare" -# pragma GCC diagnostic ignored "-Wconversion" -#endif - -// 3.2.5 initialization from coefficient and exponent: -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal64_t::decimal64_t(T1 coeff, T2 exp, bool sign) noexcept -{ - bits_ = sign ? detail::d64_sign_mask : UINT64_C(0); - - // If the coeff is not in range, make it so - int coeff_digits {-1}; - if (coeff > detail::d64_max_significand_value) - { - coeff_digits = detail::d64_constructor_num_digits(coeff); - if (coeff_digits > detail::precision_v + 1) - { - const auto digits_to_remove {coeff_digits - (detail::precision_v + 1)}; - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic push - # pragma GCC diagnostic ignored "-Wconversion" - #endif - - coeff /= detail::pow10(static_cast(digits_to_remove)); - - #if defined(__GNUC__) && !defined(__clang__) - # pragma GCC diagnostic pop - #endif - - coeff_digits -= digits_to_remove; - exp += detail::fenv_round(coeff, sign) + digits_to_remove; - } - else - { - exp += detail::fenv_round(coeff, sign); - } - } - - auto reduced_coeff {static_cast(coeff)}; - bool big_combination {false}; - - if (reduced_coeff == 0U) - { - // Normalize our handling of zeros - return; - } - - if (reduced_coeff <= detail::d64_biggest_no_combination_significand) - { - // If the coefficient fits directly, we don't need to use the combination field - // bits_.significand = reduced_coeff; - bits_ |= (reduced_coeff & detail::d64_not_11_significand_mask); - } - else - { - // Have to use the full combination field - bits_ |= (detail::d64_combination_field_mask | (reduced_coeff & detail::d64_11_significand_mask)); - big_combination = true; - } - - // If the exponent fits, we do not need to use the combination field - const auto biased_exp {static_cast(exp + detail::bias_v)}; - if (biased_exp <= detail::d64_max_biased_exponent) - { - if (big_combination) - { - bits_ |= (biased_exp << detail::d64_11_exp_shift) & detail::d64_11_exp_mask; - } - else - { - bits_ |= (biased_exp << detail::d64_not_11_exp_shift) & detail::d64_not_11_exp_mask; - } - } - else - { - // If we can fit the extra exponent in the significand, then we can construct the value - // If we can't, the value is either 0 or infinity depending on the sign of exp - - if (coeff_digits == -1) - { - coeff_digits = detail::num_digits(reduced_coeff); - } - - const auto exp_delta {biased_exp - detail::d64_max_biased_exponent}; - const auto digit_delta {coeff_digits - static_cast(exp_delta)}; - if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision_v) - { - exp -= digit_delta; - reduced_coeff *= detail::pow10(static_cast(digit_delta)); - *this = decimal64_t(reduced_coeff, exp, sign); - } - else - { - bits_ = exp < 0 ? UINT64_C(0) : detail::d64_inf_mask; - } - } -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal64_t::decimal64_t(const T1 coeff, const T2 exp) noexcept : decimal64_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -constexpr decimal64_t::decimal64_t(const bool value) noexcept : decimal64_t(static_cast(value), 0, false) {} - - -#if defined(__GNUC__) && __GNUC__ >= 6 -# pragma GCC diagnostic pop -#endif - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::decimal64_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - *this = from_bits(detail::d64_nan_mask); - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - *this = from_bits(detail::d64_inf_mask); - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "Mant: " << components.mantissa - << "\nExp: " << components.exponent - << "\nSign: " << components.sign << std::endl; - #endif - - if (components.exponent > detail::emax_v) - { - *this = from_bits(detail::d64_inf_mask); - } - else - { - *this = decimal64_t {components.mantissa, components.exponent, components.sign}; - } - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -template -BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal64_t::operator=(const Float& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal64_t&) -{ - *this = decimal64_t{val}; - return *this; -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal64_t::decimal64_t(const Decimal val) noexcept -{ - *this = to_decimal(val); -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal64_t::decimal64_t(const Integer val) noexcept : decimal64_t{val, 0} {} - -template -constexpr auto decimal64_t::operator=(const Integer& val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) -{ - using ConversionType = std::conditional_t::value, std::int32_t, Integer>; - *this = decimal64_t{static_cast(val), 0}; - return *this; -} - -constexpr decimal64_t::operator bool() const noexcept -{ - constexpr decimal64_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal64_t::operator int() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator unsigned() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator unsigned long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator long long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator unsigned long long() const noexcept -{ - return to_integral(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal64_t::operator detail::builtin_int128_t() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal64_t::operator detail::builtin_uint128_t() const noexcept -{ - return to_integral(*this); -} - -#endif - -template && (detail::decimal_val_v > detail::decimal_val_v), bool>> -constexpr decimal64_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> -constexpr decimal64_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator long double() const noexcept -{ - return to_float(*this); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal64_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal64_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal64_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal64_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -constexpr auto decimal64_t::unbiased_exponent() const noexcept -> exponent_type -{ - exponent_type expval {}; - - if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) - { - expval = (bits_ & detail::d64_11_exp_mask) >> detail::d64_11_exp_shift; - } - else - { - expval = (bits_ & detail::d64_not_11_exp_mask) >> detail::d64_not_11_exp_shift; - } - - return expval; -} - -constexpr auto decimal64_t::biased_exponent() const noexcept -> biased_exponent_type -{ - return static_cast(unbiased_exponent()) - detail::bias_v; -} - -constexpr auto decimal64_t::full_significand() const noexcept -> significand_type -{ - significand_type significand {}; - - if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) - { - constexpr std::uint64_t implied_bit {UINT64_C(0b1000'0000000000'0000000000'0000000000'0000000000'0000000000)}; - significand = implied_bit | (bits_ & detail::d64_11_significand_mask); - } - else - { - significand = bits_ & detail::d64_not_11_significand_mask; - } - - return significand; -} - -constexpr auto decimal64_t::isneg() const noexcept -> bool -{ - return static_cast(bits_ & detail::d64_sign_mask); -} - -constexpr auto decimal64_t::to_components() const noexcept -> detail::decimal64_t_components -{ - detail::decimal64_t_components components {}; - - exponent_type expval {}; - significand_type significand {}; - - if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) - { - constexpr std::uint64_t implied_bit {UINT64_C(0b1000'0000000000'0000000000'0000000000'0000000000'0000000000)}; - significand = implied_bit | (bits_ & detail::d64_11_significand_mask); - expval = (bits_ & detail::d64_11_exp_mask) >> detail::d64_11_exp_shift; - } - else - { - significand = bits_ & detail::d64_not_11_significand_mask; - expval = (bits_ & detail::d64_not_11_exp_mask) >> detail::d64_not_11_exp_shift; - } - - components.sig = significand; - components.exp = static_cast(expval) - detail::bias_v; - components.sign = bits_ & detail::d64_sign_mask; - - return components; -} - -template -constexpr auto decimal64_t::edit_exponent(const T expval) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) -{ - *this = decimal64_t(this->full_significand(), expval, this->isneg()); -} - -constexpr auto decimal64_t::edit_sign(const bool sign) noexcept -> void -{ - if (sign) - { - bits_ |= detail::d64_sign_mask; - } - else - { - bits_ &= ~detail::d64_sign_mask; - } -} - -constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - return rhs.bits_ & detail::d64_sign_mask; -} - -constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_ & detail::d64_nan_mask) == detail::d64_nan_mask; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return ((rhs.bits_ & detail::d64_nan_mask) == detail::d64_inf_mask); - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return (rhs.bits_ & detail::d64_snan_mask) == detail::d64_snan_mask; - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Check for de-normals - const auto sig {rhs.full_significand()}; - const auto exp {rhs.unbiased_exponent()}; - - if (exp <= detail::precision_v - 1) - { - return false; - } - - return (sig != 0) && isfinite(rhs); - #else - return rhs.full_significand() != 0; - #endif -} - -constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return ((rhs.bits_ & detail::d64_inf_mask) != detail::d64_inf_mask); - #else - static_cast(rhs); - return true; - #endif -} - -BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return ((rhs.bits_ & detail::d64_inf_mask) == detail::d64_inf_mask); - #else - static_cast(rhs); - return false; - #endif -} - -constexpr auto operator+(const decimal64_t rhs) noexcept -> decimal64_t -{ - return rhs; -} - -constexpr auto operator-(decimal64_t rhs) noexcept-> decimal64_t -{ - rhs.bits_ ^= detail::d64_sign_mask; - return rhs; -} - -constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decimal64_t& q, decimal64_t& r) noexcept -> void -{ - const bool sign {lhs.isneg() != rhs.isneg()}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal64_t zero {0, 0}; - constexpr decimal64_t nan {boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask)}; - constexpr decimal64_t inf {boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask)}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - - #else - static_cast(r); - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - q = detail::d64_generic_div_impl(lhs_components, rhs.to_components(), sign); -} - -constexpr auto d64_mod_impl(const decimal64_t lhs, const decimal64_t rhs, const decimal64_t& q, decimal64_t& r) noexcept -> void -{ - constexpr decimal64_t zero {0, 0}; - - // https://en.cppreference.com/w/cpp/numeric/math/fmod - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal64_t(q_trunc) * rhs); -} - -constexpr auto operator+(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - - return detail::d64_add_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator+(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::d64_add_impl(sig_lhs, exp_lhs, lhs.isneg(), - final_sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator+(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return rhs + lhs; -} - -// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa -constexpr auto operator-(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - rhs_components.sign = !rhs_components.sign; - - return detail::d64_add_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator-(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - const bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - auto sig_lhs {lhs.full_significand()}; - auto exp_lhs {lhs.biased_exponent()}; - detail::normalize(sig_lhs, exp_lhs); - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::d64_add_impl(sig_lhs, exp_lhs, lhs.isneg(), - final_sig_rhs, exp_rhs, !(rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator-(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - const bool abs_lhs_bigger {sig_lhs > abs(rhs)}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - const auto final_sig_lhs {static_cast(detail::make_positive_unsigned(sig_lhs))}; - - auto sig_rhs {rhs.full_significand()}; - auto exp_rhs {rhs.biased_exponent()}; - detail::normalize(sig_rhs, exp_rhs); - - return detail::d64_add_impl(final_sig_lhs, exp_lhs, (lhs < 0), - sig_rhs, exp_rhs, !rhs.isneg(), - abs_lhs_bigger); -} - -constexpr auto operator*(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - auto lhs_components {lhs.to_components()}; - detail::normalize(lhs_components.sig, lhs_components.exp); - auto rhs_components {rhs.to_components()}; - detail::normalize(rhs_components.sig, rhs_components.exp); - - return detail::d64_mul_impl(lhs_components, rhs_components); -} - -template -constexpr auto operator*(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto lhs_sig {lhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - detail::normalize(lhs_sig, lhs_exp); - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type rhs_exp {0}; - detail::normalize(rhs_sig, rhs_exp); - const auto final_rhs_sig {static_cast(rhs_sig)}; - - return detail::d64_mul_impl(lhs_sig, lhs_exp, lhs.isneg(), - final_rhs_sig, rhs_exp, (rhs < 0)); -} - -template -constexpr auto operator*(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return rhs * lhs; -} - -constexpr auto operator/(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - decimal64_t q {}; - decimal64_t r {}; - d64_div_impl(lhs, rhs, q, r); - - return q; -} - -template -constexpr auto operator/(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using sig_type = decimal64_t::significand_type; - using exp_type = decimal64_t::biased_exponent_type; - using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal64_t zero {0, 0}; - constexpr decimal64_t nan {boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask)}; - constexpr decimal64_t inf {boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - auto lhs_sig {lhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - detail::normalize(lhs_sig, lhs_exp); - detail::decimal64_t_components lhs_components {lhs_sig, lhs_exp, lhs.isneg()}; - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type rhs_exp {}; - detail::normalize(rhs_sig, rhs_exp); - detail::decimal64_t_components rhs_components {static_cast(rhs_sig), rhs_exp, rhs < 0}; - - return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); -} - -template -constexpr auto operator/(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - using sig_type = decimal64_t::significand_type; - using exp_type = decimal64_t::biased_exponent_type; - using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal64_t zero {0, 0}; - constexpr decimal64_t inf {boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask)}; - constexpr decimal64_t nan {boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask)}; - - const auto rhs_fp {fpclassify(rhs)}; - - if (rhs_fp == FP_NAN) - { - return nan; - } - - switch (rhs_fp) - { - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - auto rhs_sig {rhs.full_significand()}; - auto rhs_exp {rhs.biased_exponent()}; - detail::normalize(rhs_sig, rhs_exp); - - exp_type lhs_exp {}; - auto lhs_sig {static_cast(detail::make_positive_unsigned(lhs))}; - detail::normalize(lhs_sig, lhs_exp); - detail::decimal64_t_components lhs_components {static_cast(lhs_sig), lhs_exp, lhs < 0}; - detail::decimal64_t_components rhs_components {rhs_sig, rhs_exp, rhs.isneg()}; - - return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); -} - -constexpr auto operator%(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - decimal64_t q {}; - decimal64_t r {}; - d64_div_impl(lhs, rhs, q, r); - d64_mod_impl(lhs, rhs, q, r); - - return r; -} - -constexpr auto decimal64_t::operator++() noexcept -> decimal64_t& -{ - constexpr decimal64_t one{1, 0}; - *this = *this + one; - return *this; -} - -constexpr auto decimal64_t::operator++(int) noexcept -> decimal64_t -{ - return ++(*this); -} - -constexpr auto decimal64_t::operator--() noexcept -> decimal64_t& -{ - constexpr decimal64_t one{1, 0}; - *this = *this - one; - return *this; -} - -constexpr auto decimal64_t::operator--(int) noexcept -> decimal64_t -{ - return --(*this); -} - -constexpr auto decimal64_t::operator+=(const decimal64_t rhs) noexcept -> decimal64_t& -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator+=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) -{ - *this = *this + rhs; - return *this; -} - -constexpr auto decimal64_t::operator-=(const decimal64_t rhs) noexcept -> decimal64_t& -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator-=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) -{ - *this = *this - rhs; - return *this; -} - -constexpr auto decimal64_t::operator*=(const decimal64_t rhs) noexcept -> decimal64_t& -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator*=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) -{ - *this = *this * rhs; - return *this; -} - -constexpr auto decimal64_t::operator/=(const decimal64_t rhs) noexcept -> decimal64_t& -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal64_t::operator/=(const Decimal rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr auto decimal64_t::operator%=(const decimal64_t rhs) noexcept -> decimal64_t& -{ - *this = *this % rhs; - return *this; -} - -constexpr auto operator==(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - return equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -constexpr auto operator!=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -constexpr auto operator<(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - if (isnan(lhs) || isnan(rhs) || - (!lhs.isneg() && rhs.isneg())) - { - return false; - } - if (lhs.isneg() && !rhs.isneg()) - { - return true; - } - if (isfinite(lhs) && isinf(rhs)) - { - return !rhs.isneg(); - } - } - #endif - - return sequential_less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !less_impl(rhs, lhs) && lhs != rhs; -} - -constexpr auto operator<=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -constexpr auto operator>=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal64_t lhs, const decimal64_t rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif - -constexpr auto operator&(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - return from_bits(lhs.bits_ & rhs.bits_); -} - -template -constexpr auto operator&(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(lhs.bits_ & static_cast(rhs)); -} - -template -constexpr auto operator&(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(static_cast(lhs) & rhs.bits_); -} - -constexpr auto operator|(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - return from_bits(lhs.bits_ | rhs.bits_); -} - -template -constexpr auto operator|(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(lhs.bits_ | static_cast(rhs)); -} - -template -constexpr auto operator|(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(static_cast(lhs) | rhs.bits_); -} - -constexpr auto operator^(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - return from_bits(lhs.bits_ ^ rhs.bits_); -} - -template -constexpr auto operator^(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(lhs.bits_ ^ static_cast(rhs)); -} - -template -constexpr auto operator^(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(static_cast(lhs) ^ rhs.bits_); -} - -constexpr auto operator<<(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - return from_bits(lhs.bits_ << rhs.bits_); -} - -template -constexpr auto operator<<(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(lhs.bits_ << static_cast(rhs)); -} - -template -constexpr auto operator<<(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(static_cast(lhs) << rhs.bits_); -} - -constexpr auto operator>>(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - return from_bits(lhs.bits_ >> rhs.bits_); -} - -template -constexpr auto operator>>(const decimal64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(lhs.bits_ >> static_cast(rhs)); -} - -template -constexpr auto operator>>(const Integer lhs, const decimal64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) -{ - return from_bits(static_cast(lhs) >> rhs.bits_); -} - -constexpr auto operator~(decimal64_t lhs) noexcept -> decimal64_t -{ - return from_bits(~lhs.bits_); -} - -// 3.6.4 -// Effects: determines if the quantum exponents of x and y are the same. -// If both x and y are NaN, or infinity, they have the same quantum exponents; -// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. -// The samequantum functions raise no exception. -constexpr auto samequantumd64(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) - { - return true; - } - if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) - { - return false; - } - #endif - - return lhs.unbiased_exponent() == rhs.unbiased_exponent(); -} - -// 3.6.5 -// Effects: if x is finite, returns its quantum exponent. -// Otherwise, a domain error occurs and INT_MIN is returned. -constexpr auto quantexpd64(const decimal64_t x) noexcept -> int -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(x)) - { - return INT_MIN; - } - #endif - - return static_cast(x.unbiased_exponent()); -} - -// 3.6.6 -// Returns: a number that is equal in value (except for any rounding) and sign to x, -// and which has an exponent set to be equal to the exponent of y. -// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; -// if the result does not have the same value as x, the "inexact" floating-point exception is raised. -// If the exponent is being decreased and the significand of the result has more digits than the type would allow, -// the "invalid" floating-point exception is raised and the result is NaN. -// If one or both operands are NaN the result is NaN. -// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. -// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. -// The quantize functions do not signal underflow. -constexpr auto quantized64(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - // Return the correct type of nan - if (isnan(lhs)) - { - return lhs; - } - if (isnan(rhs)) - { - return rhs; - } - - // If one is infinity then return a signaling NAN - if (isinf(lhs) != isinf(rhs)) - { - return boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask); - } - if (isinf(lhs) && isinf(rhs)) - { - return lhs; - } - #endif - - return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; -} - -constexpr auto scalblnd64(decimal64_t num, const long exp) noexcept -> decimal64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal64_t zero {0, 0}; - - if (num == zero || exp == 0 || not_finite(num)) - { - return num; - } - #endif - - num.edit_exponent(num.biased_exponent() + exp); - - return num; -} - -constexpr auto scalbnd64(const decimal64_t num, const int expval) noexcept -> decimal64_t -{ - return scalblnd64(num, static_cast(expval)); -} - -constexpr auto copysignd64(decimal64_t mag, const decimal64_t sgn) noexcept -> decimal64_t -{ - mag.edit_sign(sgn.isneg()); - return mag; -} - -} //namespace decimal -} //namespace boost - -namespace std { - -template <> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ - -#ifdef _MSC_VER - public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_present; - static constexpr bool has_denorm_loss = true; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = true; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 16; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -383; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 384; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal64_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal64_t { return {boost::decimal::detail::d64_max_significand_value, max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal64_t { return {boost::decimal::detail::d64_max_significand_value, max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal64_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal64_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_nan_mask); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask); } - static constexpr auto denorm_min () -> boost::decimal::decimal64_t { return {1, boost::decimal::detail::etiny_v}; } -}; - -} // Namespace std - -#endif //BOOST_DECIMAL_decimal64_t_HPP diff --git a/include/boost/decimal/decimal64_fast.hpp b/include/boost/decimal/decimal64_fast.hpp deleted file mode 100644 index 483cc3966..000000000 --- a/include/boost/decimal/decimal64_fast.hpp +++ /dev/null @@ -1,1406 +0,0 @@ -// Copyright 2023 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_decimal_fast64_t_HPP -#define BOOST_DECIMAL_decimal_fast64_t_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BOOST_DECIMAL_BUILD_MODULE - -#include -#include - -#endif - -namespace boost { -namespace decimal { - -namespace detail { - -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_inf = std::numeric_limits::max() - 3; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_qnan = std::numeric_limits::max() - 2; -BOOST_DECIMAL_CONSTEXPR_VARIABLE auto d64_fast_snan = std::numeric_limits::max() - 1; - -} // namespace detail - -BOOST_DECIMAL_EXPORT class decimal_fast64_t final -{ -public: - using significand_type = std::uint64_t; - using exponent_type = std::uint16_t; - using biased_exponent_type = std::int32_t; - -private: - // In regular decimal64_t we have to decode the significand end exponent - // Here we will store them directly to avoid the overhead of decoding - - significand_type significand_ {}; - exponent_type exponent_ {}; - bool sign_ {}; - - constexpr auto isneg() const noexcept -> bool - { - return sign_; - } - - constexpr auto full_significand() const noexcept -> significand_type - { - return significand_; - } - - constexpr auto unbiased_exponent() const noexcept -> exponent_type - { - return exponent_; - } - - constexpr auto biased_exponent() const noexcept -> biased_exponent_type - { - return static_cast(exponent_) - detail::bias_v; - } - - constexpr auto to_components() const noexcept -> detail::decimal_fast64_t_components - { - return {full_significand(), biased_exponent(), isneg()}; - } - - // Equality template between any integer type and decimal32_t - template - friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - // Template to compare operator< for any integer type and decimal32_t - template - friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; - - template - friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept - -> std::enable_if_t<(detail::is_decimal_floating_point_v && - detail::is_decimal_floating_point_v), bool>; - - template - friend constexpr auto to_integral(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); - - template - friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept - BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); - - template - friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; - - friend constexpr auto d64_fast_div_impl(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs, decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void; - - template - friend constexpr auto ilogb(T d) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); - - template - friend constexpr auto logb(T num) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); - - friend constexpr auto not_finite(decimal_fast64_t val) noexcept -> bool; - - template - friend constexpr auto to_dpd_d64(DecimalType val) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t); - - template - friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_equal_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; - - template - friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; - - template - friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; - - template - friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; - -public: - constexpr decimal_fast64_t() noexcept = default; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal_fast64_t(T1 coeff, T2 exp, bool sign = false) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template && detail::is_integral_v, bool> = true> - #endif - constexpr decimal_fast64_t(T1 coeff, T2 exp) noexcept; - - explicit constexpr decimal_fast64_t(bool value) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - constexpr decimal_fast64_t(Integer val) noexcept; - - #ifdef BOOST_DECIMAL_HAS_CONCEPTS - template - #else - template , bool> = true> - #endif - explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t(Float val) noexcept; - - friend constexpr auto direct_init_d64(decimal_fast64_t::significand_type significand, decimal_fast64_t::exponent_type exponent, bool sign) noexcept -> decimal_fast64_t; - - // Classification functions - friend constexpr auto signbit(decimal_fast64_t val) noexcept -> bool; - friend constexpr auto isinf(decimal_fast64_t val) noexcept -> bool; - friend constexpr auto isnan(decimal_fast64_t val) noexcept -> bool; - friend constexpr auto issignaling(decimal_fast64_t val) noexcept -> bool; - friend constexpr auto isnormal(decimal_fast64_t val) noexcept -> bool; - friend constexpr auto isfinite(decimal_fast64_t val) noexcept -> bool; - - // Comparison operator - friend constexpr auto operator==(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - friend constexpr auto operator!=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - friend constexpr auto operator<(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - friend constexpr auto operator<=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - friend constexpr auto operator>(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - friend constexpr auto operator>=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; - - // Mixed type comparison operators - template - friend constexpr auto operator==(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator==(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator!=(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator<=(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - template - friend constexpr auto operator>=(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); - - // C++20 Spaceship operator - #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - friend constexpr auto operator<=>(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> std::partial_ordering; - - template - friend constexpr auto operator<=>(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - - template - friend constexpr auto operator<=>(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); - #endif - - // Conversions - explicit constexpr operator bool() const noexcept; - explicit constexpr operator int() const noexcept; - explicit constexpr operator unsigned() const noexcept; - explicit constexpr operator long() const noexcept; - explicit constexpr operator unsigned long() const noexcept; - explicit constexpr operator long long() const noexcept; - explicit constexpr operator unsigned long long() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_INT128 - explicit constexpr operator detail::builtin_int128_t() const noexcept; - explicit constexpr operator detail::builtin_uint128_t() const noexcept; - #endif - - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; - explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; - - #ifdef BOOST_DECIMAL_HAS_FLOAT16 - explicit constexpr operator std::float16_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT32 - explicit constexpr operator std::float32_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT64 - explicit constexpr operator std::float64_t() const noexcept; - #endif - #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 - explicit constexpr operator std::bfloat16_t() const noexcept; - #endif - - // Conversion to other decimal type - template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> - constexpr operator Decimal() const noexcept; - - template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> - explicit constexpr operator Decimal() const noexcept; - - // Unary Operators - friend constexpr auto operator+(decimal_fast64_t val) noexcept -> decimal_fast64_t; - friend constexpr auto operator-(decimal_fast64_t val) noexcept -> decimal_fast64_t; - - // Basic arithmetic operators - friend constexpr auto operator+(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; - friend constexpr auto operator-(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; - friend constexpr auto operator*(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; - friend constexpr auto operator/(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs) noexcept -> decimal_fast64_t; - friend constexpr auto operator%(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; - - // Mixed type arithmetic operators - template - friend constexpr auto operator+(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator+(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator-(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator-(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator*(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator*(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator/(decimal_fast64_t lhs, Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - template - friend constexpr auto operator/(Integer lhs, decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); - - // Compound Operators - constexpr auto operator+=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; - constexpr auto operator-=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; - constexpr auto operator*=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; - constexpr auto operator/=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; - - // Mixed type compound operators - template - constexpr auto operator+=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); - - template - constexpr auto operator-=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); - - template - constexpr auto operator*=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); - - template - constexpr auto operator/=(Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); - - // Increment and decrement - constexpr auto operator++() noexcept -> decimal_fast64_t&; - constexpr auto operator++(int) noexcept -> decimal_fast64_t&; - constexpr auto operator--() noexcept -> decimal_fast64_t&; - constexpr auto operator--(int) noexcept -> decimal_fast64_t&; - - // Cmath friend functions - template - friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; - - friend constexpr auto copysignd64f(decimal_fast64_t mag, decimal_fast64_t sgn) noexcept -> decimal_fast64_t; - friend constexpr auto fmad64f(decimal_fast64_t x, decimal_fast64_t y, decimal_fast64_t z) noexcept -> decimal_fast64_t; - friend constexpr auto scalbnd64f(decimal_fast64_t num, int exp) noexcept -> decimal_fast64_t; - friend constexpr auto scalblnd64f(decimal_fast64_t num, long exp) noexcept -> decimal_fast64_t; -}; - -BOOST_DECIMAL_EXPORT using decimal64_fast [[deprecated("Use re-named type decimal_fast64_t instead of decimal64_fast")]] = decimal_fast64_t; - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal_fast64_t::decimal_fast64_t(T1 coeff, T2 exp, bool sign) noexcept -{ - using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; - - minimum_coefficient_size min_coeff {coeff}; - - sign_ = sign; - - // Normalize the value, so we don't have to worry about it with operations - detail::normalize(min_coeff, exp, sign); - - significand_ = static_cast(min_coeff); - - const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias_v}; - - if (biased_exp > detail::max_biased_exp_v) - { - significand_ = detail::d64_fast_inf; - } - else if (biased_exp >= 0) - { - exponent_ = static_cast(biased_exp); - } - else - { - // Flush denorms to zero - significand_ = static_cast(0); - exponent_ = static_cast(detail::bias_v); - sign_ = false; - } -} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template && detail::is_integral_v, bool>> -#endif -constexpr decimal_fast64_t::decimal_fast64_t(const T1 coeff, const T2 exp) noexcept : decimal_fast64_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} - -constexpr decimal_fast64_t::decimal_fast64_t(const bool value) noexcept : decimal_fast64_t(static_cast(value), 0, false) {} - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -constexpr decimal_fast64_t::decimal_fast64_t(const Integer val) noexcept : decimal_fast64_t{val, 0} {} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wfloat-equal" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -#ifdef BOOST_DECIMAL_HAS_CONCEPTS -template -#else -template , bool>> -#endif -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::decimal_fast64_t(const Float val) noexcept -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val != val) - { - significand_ = detail::d64_fast_qnan; - } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) - { - significand_ = detail::d64_fast_inf; - } - else - #endif - { - const auto components {detail::ryu::floating_point_to_fd128(val)}; - *this = decimal_fast64_t {components.mantissa, components.exponent, components.sign}; - } -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#endif - -constexpr auto direct_init_d64(const decimal_fast64_t::significand_type significand, - const decimal_fast64_t::exponent_type exponent, - const bool sign) noexcept -> decimal_fast64_t -{ - decimal_fast64_t val {}; - val.significand_ = significand; - val.exponent_ = exponent; - val.sign_ = sign; - - return val; -} - -constexpr auto signbit(const decimal_fast64_t val) noexcept -> bool -{ - return val.sign_; -} - -constexpr auto isinf(const decimal_fast64_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ == detail::d64_fast_inf; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnan(const decimal_fast64_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ >= detail::d64_fast_qnan; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto issignaling(const decimal_fast64_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - return val.significand_ == detail::d64_fast_snan; - #else - static_cast(val); - return false; - #endif -} - -constexpr auto isnormal(const decimal_fast64_t val) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (val.exponent_ <= static_cast(detail::precision_v - 1)) - { - return false; - } - - return (val.significand_ != 0) && isfinite(val); - #else - return val.significand_ != 0; - #endif -} - -constexpr auto isfinite(const decimal_fast64_t val) noexcept -> bool -{ - return val.significand_ < detail::d64_fast_inf; -} - -BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast64_t val) noexcept -> bool -{ - return val.significand_ >= detail::d64_fast_inf; -} - -constexpr auto operator==(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - return fast_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(lhs, rhs); -} - -template -constexpr auto operator==(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return mixed_equality_impl(rhs, lhs); -} - -constexpr auto operator!=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - return fast_inequality_impl(lhs, rhs); -} - -template -constexpr auto operator!=(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -template -constexpr auto operator!=(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return !(lhs == rhs); -} - -constexpr auto operator<(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - return fast_less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return less_impl(lhs, rhs); -} - -template -constexpr auto operator<(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !less_impl(rhs, lhs) && lhs != rhs; -} - -constexpr auto operator<=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -template -constexpr auto operator<=(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(rhs < lhs); -} - -constexpr auto operator>(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -template -constexpr auto operator>(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - return rhs < lhs; -} - -constexpr auto operator>=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs) || isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(lhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -template -constexpr auto operator>=(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (isnan(rhs)) - { - return false; - } - #endif - - return !(lhs < rhs); -} - -#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator<=>(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> std::partial_ordering -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -template -constexpr auto operator<=>(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) -{ - if (lhs < rhs) - { - return std::partial_ordering::less; - } - else if (lhs > rhs) - { - return std::partial_ordering::greater; - } - else if (lhs == rhs) - { - return std::partial_ordering::equivalent; - } - - return std::partial_ordering::unordered; -} - -#endif // BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR - -constexpr auto operator+(const decimal_fast64_t val) noexcept -> decimal_fast64_t -{ - return val; -} - -constexpr auto operator-(decimal_fast64_t val) noexcept -> decimal_fast64_t -{ - val.sign_ = !val.sign_; - return val; -} - -constexpr decimal_fast64_t::operator bool() const noexcept -{ - constexpr decimal_fast64_t zero {0, 0}; - return *this != zero; -} - -constexpr decimal_fast64_t::operator int() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator unsigned() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator unsigned long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator long long() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator unsigned long long() const noexcept -{ - return to_integral(*this); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 - -constexpr decimal_fast64_t::operator detail::builtin_int128_t() const noexcept -{ - return to_integral(*this); -} - -constexpr decimal_fast64_t::operator detail::builtin_uint128_t() const noexcept -{ - return to_integral(*this); -} - -#endif // BOOST_DECIMAL_HAS_INT128 - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator float() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator double() const noexcept -{ - return to_float(*this); -} - -BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator long double() const noexcept -{ - return to_float(*this); -} - -#ifdef BOOST_DECIMAL_HAS_FLOAT16 -constexpr decimal_fast64_t::operator std::float16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT32 -constexpr decimal_fast64_t::operator std::float32_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_FLOAT64 -constexpr decimal_fast64_t::operator std::float64_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif -#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 -constexpr decimal_fast64_t::operator std::bfloat16_t() const noexcept -{ - return static_cast(to_float(*this)); -} -#endif - -template && (detail::decimal_val_v > detail::decimal_val_v), bool>> -constexpr decimal_fast64_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> -constexpr decimal_fast64_t::operator Decimal() const noexcept -{ - return to_decimal(*this); -} - -constexpr auto operator+(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d64_add_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs.significand_, rhs.biased_exponent(), rhs.sign_, - (abs(lhs) > abs(rhs))); -} - -template -constexpr auto operator+(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - const bool abs_lhs_bigger {abs(lhs) > sig_rhs}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::d64_add_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_sig_rhs, exp_rhs, (rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator+(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - return rhs + lhs; -} - -constexpr auto operator-(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d64_add_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - rhs.significand_, rhs.biased_exponent(), !rhs.sign_, - abs(lhs) > abs(rhs) - ); -} - -template -constexpr auto operator-(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; - const bool abs_lhs_bigger {abs(lhs) > detail::make_positive_unsigned(rhs)}; - - exp_type exp_rhs {0}; - detail::normalize(sig_rhs, exp_rhs); - const auto final_sig_rhs {static_cast(sig_rhs)}; - - return detail::d64_add_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_sig_rhs, exp_rhs, !(rhs < 0), - abs_lhs_bigger); -} - -template -constexpr auto operator-(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(rhs)) - { - return rhs; - } - #endif - - auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; - const bool abs_lhs_bigger {sig_lhs > abs(rhs)}; - - exp_type exp_lhs {0}; - detail::normalize(sig_lhs, exp_lhs); - const auto final_sig_lhs {static_cast(sig_lhs)}; - - return detail::d64_add_impl(final_sig_lhs, exp_lhs, (lhs < 0), - rhs.significand_, rhs.biased_exponent(), !rhs.sign_, - abs_lhs_bigger); -} - -constexpr auto operator*(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs) || not_finite(rhs)) - { - return detail::check_non_finite(lhs, rhs); - } - #endif - - return detail::d64_mul_impl(lhs, rhs); -} - -template -constexpr auto operator*(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = decimal_fast64_t::biased_exponent_type; - - #ifndef BOOST_DECIMAL_FAST_MATH - if (not_finite(lhs)) - { - return lhs; - } - #endif - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type rhs_exp {0}; - detail::normalize(rhs_sig, rhs_exp); - auto final_rhs_sig {static_cast(rhs_sig)}; - - return detail::d64_mul_impl( - lhs.significand_, lhs.biased_exponent(), lhs.sign_, - final_rhs_sig, rhs_exp, (rhs < 0) - ); -} - -template -constexpr auto operator*(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - return rhs * lhs; -} - -constexpr auto d64_fast_div_impl(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs, decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void -{ - const bool sign {lhs.isneg() != rhs.isneg()}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast64_t zero {0, 0}; - constexpr decimal_fast64_t nan {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_snan, 0, false)}; - constexpr decimal_fast64_t inf {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_inf, 0, false)}; - - const auto lhs_fp {fpclassify(lhs)}; - const auto rhs_fp {fpclassify(rhs)}; - - if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) - { - q = nan; - r = nan; - return; - } - - switch (lhs_fp) - { - case FP_INFINITE: - q = sign ? -inf : inf; - r = zero; - return; - case FP_ZERO: - q = sign ? -zero : zero; - r = sign ? -zero : zero; - return; - default: - static_cast(lhs); - } - - switch (rhs_fp) - { - case FP_ZERO: - q = inf; - r = zero; - return; - case FP_INFINITE: - q = sign ? -zero : zero; - r = lhs; - return; - default: - static_cast(rhs); - } - #else - static_cast(r); - #endif - - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "sig lhs: " << sig_lhs - << "\nexp lhs: " << exp_lhs - << "\nsig rhs: " << sig_rhs - << "\nexp rhs: " << exp_rhs << std::endl; - #endif - - using unsigned_int128_type = boost::int128::uint128_t; - - // If rhs is greater than we need to offset the significands to get the correct values - // e.g. 4/8 is 0 but 40/8 yields 5 in integer maths - constexpr auto tens_needed {detail::pow10(static_cast(detail::precision_v))}; - const auto big_sig_lhs {static_cast(lhs.significand_) * tens_needed}; - - const auto res_sig {big_sig_lhs / static_cast(rhs.significand_)}; - const auto res_exp {(lhs.biased_exponent() - detail::precision_v) - rhs.biased_exponent()}; - - BOOST_DECIMAL_ASSERT(res_sig <= std::numeric_limits::max()); - - q = decimal_fast64_t{static_cast(res_sig), res_exp, sign}; -} - -constexpr auto d64_fast_mod_impl(const decimal_fast64_t lhs, const decimal_fast64_t rhs, const decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void -{ - constexpr decimal_fast64_t zero {0, 0}; - - // https://en.cppreference.com/w/cpp/numeric/math/fmod - auto q_trunc {q > zero ? floor(q) : ceil(q)}; - r = lhs - (decimal_fast64_t(q_trunc) * rhs); -} - -constexpr auto operator/(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs) noexcept -> decimal_fast64_t -{ - decimal_fast64_t q {}; - decimal_fast64_t r {}; - - d64_fast_div_impl(lhs, rhs, q, r); - - return q; -} - -template -constexpr auto operator/(const decimal_fast64_t lhs, const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = detail::decimal_fast64_t_components::biased_exponent_type; - - const bool sign {lhs.isneg() != (rhs < 0)}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast64_t zero {0, 0}; - constexpr decimal_fast64_t nan {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_snan, 0, false)}; - constexpr decimal_fast64_t inf {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_inf, 0, false)}; - - const auto lhs_fp {fpclassify(lhs)}; - - switch (lhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return inf; - case FP_ZERO: - return sign ? -zero : zero; - default: - static_cast(lhs); - } - - if (rhs == 0) - { - return sign ? -inf : inf; - } - #endif - - const detail::decimal_fast64_t_components lhs_components {lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()}; - - auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; - exp_type rhs_exp {}; - detail::decimal_fast64_t_components rhs_components {detail::shrink_significand(rhs_sig, rhs_exp), rhs_exp, rhs < 0}; - - return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); -} - -template -constexpr auto operator/(const Integer lhs, const decimal_fast64_t rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) -{ - using promoted_significand_type = detail::promote_significand_t; - using exp_type = detail::decimal_fast64_t_components::biased_exponent_type; - - const bool sign {(lhs < 0) != rhs.isneg()}; - - #ifndef BOOST_DECIMAL_FAST_MATH - // Check pre-conditions - constexpr decimal_fast64_t zero {0, 0}; - constexpr decimal_fast64_t nan {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_snan, 0, false)}; - constexpr decimal_fast64_t inf {boost::decimal::direct_init_d64(boost::decimal::detail::d64_fast_inf, 0, false)}; - - const auto rhs_fp {fpclassify(rhs)}; - - switch (rhs_fp) - { - case FP_NAN: - return nan; - case FP_INFINITE: - return sign ? -zero : zero; - case FP_ZERO: - return sign ? -inf : inf; - default: - static_cast(lhs); - } - #endif - - const detail::decimal_fast64_t_components rhs_components {rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; - - auto lhs_sig {static_cast(detail::make_positive_unsigned(lhs))}; - exp_type lhs_exp {}; - const detail::decimal_fast64_t_components lhs_components {detail::shrink_significand(lhs_sig, lhs_exp), lhs_exp, lhs < 0}; - - return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); -} - -constexpr auto operator%(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t -{ - decimal_fast64_t q {}; - decimal_fast64_t r {}; - d64_fast_div_impl(lhs, rhs, q, r); - d64_fast_mod_impl(lhs, rhs, q, r); - - return r; -} - -constexpr auto decimal_fast64_t::operator+=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & -{ - *this = *this + rhs; - return *this; -} - -constexpr auto decimal_fast64_t::operator-=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & -{ - *this = *this - rhs; - return *this; -} - -constexpr auto decimal_fast64_t::operator*=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & -{ - *this = *this * rhs; - return *this; -} - -constexpr auto decimal_fast64_t::operator/=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & -{ - *this = *this / rhs; - return *this; -} - -template -constexpr auto decimal_fast64_t::operator+=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) -{ - *this = *this + rhs; - return *this; -} - -template -constexpr auto decimal_fast64_t::operator-=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) -{ - *this = *this - rhs; - return *this; -} - -template -constexpr auto decimal_fast64_t::operator*=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) -{ - *this = *this * rhs; - return *this; -} - -template -constexpr auto decimal_fast64_t::operator/=(const Integer rhs) noexcept - BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) -{ - *this = *this / rhs; - return *this; -} - -constexpr auto decimal_fast64_t::operator++() noexcept -> decimal_fast64_t& -{ - constexpr decimal_fast64_t one {1, 0}; - *this = *this + one; - return *this; -} - -constexpr auto decimal_fast64_t::operator++(int) noexcept -> decimal_fast64_t& -{ - return ++(*this); -} - -constexpr auto decimal_fast64_t::operator--() noexcept -> decimal_fast64_t& -{ - constexpr decimal_fast64_t one {1, 0}; - *this = *this - one; - return *this; -} - -constexpr auto decimal_fast64_t::operator--(int) noexcept -> decimal_fast64_t& -{ - return --(*this); -} - -constexpr auto scalblnd64f(decimal_fast64_t num, const long exp) noexcept -> decimal_fast64_t -{ - #ifndef BOOST_DECIMAL_FAST_MATH - constexpr decimal_fast64_t zero {0, 0}; - - if (num == zero || exp == 0 || not_finite(num)) - { - return num; - } - #endif - - num = decimal_fast64_t(num.significand_, num.biased_exponent() + exp, num.sign_); - - return num; -} - -constexpr auto scalbnd64f(const decimal_fast64_t num, const int expval) noexcept -> decimal_fast64_t -{ - return scalblnd64f(num, static_cast(expval)); -} - -constexpr auto copysignd64f(decimal_fast64_t mag, const decimal_fast64_t sgn) noexcept -> decimal_fast64_t -{ - mag.sign_ = sgn.sign_; - return mag; -} - -} // namespace decimal -} // namespace boost - -namespace std { - -template <> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits -#endif -{ -#ifdef _MSC_VER - public: -#endif - - static constexpr bool is_specialized = true; - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = true; - - // These members were deprecated in C++23 - #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) - static constexpr std::float_denorm_style has_denorm = std::denorm_present; - static constexpr bool has_denorm_loss = true; - #endif - - static constexpr std::float_round_style round_style = std::round_indeterminate; - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - static constexpr int digits = 16; - static constexpr int digits10 = digits; - static constexpr int max_digits10 = digits; - static constexpr int radix = 10; - static constexpr int min_exponent = -383; - static constexpr int min_exponent10 = min_exponent; - static constexpr int max_exponent = 384; - static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; - static constexpr bool tinyness_before = true; - - // Member functions - static constexpr auto (min) () -> boost::decimal::decimal_fast64_t { return {UINT32_C(1), min_exponent}; } - static constexpr auto (max) () -> boost::decimal::decimal_fast64_t { return {UINT64_C(9'999'999'999'999'999), max_exponent - digits + 1}; } - static constexpr auto lowest () -> boost::decimal::decimal_fast64_t { return {UINT64_C(9'999'999'999'999'999), max_exponent - digits + 1, true}; } - static constexpr auto epsilon () -> boost::decimal::decimal_fast64_t { return {UINT32_C(1), -digits + 1}; } - static constexpr auto round_error () -> boost::decimal::decimal_fast64_t { return epsilon(); } - static constexpr auto infinity () -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( - boost::decimal::detail::d64_fast_inf, 0, false); } - static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( - boost::decimal::detail::d64_fast_qnan, 0, false); } - static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( - boost::decimal::detail::d64_fast_snan, 0, false); } - static constexpr auto denorm_min () -> boost::decimal::decimal_fast64_t { return min(); } -}; - -} // namespace std - -#endif //BOOST_DECIMAL_decimal_fast64_t_HPP diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 1a78474ed..b963aff10 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -1,10 +1,2206 @@ -// Copyright 2025 Matt Borland +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL64_T_HPP -#define BOOST_DECIMAL_DECIMAL64_T_HPP +#ifndef BOOST_DECIMAL_decimal64_t_HPP +#define BOOST_DECIMAL_decimal64_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL64_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_DECIMAL_DISABLE_IOSTREAM) +#include +#include +#endif + +#endif // BOOST_DECIMAL_BUILD_MODULE + +namespace boost { +namespace decimal { +namespace detail { + +// See IEEE 754 section 3.5.2 +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_inf_mask = UINT64_C(0x7800000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_nan_mask = UINT64_C(0x7C00000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_snan_mask = UINT64_C(0x7E00000000000000); + +// Comb. Exponent Significand +// s eeeeeeeeee [ttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt] +// s 11 eeeeeeeeee [100t][tttttttttt][tttttttttt][tttttttttt][tttttttttt][tttttttttt] + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_sign_mask = UINT64_C(0x8000000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_combination_field_mask = UINT64_C(0x6000000000000000); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_exp_mask = UINT64_C(0x7FE0000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_exp_shift = UINT64_C(53); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_11_exp_mask = UINT64_C(0x1FF8000000000000); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_11_exp_shift = UINT64_C(51); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_not_11_significand_mask = UINT64_C(0x1FFFFFFFFFFFFF); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_11_significand_mask = UINT64_C(0x7FFFFFFFFFFFF); + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_biggest_no_combination_significand = d64_not_11_significand_mask; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_max_biased_exponent = UINT64_C(767); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t d64_max_significand_value = UINT64_C(9'999'999'999'999'999); + + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto d64_fma_impl(T x, T y, T z) noexcept -> T; + +} //namespace detail + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + +BOOST_DECIMAL_EXPORT class decimal64_t final +{ +public: + using significand_type = std::uint64_t; + using exponent_type = std::uint64_t; + using biased_exponent_type = std::int32_t; + +private: + + std::uint64_t bits_ {}; + + // Returns the un-biased (quantum) exponent + constexpr auto unbiased_exponent() const noexcept -> exponent_type; + + // Returns the biased exponent + constexpr auto biased_exponent() const noexcept -> biased_exponent_type; + + // Allows direct editing of the exp + template + constexpr auto edit_exponent(T exp) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void); + + // Returns the significand complete with the bits implied from the combination field + constexpr auto full_significand() const noexcept -> significand_type; + constexpr auto isneg() const noexcept -> bool; + constexpr auto edit_sign(bool sign) noexcept -> void; + + constexpr auto to_components() const noexcept -> detail::decimal64_t_components; + + // Attempts conversion to integral type: + // If this is nan sets errno to EINVAL and returns 0 + // If this is not representable sets errno to ERANGE and returns 0 + template + friend constexpr auto to_integral(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + // Debug bit pattern + friend constexpr auto from_bits(std::uint64_t bits) noexcept -> decimal64_t; + friend constexpr auto to_bits(decimal64_t rhs) noexcept -> std::uint64_t; + + // Equality template between any integer type and decimal64_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal64_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + friend constexpr auto d64_div_impl(decimal64_t lhs, decimal64_t rhs, decimal64_t& q, decimal64_t& r) noexcept -> void; + + friend constexpr auto d64_mod_impl(decimal64_t lhs, decimal64_t rhs, const decimal64_t& q, decimal64_t& r) noexcept -> void; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + // Micro-optimization: Nearly every call to isfinite in the basic operators is !isfinite. + // We can super easily combine this into a single operation + friend constexpr auto not_finite(decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto equality_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; + + template + friend constexpr auto sequential_less_impl(DecimalType lhs, DecimalType rhs) noexcept -> bool; + + friend constexpr auto to_bid_d64(decimal64_t val) noexcept -> std::uint64_t; + + friend constexpr auto from_bid_d64(std::uint64_t bits) noexcept -> decimal64_t; + + template + friend constexpr auto to_dpd_d64(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t); + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::d64_fma_impl(T x, T y, T z) noexcept -> T; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal64_t(const char* str, std::size_t len); + #endif + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_ieee_type_v, T, typename T::significand_type); + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_ieee_type_v, TargetDecimalType); + + friend constexpr auto nan_conversion(const decimal64_t value) noexcept -> decimal64_t + { + constexpr auto convert_nan_mask {detail::d64_snan_mask ^ detail::d64_nan_mask}; + + decimal64_t return_value; + return_value.bits_ = value.bits_ ^ convert_nan_mask; + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + +public: + // 3.2.3.1 construct/copy/destroy + constexpr decimal64_t() noexcept = default; + constexpr decimal64_t& operator=(const decimal64_t& rhs) noexcept = default; + constexpr decimal64_t& operator=(decimal64_t&& rhs) noexcept = default; + constexpr decimal64_t(const decimal64_t& rhs) noexcept = default; + constexpr decimal64_t(decimal64_t&& rhs) noexcept = default; + + // 3.2.2.2 Conversion form floating-point type + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit constexpr decimal64_t(long double val) noexcept = delete; + #endif + + template + BOOST_DECIMAL_CXX20_CONSTEXPR auto operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal64_t&); + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + explicit constexpr decimal64_t(Decimal val) noexcept; + + // 3.2.3.3 Conversion from integral type + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal64_t(Integer val) noexcept; + + template + constexpr auto operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); + + // 3.2.3.4 Conversion to integral type + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator detail::builtin_int128_t() const noexcept; + explicit constexpr operator detail::builtin_uint128_t() const noexcept; + #endif + + + // Conversion to another decimal type + template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> + constexpr operator Decimal() const noexcept; + + template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> + explicit constexpr operator Decimal() const noexcept; + + // 3.2.6 Conversion to a floating-point type + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + // 3.2.5 initialization from coefficient and exponent: + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal64_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal64_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal64_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal64_t(bool value) noexcept; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + explicit constexpr decimal64_t(const char* str); + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal64_t(const std::string& str); + #else + explicit constexpr decimal64_t(std::string_view str); + #endif + + #endif + + // cmath functions that are easier as friends + friend constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + friend constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + friend constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + friend constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + friend constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + friend constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64_t rhs) noexcept -> bool; + + // 3.2.7 unary arithmetic operators: + friend constexpr auto operator+(decimal64_t rhs) noexcept -> decimal64_t; + friend constexpr auto operator-(decimal64_t rhs) noexcept -> decimal64_t; + + // 3.2.8 Binary arithmetic operators + friend constexpr auto operator+(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + template + friend constexpr auto operator+(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + template + friend constexpr auto operator+(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + friend constexpr auto operator-(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + template + friend constexpr auto operator-(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + template + friend constexpr auto operator-(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + friend constexpr auto operator*(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + template + friend constexpr auto operator*(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + template + friend constexpr auto operator*(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + friend constexpr auto operator/(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + template + friend constexpr auto operator/(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + template + friend constexpr auto operator/(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t); + + friend constexpr auto operator%(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + // 3.2.3.5 Increment and Decrement + constexpr auto operator++() noexcept -> decimal64_t&; + constexpr auto operator++(int) noexcept -> decimal64_t; // NOLINT : C++14 so constexpr implies const + constexpr auto operator--() noexcept -> decimal64_t&; + constexpr auto operator--(int) noexcept -> decimal64_t; // NOLINT : C++14 so constexpr implies const + + // 3.2.3.6 Compound assignment + constexpr auto operator+=(decimal64_t rhs) noexcept -> decimal64_t&; + + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); + + template + constexpr auto operator+=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); + + constexpr auto operator-=(decimal64_t rhs) noexcept -> decimal64_t&; + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); + + template + constexpr auto operator-=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); + + constexpr auto operator*=(decimal64_t rhs) noexcept -> decimal64_t&; + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); + + template + constexpr auto operator*=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); + + constexpr auto operator/=(decimal64_t rhs) noexcept -> decimal64_t&; + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&); + + template + constexpr auto operator/=(Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&); + + constexpr auto operator%=(decimal64_t rhs) noexcept -> decimal64_t&; + + // 3.2.9 Comparison operators: + // Equality + friend constexpr auto operator==(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator==(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Inequality + friend constexpr auto operator!=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator!=(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less + friend constexpr auto operator<(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator<(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Less equal + friend constexpr auto operator<=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator<=(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater + friend constexpr auto operator>(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator>(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // Greater equal + friend constexpr auto operator>=(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + template + friend constexpr auto operator>=(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // C++20 spaceship + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + friend constexpr auto operator<=>(decimal64_t lhs, decimal64_t rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(decimal64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + #endif + + // 3.6.4 Same Quantum + friend constexpr auto samequantumd64(decimal64_t lhs, decimal64_t rhs) noexcept -> bool; + + // 3.6.5 Quantum exponent + friend constexpr auto quantexpd64(decimal64_t x) noexcept -> int; + + // 3.6.6 Quantize + friend constexpr auto quantized64(decimal64_t lhs, decimal64_t rhs) noexcept -> decimal64_t; + + // functions that need to be friends + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto copysignd64(decimal64_t mag, decimal64_t sgn) noexcept -> decimal64_t; + friend constexpr auto scalbnd64(decimal64_t num, int exp) noexcept -> decimal64_t; + friend constexpr auto scalblnd64(decimal64_t num, long exp) noexcept -> decimal64_t; +}; + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic pop +#endif + +constexpr auto from_bits(std::uint64_t bits) noexcept -> decimal64_t +{ + decimal64_t result; + result.bits_ = bits; + + return result; +} + +constexpr auto to_bits(decimal64_t rhs) noexcept -> std::uint64_t +{ + return rhs.bits_; +} + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wduplicated-branches" +# pragma GCC diagnostic ignored "-Wbool-compare" +# pragma GCC diagnostic ignored "-Wconversion" +#endif + +// 3.2.5 initialization from coefficient and exponent: +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal64_t::decimal64_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept +{ + const auto is_negative {static_cast(resultant_sign)}; + bits_ = is_negative ? detail::d64_sign_mask : UINT64_C(0); + + // If the coeff is not in range, make it so + int coeff_digits {-1}; + auto biased_exp {static_cast(exp) + detail::bias_v}; + if (coeff > detail::d64_max_significand_value || biased_exp < -(detail::precision_v - 1)) + { + coeff_digits = detail::coefficient_rounding(coeff, exp, biased_exp, is_negative, detail::num_digits(coeff)); + } + + auto reduced_coeff {static_cast(coeff)}; + bool big_combination {false}; + + if (reduced_coeff == 0U) + { + // Normalize our handling of zeros + return; + } + + if (reduced_coeff <= detail::d64_biggest_no_combination_significand) + { + // If the coefficient fits directly, we don't need to use the combination field + // bits_.significand = reduced_coeff; + bits_ |= (reduced_coeff & detail::d64_not_11_significand_mask); + } + else + { + // Have to use the full combination field + bits_ |= (detail::d64_combination_field_mask | (reduced_coeff & detail::d64_11_significand_mask)); + big_combination = true; + } + + // If the exponent fits, we do not need to use the combination field + if (BOOST_DECIMAL_LIKELY(biased_exp >= 0 && biased_exp <= static_cast(detail::d64_max_biased_exponent))) + { + if (big_combination) + { + bits_ |= (static_cast(biased_exp) << detail::d64_11_exp_shift) & detail::d64_11_exp_mask; + } + else + { + bits_ |= (static_cast(biased_exp) << detail::d64_not_11_exp_shift) & detail::d64_not_11_exp_mask; + } + } + else + { + // If we can fit the extra exponent in the significand, then we can construct the value + // If we can't, the value is either 0 or infinity depending on the sign of exp + + if (coeff_digits == -1) + { + coeff_digits = detail::num_digits(reduced_coeff); + } + + const auto exp_delta {biased_exp - static_cast(detail::d64_max_biased_exponent)}; + const auto digit_delta {coeff_digits - exp_delta}; + if (biased_exp < 0 && coeff_digits == 1) + { + // This needs to be flushed to 0 or rounded to subnormal min + // e.g. 7e-399 should not become 70e-398 but 7e-400 should become 0 + rounding_mode current_round_mode {_boost_decimal_global_rounding_mode}; + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(coeff)) + { + current_round_mode = _boost_decimal_global_runtime_rounding_mode; + } + + #endif + + bool round {false}; + if (biased_exp == -1) + { + switch (current_round_mode) + { + case rounding_mode::fe_dec_to_nearest_from_zero: + BOOST_DECIMAL_FALLTHROUGH + case rounding_mode::fe_dec_to_nearest: + if (reduced_coeff >= 5U) + { + round = true; + } + break; + case rounding_mode::fe_dec_upward: + if (!is_negative && reduced_coeff != 0) + { + round = true; + } + break; + default: + round = false; + break; + } + } + + if (round) + { + // Subnormal min is just 1 + bits_ = UINT64_C(1); + } + else + { + bits_ = UINT64_C(0); + } + + bits_ |= is_negative ? detail::d64_sign_mask : UINT64_C(0); + } + else if (digit_delta > 0 && coeff_digits + digit_delta <= detail::precision_v) + { + exp -= digit_delta; + reduced_coeff *= detail::pow10(static_cast(digit_delta)); + *this = decimal64_t(reduced_coeff, exp, is_negative); + } + else if (coeff_digits + biased_exp <= detail::precision_v) + { + // Handle the case of sub-normals that don't need further rounding + bits_ = is_negative ? detail::d64_sign_mask : UINT64_C(0); // Reset the sign bit + const auto zeros {detail::remove_trailing_zeros(reduced_coeff)}; + biased_exp += static_cast(zeros.number_of_removed_zeros); + reduced_coeff = zeros.trimmed_number; + if (biased_exp > 0) + { + reduced_coeff *= detail::pow10(static_cast(biased_exp)); + } + bits_ |= reduced_coeff; + } + else if (digit_delta < 0 && coeff_digits - digit_delta <= detail::precision_v) + { + const auto offset {detail::precision_v - coeff_digits}; + exp -= offset; + reduced_coeff *= detail::pow10(static_cast(offset)); + *this = decimal64_t(reduced_coeff, exp, is_negative); + } + else if (biased_exp > detail::max_biased_exp_v) + { + // Similar to subnormals, but for extremely large values + const auto available_space {detail::precision_v - coeff_digits}; + if (available_space >= exp_delta) + { + reduced_coeff *= detail::pow10(static_cast(available_space)); + exp -= available_space; + *this = decimal64_t(reduced_coeff, exp, is_negative); + } + else + { + bits_ = exp < 0 ? UINT64_C(0) : detail::d64_inf_mask; + bits_ |= is_negative ? detail::d64_sign_mask : UINT64_C(0); + } + } + else + { + // Reset the value and make sure to preserve the sign of 0/inf + bits_ = exp < 0 ? UINT64_C(0) : detail::d64_inf_mask; + bits_ |= is_negative ? detail::d64_sign_mask : UINT64_C(0); + } + } +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal64_t::decimal64_t(const T1 coeff, const T2 exp) noexcept : decimal64_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +constexpr decimal64_t::decimal64_t(const bool value) noexcept : decimal64_t(static_cast(value), 0, false) {} + + +#if defined(__GNUC__) && __GNUC__ >= 6 +# pragma GCC diagnostic pop +#endif + +namespace detail { + +template +class numeric_limits_impl64 +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = true; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 16; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -383; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 384; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal64_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal64_t { return {boost::decimal::detail::d64_max_significand_value, max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal64_t { return {boost::decimal::detail::d64_max_significand_value, max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal64_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal64_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_nan_mask); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal64_t { return boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask); } + static constexpr auto denorm_min () -> boost::decimal::decimal64_t { return {1, boost::decimal::detail::etiny_v}; } +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl64::is_specialized; +template constexpr bool numeric_limits_impl64::is_signed; +template constexpr bool numeric_limits_impl64::is_integer; +template constexpr bool numeric_limits_impl64::is_exact; +template constexpr bool numeric_limits_impl64::has_infinity; +template constexpr bool numeric_limits_impl64::has_quiet_NaN; +template constexpr bool numeric_limits_impl64::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl64::has_denorm; +template constexpr bool numeric_limits_impl64::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl64::round_style; +template constexpr bool numeric_limits_impl64::is_iec559; +template constexpr bool numeric_limits_impl64::is_bounded; +template constexpr bool numeric_limits_impl64::is_modulo; +template constexpr int numeric_limits_impl64::digits; +template constexpr int numeric_limits_impl64::digits10; +template constexpr int numeric_limits_impl64::max_digits10; +template constexpr int numeric_limits_impl64::radix; +template constexpr int numeric_limits_impl64::min_exponent; +template constexpr int numeric_limits_impl64::min_exponent10; +template constexpr int numeric_limits_impl64::max_exponent; +template constexpr int numeric_limits_impl64::max_exponent10; +template constexpr bool numeric_limits_impl64::traps; +template constexpr bool numeric_limits_impl64::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} //namespace decimal +} //namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl64 {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // Namespace std + +namespace boost { +namespace decimal { + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::decimal64_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + *this = from_bits(detail::d64_nan_mask); + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + *this = from_bits(detail::d64_inf_mask); + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "Mant: " << components.mantissa + << "\nExp: " << components.exponent + << "\nSign: " << components.sign << std::endl; + #endif + + if (components.exponent > detail::emax_v) + { + *this = from_bits(detail::d64_inf_mask); + } + else + { + *this = decimal64_t {components.mantissa, components.exponent, components.sign}; + } + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +template +BOOST_DECIMAL_CXX20_CONSTEXPR auto decimal64_t::operator=(const Float& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_floating_point_v, Float, decimal64_t&) +{ + *this = decimal64_t{val}; + return *this; +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal64_t::decimal64_t(const Decimal val) noexcept +{ + *this = to_decimal(val); +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal64_t::decimal64_t(const Integer val) noexcept : decimal64_t{val, 0} {} + +template +constexpr auto decimal64_t::operator=(const Integer& val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) +{ + using ConversionType = std::conditional_t::value, std::int32_t, Integer>; + *this = decimal64_t{static_cast(val), 0}; + return *this; +} + +constexpr decimal64_t::operator bool() const noexcept +{ + constexpr decimal64_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal64_t::operator int() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator unsigned() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator unsigned long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator long long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator unsigned long long() const noexcept +{ + return to_integral(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal64_t::operator detail::builtin_int128_t() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal64_t::operator detail::builtin_uint128_t() const noexcept +{ + return to_integral(*this); +} + +#endif + +template && (detail::decimal_val_v > detail::decimal_val_v), bool>> +constexpr decimal64_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> +constexpr decimal64_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::operator long double() const noexcept +{ + return to_float(*this); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal64_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal64_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal64_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal64_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +constexpr auto decimal64_t::unbiased_exponent() const noexcept -> exponent_type +{ + exponent_type expval {}; + + if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) + { + expval = (bits_ & detail::d64_11_exp_mask) >> detail::d64_11_exp_shift; + } + else + { + expval = (bits_ & detail::d64_not_11_exp_mask) >> detail::d64_not_11_exp_shift; + } + + return expval; +} + +constexpr auto decimal64_t::biased_exponent() const noexcept -> biased_exponent_type +{ + return static_cast(unbiased_exponent()) - detail::bias_v; +} + +constexpr auto decimal64_t::full_significand() const noexcept -> significand_type +{ + significand_type significand {}; + + if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) + { + constexpr std::uint64_t implied_bit {UINT64_C(0x20000000000000)}; + significand = implied_bit | (bits_ & detail::d64_11_significand_mask); + } + else + { + significand = bits_ & detail::d64_not_11_significand_mask; + } + + return significand; +} + +constexpr auto decimal64_t::isneg() const noexcept -> bool +{ + return static_cast(bits_ & detail::d64_sign_mask); +} + +constexpr auto decimal64_t::to_components() const noexcept -> detail::decimal64_t_components +{ + detail::decimal64_t_components components {}; + + exponent_type expval {}; + significand_type significand {}; + + if ((bits_ & detail::d64_combination_field_mask) == detail::d64_combination_field_mask) + { + constexpr std::uint64_t implied_bit {UINT64_C(0x20000000000000)}; + significand = implied_bit | (bits_ & detail::d64_11_significand_mask); + expval = (bits_ & detail::d64_11_exp_mask) >> detail::d64_11_exp_shift; + } + else + { + significand = bits_ & detail::d64_not_11_significand_mask; + expval = (bits_ & detail::d64_not_11_exp_mask) >> detail::d64_not_11_exp_shift; + } + + components.sig = significand; + components.exp = static_cast(expval) - detail::bias_v; + components.sign = bits_ & detail::d64_sign_mask; + + return components; +} + +template +constexpr auto decimal64_t::edit_exponent(const T expval) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, T, void) +{ + *this = decimal64_t(this->full_significand(), expval, this->isneg()); +} + +constexpr auto decimal64_t::edit_sign(const bool sign) noexcept -> void +{ + if (sign) + { + bits_ |= detail::d64_sign_mask; + } + else + { + bits_ &= ~detail::d64_sign_mask; + } +} + +constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + return rhs.bits_ & detail::d64_sign_mask; +} + +constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_ & detail::d64_nan_mask) == detail::d64_nan_mask; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return ((rhs.bits_ & detail::d64_nan_mask) == detail::d64_inf_mask); + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return (rhs.bits_ & detail::d64_snan_mask) == detail::d64_snan_mask; + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check for de-normals + const auto sig {rhs.full_significand()}; + const auto exp {rhs.unbiased_exponent()}; + + if (exp <= detail::precision_v - 1) + { + return false; + } + + return (sig != 0) && isfinite(rhs); + #else + return rhs.full_significand() != 0; + #endif +} + +constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return ((rhs.bits_ & detail::d64_inf_mask) != detail::d64_inf_mask); + #else + static_cast(rhs); + return true; + #endif +} + +BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return ((rhs.bits_ & detail::d64_inf_mask) == detail::d64_inf_mask); + #else + static_cast(rhs); + return false; + #endif +} + +constexpr auto operator==(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + return equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +constexpr auto operator!=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +constexpr auto operator<(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isnan(lhs) || isnan(rhs) || + (!lhs.isneg() && rhs.isneg())) + { + return false; + } + if (lhs.isneg() && !rhs.isneg()) + { + return true; + } + if (isfinite(lhs) && isinf(rhs)) + { + return !rhs.isneg(); + } + } + #endif + + return sequential_less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !less_impl(rhs, lhs) && lhs != rhs; +} + +constexpr auto operator<=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +constexpr auto operator>=(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal64_t lhs, const decimal64_t rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif + +constexpr auto operator+(const decimal64_t rhs) noexcept -> decimal64_t +{ + return rhs; +} + +constexpr auto operator-(decimal64_t rhs) noexcept-> decimal64_t +{ + rhs.bits_ ^= detail::d64_sign_mask; + return rhs; +} + +constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decimal64_t& q, decimal64_t& r) noexcept -> void +{ + const bool sign {lhs.isneg() != rhs.isneg()}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal64_t zero {0, 0}; + constexpr decimal64_t nan {from_bits(detail::d64_nan_mask)}; + constexpr decimal64_t inf {from_bits(detail::d64_inf_mask)}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal64_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (lhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + + #else + static_cast(r); + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "sig lhs: " << sig_lhs + << "\nexp lhs: " << exp_lhs + << "\nsig rhs: " << sig_rhs + << "\nexp rhs: " << exp_rhs << std::endl; + #endif + + q = detail::d64_generic_div_impl(lhs_components, rhs.to_components(), sign); +} + +constexpr auto d64_mod_impl(const decimal64_t lhs, const decimal64_t rhs, const decimal64_t& q, decimal64_t& r) noexcept -> void +{ + constexpr decimal64_t zero {0, 0}; + + // https://en.cppreference.com/w/cpp/numeric/math/fmod + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator+(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return from_bits(detail::d64_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + + return detail::add_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator+(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_lhs {lhs.full_significand()}; + auto exp_lhs {lhs.biased_exponent()}; + detail::expand_significand(sig_lhs, exp_lhs); + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::add_impl( + detail::decimal64_t_components{sig_lhs, exp_lhs, lhs.isneg()}, + detail::decimal64_t_components{final_sig_rhs, exp_rhs, (rhs < 0)} + ); +} + +template +constexpr auto operator+(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + return rhs + lhs; +} + +// NOLINTNEXTLINE: If subtraction is actually addition than use operator+ and vice versa +constexpr auto operator-(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return from_bits(detail::d64_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + auto lhs_components {lhs.to_components()}; + detail::expand_significand(lhs_components.sig, lhs_components.exp); + auto rhs_components {rhs.to_components()}; + detail::expand_significand(rhs_components.sig, rhs_components.exp); + rhs_components.sign = !rhs_components.sign; + + return detail::add_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator-(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_lhs {lhs.full_significand()}; + auto exp_lhs {lhs.biased_exponent()}; + detail::expand_significand(sig_lhs, exp_lhs); + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::add_impl( + detail::decimal64_t_components{sig_lhs, exp_lhs, lhs.isneg()}, + detail::decimal64_t_components{final_sig_rhs, exp_rhs, !(rhs < 0)} + ); +} + +template +constexpr auto operator-(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; + exp_type exp_lhs {0}; + detail::normalize(sig_lhs, exp_lhs); + const auto final_sig_lhs {static_cast(detail::make_positive_unsigned(sig_lhs))}; + + auto sig_rhs {rhs.full_significand()}; + auto exp_rhs {rhs.biased_exponent()}; + detail::expand_significand(sig_rhs, exp_rhs); + + return detail::add_impl( + detail::decimal64_t_components{final_sig_lhs, exp_lhs, (lhs < 0)}, + detail::decimal64_t_components{sig_rhs, exp_rhs, !rhs.isneg()} + ); +} + +constexpr auto operator*(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return from_bits(detail::d64_nan_mask); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + const auto lhs_components {lhs.to_components()}; + const auto rhs_components {rhs.to_components()}; + + return detail::mul_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator*(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto lhs_sig {lhs.full_significand()}; + auto lhs_exp {lhs.biased_exponent()}; + detail::expand_significand(lhs_sig, lhs_exp); + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type rhs_exp {0}; + detail::normalize(rhs_sig, rhs_exp); + const auto final_rhs_sig {static_cast(rhs_sig)}; + + return detail::d64_mul_impl(lhs_sig, lhs_exp, lhs.isneg(), + final_rhs_sig, rhs_exp, (rhs < 0)); +} + +template +constexpr auto operator*(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + return rhs * lhs; +} + +constexpr auto operator/(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + decimal64_t q {}; + decimal64_t r {}; + d64_div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using sig_type = decimal64_t::significand_type; + using exp_type = decimal64_t::biased_exponent_type; + using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal64_t zero {0, 0}; + constexpr decimal64_t inf {from_bits(detail::d64_inf_mask)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + auto lhs_sig {lhs.full_significand()}; + auto lhs_exp {lhs.biased_exponent()}; + detail::expand_significand(lhs_sig, lhs_exp); + detail::decimal64_t_components lhs_components {lhs_sig, lhs_exp, lhs.isneg()}; + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type rhs_exp {}; + detail::normalize(rhs_sig, rhs_exp); + detail::decimal64_t_components rhs_components {static_cast(rhs_sig), rhs_exp, rhs < 0}; + + return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); +} + +template +constexpr auto operator/(const Integer lhs, const decimal64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t) +{ + using sig_type = decimal64_t::significand_type; + using exp_type = decimal64_t::biased_exponent_type; + using integer_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), detail::make_unsigned_t, sig_type>; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal64_t zero {0, 0}; + constexpr decimal64_t inf {from_bits(detail::d64_inf_mask)}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + auto rhs_sig {rhs.full_significand()}; + auto rhs_exp {rhs.biased_exponent()}; + detail::expand_significand(rhs_sig, rhs_exp); + + exp_type lhs_exp {}; + auto lhs_sig {static_cast(detail::make_positive_unsigned(lhs))}; + detail::normalize(lhs_sig, lhs_exp); + detail::decimal64_t_components lhs_components {static_cast(lhs_sig), lhs_exp, lhs < 0}; + detail::decimal64_t_components rhs_components {rhs_sig, rhs_exp, rhs.isneg()}; + + return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); +} + +constexpr auto operator%(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + decimal64_t q {}; + decimal64_t r {}; + d64_div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + d64_mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal64_t::operator++() noexcept -> decimal64_t& +{ + constexpr decimal64_t one{1, 0}; + *this = *this + one; + return *this; +} + +constexpr auto decimal64_t::operator++(int) noexcept -> decimal64_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal64_t::operator--() noexcept -> decimal64_t& +{ + constexpr decimal64_t one{1, 0}; + *this = *this - one; + return *this; +} + +constexpr auto decimal64_t::operator--(int) noexcept -> decimal64_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +constexpr auto decimal64_t::operator+=(const decimal64_t rhs) noexcept -> decimal64_t& +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator+=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) +{ + *this = *this + rhs; + return *this; +} + +constexpr auto decimal64_t::operator-=(const decimal64_t rhs) noexcept -> decimal64_t& +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator-=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) +{ + *this = *this - rhs; + return *this; +} + +constexpr auto decimal64_t::operator*=(const decimal64_t rhs) noexcept -> decimal64_t& +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator*=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) +{ + *this = *this * rhs; + return *this; +} + +constexpr auto decimal64_t::operator/=(const decimal64_t rhs) noexcept -> decimal64_t& +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal64_t&) +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal64_t::operator/=(const Decimal rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, Decimal, decimal64_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto decimal64_t::operator%=(const decimal64_t rhs) noexcept -> decimal64_t& +{ + *this = *this % rhs; + return *this; +} + +// 3.6.4 +// Effects: determines if the quantum exponents of x and y are the same. +// If both x and y are NaN, or infinity, they have the same quantum exponents; +// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. +// The samequantum functions raise no exception. +constexpr auto samequantumd64(const decimal64_t lhs, const decimal64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) + { + return true; + } + if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) + { + return false; + } + #endif + + return lhs.unbiased_exponent() == rhs.unbiased_exponent(); +} + +// 3.6.5 +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd64(const decimal64_t x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +// 3.6.6 +// Returns: a number that is equal in value (except for any rounding) and sign to x, +// and which has an exponent set to be equal to the exponent of y. +// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; +// if the result does not have the same value as x, the "inexact" floating-point exception is raised. +// If the exponent is being decreased and the significand of the result has more digits than the type would allow, +// the "invalid" floating-point exception is raised and the result is NaN. +// If one or both operands are NaN the result is NaN. +// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. +// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. +// The quantize functions do not signal underflow. +constexpr auto quantized64(const decimal64_t lhs, const decimal64_t rhs) noexcept -> decimal64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Return the correct type of nan + if (isnan(lhs)) + { + return lhs; + } + if (isnan(rhs)) + { + return rhs; + } + + // If one is infinity then return a signaling NAN + if (isinf(lhs) != isinf(rhs)) + { + return boost::decimal::from_bits(boost::decimal::detail::d64_snan_mask); + } + if (isinf(lhs) && isinf(rhs)) + { + return lhs; + } + #endif + + return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; +} + +constexpr auto scalblnd64(decimal64_t num, const long exp) noexcept -> decimal64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal64_t zero {0, 0}; + + if (num == zero || exp == 0 || not_finite(num)) + { + return num; + } + #endif + + num.edit_exponent(num.biased_exponent() + exp); + + return num; +} + +constexpr auto scalbnd64(const decimal64_t num, const int expval) noexcept -> decimal64_t +{ + return scalblnd64(num, static_cast(expval)); +} + +constexpr auto copysignd64(decimal64_t mag, const decimal64_t sgn) noexcept -> decimal64_t +{ + mag.edit_sign(sgn.isneg()); + return mag; +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal64_t::decimal64_t(const char* str, std::size_t len) +{ + if (str == nullptr || len == 0) + { + bits_ = detail::d64_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal64_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + bits_ = detail::d64_nan_mask; + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal64_t::decimal64_t(const char* str) : decimal64_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal64_t::decimal64_t(const std::string& str) : decimal64_t(str.c_str(), str.size()) {} +#else +constexpr decimal64_t::decimal64_t(std::string_view str) : decimal64_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif //BOOST_DECIMAL_decimal64_t_HPP diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index 1830cf0a3..b6dd09a09 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -1,10 +1,1722 @@ -// Copyright 2025 Matt Borland +// Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL_FAST128_T_HPP -#define BOOST_DECIMAL_DECIMAL_FAST128_T_HPP +#ifndef BOOST_DECIMAL_decimal_fast128_t_HPP +#define BOOST_DECIMAL_decimal_fast128_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL_FAST128_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE + +#include +#include + +#endif + +namespace boost { +namespace decimal { + +namespace detail { + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_inf_high_bits {UINT64_C(0b1) << 61U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_qnan_high_bits {UINT64_C(0b11) << 61U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_snan_high_bits {UINT64_C(0b111) << 61U}; + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_inf = boost::int128::uint128_t {d128_fast_inf_high_bits, 0U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_qnan = boost::int128::uint128_t {d128_fast_qnan_high_bits, 0U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d128_fast_snan = boost::int128::uint128_t {d128_fast_snan_high_bits, 0U}; + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + +} // namespace detail + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) // Structure was padded due to alignment specifier +#endif + +BOOST_DECIMAL_EXPORT class alignas(16) decimal_fast128_t final +{ +public: + using significand_type = int128::uint128_t; + using exponent_type = std::uint32_t; + using biased_exponent_type = std::int32_t; + +private: + // Instead of having to encode and decode at every operation + // we store the constituent pieces directly + + significand_type significand_ {}; + exponent_type exponent_ {}; + bool sign_ {}; + char pad_[11] {}; + + constexpr auto isneg() const noexcept -> bool + { + return sign_; + } + + constexpr auto full_significand() const noexcept -> significand_type + { + return significand_; + } + + constexpr auto unbiased_exponent() const noexcept -> exponent_type + { + return exponent_; + } + + constexpr auto biased_exponent() const noexcept -> biased_exponent_type + { + return static_cast(exponent_) - detail::bias_v; + } + + constexpr auto to_components() const noexcept -> detail::decimal_fast128_t_components + { + return {full_significand(), biased_exponent(), isneg()}; + } + + template + friend constexpr auto to_integral_128(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + friend constexpr auto d128f_div_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, decimal_fast128_t& q, decimal_fast128_t& r) noexcept -> void; + + // Equality template between any integer type and decimal128_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal128_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + friend constexpr auto not_finite(const decimal_fast128_t& val) noexcept -> bool; + + template + friend constexpr auto to_dpd_d128(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, int128::uint128_t); + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_fast_type_v, T, typename T::significand_type); + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal_fast128_t(const char* str, std::size_t len); + #endif + + friend constexpr auto nan_conversion(const decimal_fast128_t& value) noexcept -> decimal_fast128_t + { + constexpr auto convert_nan_mask {detail::d128_fast_qnan ^ detail::d128_fast_snan}; + + decimal_fast128_t return_value {value}; + return_value.significand_ ^= convert_nan_mask; + + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + + template + friend constexpr auto detail::d128_add_impl_new(const T& lhs, const T& rhs) noexcept -> ReturnType; + +public: + constexpr decimal_fast128_t() noexcept = default; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast128_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast128_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast128_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal_fast128_t(bool value) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal_fast128_t(Integer val) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t(long double val) noexcept = delete; + #endif + + friend constexpr auto direct_init_d128(significand_type significand, exponent_type exponent, bool sign) noexcept -> decimal_fast128_t; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + constexpr decimal_fast128_t(const char* str); + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal_fast128_t(const std::string& str); + #else + explicit constexpr decimal_fast128_t(std::string_view str); + #endif + + #endif // BOOST_DECIMAL_DISABLE_CLIB + + // Classification functions + friend constexpr auto signbit(const decimal_fast128_t& val) noexcept -> bool; + friend constexpr auto isinf(const decimal_fast128_t& val) noexcept -> bool; + friend constexpr auto isnan(const decimal_fast128_t& val) noexcept -> bool; + friend constexpr auto issignaling(const decimal_fast128_t& val) noexcept -> bool; + friend constexpr auto isnormal(const decimal_fast128_t& val) noexcept -> bool; + friend constexpr auto isfinite(const decimal_fast128_t& val) noexcept -> bool; + + // Comparison operators + friend constexpr auto operator==(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + friend constexpr auto operator!=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + friend constexpr auto operator<(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + friend constexpr auto operator<=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + friend constexpr auto operator>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + friend constexpr auto operator>=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + + // Mixed comparison operators + template + friend constexpr auto operator==(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + friend constexpr auto operator<=>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + #endif + + // Unary arithmetic operators + friend constexpr auto operator+(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + friend constexpr auto operator-(decimal_fast128_t rhs) noexcept -> decimal_fast128_t; + + // Increment and Decrement + constexpr auto operator++() noexcept -> decimal_fast128_t&; + constexpr auto operator++(int) noexcept -> decimal_fast128_t; // NOLINT : C++14 so constexpr implies const + constexpr auto operator--() noexcept -> decimal_fast128_t&; + constexpr auto operator--(int) noexcept -> decimal_fast128_t; // NOLINT : C++14 so constexpr implies const + + // Binary arithmetic operators + friend constexpr auto operator+(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + friend constexpr auto operator-(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + friend constexpr auto operator*(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + friend constexpr auto operator/(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + friend constexpr auto operator%(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; + + // Mixed type binary arithmetic operators + template + friend constexpr auto operator+(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator+(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator-(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator-(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator*(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator*(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator/(const decimal_fast128_t& lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + template + friend constexpr auto operator/(Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t); + + // Compound Arithmetic Operators + constexpr auto operator+=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; + + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); + + constexpr auto operator-=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); + + constexpr auto operator*=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); + + constexpr auto operator/=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t&; + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&); + + // Conversions + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator int128::int128_t() const noexcept; + explicit constexpr operator int128::uint128_t() const noexcept; + #endif + + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + template , bool> = true> + explicit constexpr operator Decimal() const noexcept; + + // functions that are better as friends + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto copysignd128f(decimal_fast128_t mag, decimal_fast128_t sgn) noexcept -> decimal_fast128_t; + friend constexpr auto scalblnd128f(decimal_fast128_t num, long exp) noexcept -> decimal_fast128_t; + friend constexpr auto scalbnd128f(decimal_fast128_t num, int exp) noexcept -> decimal_fast128_t; + friend constexpr auto fmad128f(decimal_fast128_t x, decimal_fast128_t y, decimal_fast128_t z) noexcept -> decimal_fast128_t; + + // Decimal functions + // 3.6.4 Same Quantum + friend constexpr auto samequantumd128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool; + + // 3.6.5 Quantum exponent + friend constexpr auto quantexpd128f(const decimal_fast128_t& x) noexcept -> int; + + // 3.6.6 Quantize + friend constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t; +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal_fast128_t::decimal_fast128_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept +{ + using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; + + minimum_coefficient_size min_coeff {coeff}; + + const auto is_negative {static_cast(resultant_sign)}; + sign_ = is_negative; + + // Normalize the significand in the constructor, so we don't have + // to calculate the number of digits for operations + detail::normalize(min_coeff, exp, is_negative); + + significand_ = static_cast(min_coeff); + + const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias_v}; + + if (biased_exp > detail::max_biased_exp_v) + { + significand_ = detail::d128_fast_inf; + } + else if (biased_exp >= 0) + { + exponent_ = static_cast(biased_exp); + } + else + { + // Flush denorms to zero + significand_ = static_cast(0); + exponent_ = static_cast(detail::bias_v); + sign_ = false; + } +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal_fast128_t::decimal_fast128_t(const T1 coeff, const T2 exp) noexcept : decimal_fast128_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +constexpr decimal_fast128_t::decimal_fast128_t(const bool value) noexcept : decimal_fast128_t(static_cast(value), 0, false) {} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal_fast128_t::decimal_fast128_t(const Integer val) noexcept : decimal_fast128_t{val, 0} {} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::decimal_fast128_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + significand_ = detail::d128_fast_qnan; + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + significand_ = detail::d128_fast_inf; + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + *this = decimal_fast128_t {components.mantissa, components.exponent, components.sign}; + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +constexpr auto direct_init_d128(const decimal_fast128_t::significand_type significand, + const decimal_fast128_t::exponent_type exponent, + const bool sign) noexcept -> decimal_fast128_t +{ + decimal_fast128_t val {}; + val.significand_ = significand; + val.exponent_ = exponent; + val.sign_ = sign; + + return val; +} + +namespace detail { + +template +class numeric_limits_impl128f +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = true; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 34; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -6143; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 6144; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal_fast128_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal_fast128_t { return {boost::int128::uint128_t{UINT64_C(0x1ED09BEAD87C0), UINT64_C(0x378D8E63FFFFFFFF)}, max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal_fast128_t { return {boost::int128::uint128_t{UINT64_C(0x1ED09BEAD87C0), UINT64_C(0x378D8E63FFFFFFFF)}, max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal_fast128_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal_fast128_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_inf, 0, false); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast128_t { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_snan, 0, false); } + static constexpr auto denorm_min () -> boost::decimal::decimal_fast128_t { return min(); } +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl128f::is_specialized; +template constexpr bool numeric_limits_impl128f::is_signed; +template constexpr bool numeric_limits_impl128f::is_integer; +template constexpr bool numeric_limits_impl128f::is_exact; +template constexpr bool numeric_limits_impl128f::has_infinity; +template constexpr bool numeric_limits_impl128f::has_quiet_NaN; +template constexpr bool numeric_limits_impl128f::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl128f::has_denorm; +template constexpr bool numeric_limits_impl128f::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl128f::round_style; +template constexpr bool numeric_limits_impl128f::is_iec559; +template constexpr bool numeric_limits_impl128f::is_bounded; +template constexpr bool numeric_limits_impl128f::is_modulo; +template constexpr int numeric_limits_impl128f::digits; +template constexpr int numeric_limits_impl128f::digits10; +template constexpr int numeric_limits_impl128f::max_digits10; +template constexpr int numeric_limits_impl128f::radix; +template constexpr int numeric_limits_impl128f::min_exponent; +template constexpr int numeric_limits_impl128f::min_exponent10; +template constexpr int numeric_limits_impl128f::max_exponent; +template constexpr int numeric_limits_impl128f::max_exponent10; +template constexpr bool numeric_limits_impl128f::traps; +template constexpr bool numeric_limits_impl128f::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl128f {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // namespace std + +namespace boost { +namespace decimal { + +constexpr auto signbit(const decimal_fast128_t& val) noexcept -> bool +{ + return val.sign_; +} + +constexpr auto isinf(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_.high == detail::d128_fast_inf_high_bits; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnan(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_.high >= detail::d128_fast_qnan_high_bits; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto issignaling(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_.high >= detail::d128_fast_snan_high_bits; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnormal(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val.exponent_ <= static_cast(detail::precision_v - 1)) + { + return false; + } + + return (val.significand_ != 0U) && isfinite(val); + #else + return val.significand_ != 0U; + #endif +} + +constexpr auto isfinite(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_.high < detail::d128_fast_inf_high_bits; + #else + static_cast(val); + return true; + #endif +} + +BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast128_t& val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_.high >= detail::d128_fast_inf_high_bits; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto operator==(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + return fast_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +constexpr auto operator!=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + return fast_inequality_impl(lhs, rhs); +} + +template +constexpr auto operator!=(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +constexpr auto operator<(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + return fast_less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !less_impl(rhs, lhs) && lhs != rhs; +} + +constexpr auto operator<=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +constexpr auto operator>=(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const decimal_fast128_t& lhs, const Integer rhs) noexcept +BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const Integer lhs, const decimal_fast128_t& rhs) noexcept +BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif + +constexpr auto operator+(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + return rhs; +} + +constexpr auto operator-(decimal_fast128_t rhs) noexcept -> decimal_fast128_t +{ + rhs.sign_ = !rhs.sign_; + return rhs; +} + +constexpr auto operator+(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return direct_init_d128(detail::d128_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::d128_add_impl_new(lhs, rhs); +} + +template +constexpr auto operator+(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + using exp_type = decimal_fast128_t::biased_exponent_type; + using sig_type = decimal_fast128_t::significand_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const detail::decimal_fast128_t_components rhs_components {sig_rhs, exp_rhs, rhs < 0}; + + return detail::d128_add_impl_new(lhs.to_components(), rhs_components); +} + +template +constexpr auto operator+(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + return rhs + lhs; +} + +constexpr auto operator-(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return direct_init_d128(detail::d128_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::d128_add_impl_new(lhs, -rhs); +} + +template +constexpr auto operator-(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + using exp_type = decimal_fast128_t::biased_exponent_type; + using sig_type = decimal_fast128_t::significand_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const detail::decimal_fast128_t_components rhs_components {sig_rhs, exp_rhs, !(rhs < 0)}; + + return detail::d128_add_impl_new(lhs.to_components(), rhs_components); +} + +template +constexpr auto operator-(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + return -rhs + lhs; +} + +constexpr auto operator*(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return direct_init_d128(detail::d128_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::d128_mul_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, + rhs.significand_, rhs.biased_exponent(), rhs.sign_); +} + +template +constexpr auto operator*(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + using exp_type = decimal_fast128_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type rhs_exp {0}; + detail::normalize(rhs_sig, rhs_exp); + + return detail::d128_fast_mul_impl( + lhs.significand_, lhs.biased_exponent(), lhs.sign_, + rhs_sig, rhs_exp, (rhs < 0)); +} + +template +constexpr auto operator*(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + return rhs * lhs; +} + +constexpr auto d128f_div_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, decimal_fast128_t& q, decimal_fast128_t& r) noexcept -> void +{ + const bool sign {lhs.isneg() != rhs.isneg()}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast128_t zero {0, 0}; + constexpr decimal_fast128_t nan {direct_init_d128(detail::d128_fast_qnan, 0, false)}; + constexpr decimal_fast128_t inf {direct_init_d128(detail::d128_fast_inf, 0, false)}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + // NAN has to come first + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal_fast128_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + #else + static_cast(r); + #endif + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "sig lhs: " << sig_lhs + << "\nexp lhs: " << exp_lhs + << "\nsig rhs: " << sig_rhs + << "\nexp rhs: " << exp_rhs << std::endl; + #endif + + constexpr auto ten_pow_precision {detail::pow10(int128::uint128_t(detail::precision_v))}; + const auto big_sig_lhs {detail::umul256(lhs.significand_, ten_pow_precision)}; + + const auto res_sig {big_sig_lhs / rhs.significand_}; + const auto res_exp {lhs.biased_exponent() - rhs.biased_exponent() - detail::precision_v}; + + q = decimal_fast128_t(static_cast(res_sig), res_exp, sign); +} + +constexpr auto d128f_mod_impl(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs, const decimal_fast128_t& q, decimal_fast128_t& r) -> void +{ + constexpr decimal_fast128_t zero {0, 0}; + + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator/(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + decimal_fast128_t q {}; + decimal_fast128_t r {}; + d128f_div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal_fast128_t& lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast128_t zero {0, 0}; + constexpr decimal_fast128_t inf {direct_init_d128(detail::d128_fast_inf, 0, false)}; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs;; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + const detail::decimal_fast128_t_components lhs_components {lhs.significand_, lhs.biased_exponent(), lhs.isneg()}; + + const auto rhs_sig {detail::make_positive_unsigned(rhs)}; + const detail::decimal_fast128_t_components rhs_components {rhs_sig, 0, rhs < 0}; + detail::decimal_fast128_t_components q_components {}; + + detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); + + return {q_components.sig, q_components.exp, q_components.sign}; +} + +template +constexpr auto operator/(const Integer lhs, const decimal_fast128_t& rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast128_t zero {0, 0}; + constexpr decimal_fast128_t inf {direct_init_d128(detail::d128_fast_inf, 0, false)}; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + const detail::decimal_fast128_t_components lhs_components {detail::make_positive_unsigned(lhs), 0, lhs < 0}; + const detail::decimal_fast128_t_components rhs_components {rhs.significand_, rhs.biased_exponent(), rhs.isneg()}; + detail::decimal_fast128_t_components q_components {}; + + detail::d128_generic_div_impl(lhs_components, rhs_components, q_components); + + return {q_components.sig, q_components.exp, q_components.sign}; +} + +constexpr auto operator%(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + decimal_fast128_t q {}; + decimal_fast128_t r {}; + d128f_div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + d128f_mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal_fast128_t::operator+=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal_fast128_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) +{ + *this = *this + rhs; + return *this; +} + +constexpr auto decimal_fast128_t::operator-=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal_fast128_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) +{ + *this = *this - rhs; + return *this; +} + +constexpr auto decimal_fast128_t::operator*=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal_fast128_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) +{ + *this = *this * rhs; + return *this; +} + +constexpr auto decimal_fast128_t::operator/=(const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t& +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal_fast128_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast128_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto decimal_fast128_t::operator++() noexcept -> decimal_fast128_t& +{ + constexpr decimal_fast128_t one {1, 0}; + *this = *this + one; + return *this; +} + +constexpr auto decimal_fast128_t::operator++(int) noexcept -> decimal_fast128_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal_fast128_t::operator--() noexcept -> decimal_fast128_t& +{ + constexpr decimal_fast128_t one {1, 0}; + *this = *this - one; + return *this; +} + +constexpr auto decimal_fast128_t::operator--(int) noexcept -> decimal_fast128_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +constexpr decimal_fast128_t::operator bool() const noexcept +{ + constexpr decimal_fast128_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal_fast128_t::operator int() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator unsigned() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator unsigned long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator long long() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator unsigned long long() const noexcept +{ + return to_integral_128(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal_fast128_t::operator boost::int128::int128_t() const noexcept +{ + return to_integral_128(*this); +} + +constexpr decimal_fast128_t::operator boost::int128::uint128_t() const noexcept +{ + return to_integral_128(*this); +} + +#endif // BOOST_DECIMAL_HAS_INT128 + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::operator long double() const noexcept +{ + return to_float(*this); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal_fast128_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal_fast128_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal_fast128_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal_fast128_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +template , bool>> +constexpr decimal_fast128_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +constexpr auto copysignd128f(decimal_fast128_t mag, const decimal_fast128_t sgn) noexcept -> decimal_fast128_t +{ + mag.sign_ = sgn.sign_; + return mag; +} + +constexpr auto scalblnd128f(decimal_fast128_t num, const long exp) noexcept -> decimal_fast128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal_fast128_t zero {0, 0}; + + if (num == zero || exp == 0 || not_finite(num)) + { + return num; + } + #endif + + num = decimal_fast128_t(num.significand_, num.biased_exponent() + exp, num.sign_); + + return num; +} + +constexpr auto scalbnd128f(const decimal_fast128_t num, const int exp) noexcept -> decimal_fast128_t +{ + return scalblnd128f(num, static_cast(exp)); +} + +// 3.6.4 +// Effects: determines if the quantum exponents of x and y are the same. +// If both x and y are NaN, or infinity, they have the same quantum exponents; +// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. +// The samequantum functions raise no exception. +constexpr auto samequantumd128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) + { + return true; + } + if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) + { + return false; + } + #endif + + return lhs.unbiased_exponent() == rhs.unbiased_exponent(); +} + +// 3.6.5 +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd128f(const decimal_fast128_t& x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +// 3.6.6 +// Returns: a number that is equal in value (except for any rounding) and sign to x, +// and which has an exponent set to be equal to the exponent of y. +// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; +// if the result does not have the same value as x, the "inexact" floating-point exception is raised. +// If the exponent is being decreased and the significand of the result has more digits than the type would allow, +// the "invalid" floating-point exception is raised and the result is NaN. +// If one or both operands are NaN the result is NaN. +// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. +// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. +// The quantize functions do not signal underflow. +constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128_t& rhs) noexcept -> decimal_fast128_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Return the correct type of nan + if (isnan(lhs)) + { + return lhs; + } + else if (isnan(rhs)) + { + return rhs; + } + + // If one is infinity then return a signaling NAN + if (isinf(lhs) != isinf(rhs)) + { + return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false); + } + else if (isinf(lhs) && isinf(rhs)) + { + return lhs; + } + #endif + + return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal_fast128_t::decimal_fast128_t(const char* str, const std::size_t len) +{ + if (str == nullptr || len == 0) + { + *this = direct_init_d128(detail::d128_fast_qnan, 0, false); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal_fast128_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + *this = direct_init_d128(detail::d128_fast_qnan, 0, false); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal_fast128_t::decimal_fast128_t(const char* str) : decimal_fast128_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal_fast128_t::decimal_fast128_t(const std::string& str) : decimal_fast128_t(str.c_str(), str.size()) {} +#else +constexpr decimal_fast128_t::decimal_fast128_t(std::string_view str) : decimal_fast128_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif //BOOST_DECIMAL_decimal_fast128_t_HPP diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index e6d17ac8f..bd159dbe5 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -1,10 +1,1714 @@ -// Copyright 2025 Matt Borland +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL_FAST32_T_HPP -#define BOOST_DECIMAL_DECIMAL_FAST32_T_HPP +#ifndef BOOST_DECIMAL_decimal_fast32_t_HPP +#define BOOST_DECIMAL_decimal_fast32_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL_FAST32_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE +#include +#include +#endif + +namespace boost { +namespace decimal { + +namespace detail { + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d32_fast_inf {UINT32_C(0b1) << 29U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d32_fast_qnan {UINT32_C(0b11) << 29U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d32_fast_snan {UINT32_C(0b111) << 29U}; + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto d32_fma_impl(T x, T y, T z) noexcept -> T; + +template +constexpr auto write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + +} // namespace detail + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) // Structure was padded due to alignment specifier +#endif + +BOOST_DECIMAL_EXPORT class alignas(4) decimal_fast32_t final +{ +public: + using significand_type = std::uint32_t; + using exponent_type = std::uint8_t; + using biased_exponent_type = std::int32_t; + +private: + // In regular decimal32_t we have to decode the 24 bits of the significand and the 8 bits of the exp + // Here we just use them directly at the cost of at least 2 extra bytes of internal state + // since the fast integer types will be at least 32 and 8 bits respectively + + significand_type significand_ {}; + exponent_type exponent_ {}; + bool sign_ {}; + char pad_[2] {}; + + constexpr auto isneg() const noexcept -> bool + { + return sign_; + } + + constexpr auto full_significand() const noexcept -> significand_type + { + return significand_; + } + + constexpr auto unbiased_exponent() const noexcept -> exponent_type + { + return exponent_; + } + + constexpr auto biased_exponent() const noexcept -> biased_exponent_type + { + return static_cast(exponent_) - detail::bias_v; + } + + constexpr auto to_components() const noexcept -> detail::decimal_fast32_t_components + { + return {full_significand(), biased_exponent(), isneg()}; + } + + friend constexpr auto div_impl(decimal_fast32_t lhs, decimal_fast32_t rhs, decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void; + + friend constexpr auto mod_impl(decimal_fast32_t lhs, decimal_fast32_t rhs, const decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void; + + // Attempts conversion to integral type: + // If this is nan sets errno to EINVAL and returns 0 + // If this is not representable sets errno to ERANGE and returns 0 + template + friend constexpr auto to_integral(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + // Equality template between any integer type and decimal32_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal32_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + template + friend constexpr auto to_dpd_d32(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint32_t); + + template + friend constexpr auto detail::add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; + + template + friend constexpr auto detail::mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + friend constexpr auto not_finite(const decimal_fast32_t& val) noexcept -> bool; + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::generic_div_impl(const T& lhs, const T& rhs) noexcept -> DecimalType; + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_fast_type_v, T, typename T::significand_type); + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal_fast32_t(const char* str, std::size_t len); + #endif + + friend constexpr auto nan_conversion(const decimal_fast32_t value) noexcept -> decimal_fast32_t + { + constexpr auto convert_nan_mask {detail::d32_fast_qnan ^ detail::d32_fast_snan}; + + decimal_fast32_t return_value {value}; + return_value.significand_ ^= convert_nan_mask; + + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + +public: + constexpr decimal_fast32_t() noexcept = default; + + template && detail::is_integral_v, bool> = true> + constexpr decimal_fast32_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + template && detail::is_integral_v, bool> = true> + constexpr decimal_fast32_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + template && detail::is_integral_v, bool> = true> + constexpr decimal_fast32_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal_fast32_t(bool value) noexcept; + + template , bool> = true> + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal_fast32_t(Integer coeff) noexcept; + + template , bool> = true> + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit constexpr decimal_fast32_t(long double val) noexcept = delete; + #endif + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + explicit constexpr decimal_fast32_t(const char* str); + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal_fast32_t(const std::string& str); + #else + explicit constexpr decimal_fast32_t(std::string_view str); + #endif + + #endif // BOOST_DECIMAL_DISABLE_CLIB + + constexpr decimal_fast32_t(const decimal_fast32_t& val) noexcept = default; + constexpr decimal_fast32_t(decimal_fast32_t&& val) noexcept = default; + constexpr auto operator=(const decimal_fast32_t& val) noexcept -> decimal_fast32_t& = default; + constexpr auto operator=(decimal_fast32_t&& val) noexcept -> decimal_fast32_t& = default; + + // cmath functions that are easier as friends + friend constexpr auto signbit(decimal_fast32_t val) noexcept -> bool; + friend constexpr auto isinf(decimal_fast32_t val) noexcept -> bool; + friend constexpr auto isnan(decimal_fast32_t val) noexcept -> bool; + friend constexpr auto issignaling(decimal_fast32_t val) noexcept -> bool; + friend constexpr auto isnormal(decimal_fast32_t val) noexcept -> bool; + friend constexpr auto isfinite(decimal_fast32_t val) noexcept -> bool; + + // Comparison operators + friend constexpr auto operator==(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto operator!=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto operator<(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto operator<=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto operator>(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto operator>=(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + + // Mixed comparisons + template + friend constexpr auto operator==(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + + friend constexpr auto operator<=>(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + #endif + + // Unary operators + friend constexpr auto operator+(decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + friend constexpr auto operator-(decimal_fast32_t lhs) noexcept -> decimal_fast32_t; + + // Binary arithmetic + friend constexpr auto operator+(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + friend constexpr auto operator-(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + friend constexpr auto operator*(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + friend constexpr auto operator/(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + friend constexpr auto operator%(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; + + // Mixed type binary arithmetic + template + friend constexpr auto operator+(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator+(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator-(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator-(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator*(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator*(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator/(decimal_fast32_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + template + friend constexpr auto operator/(Integer lhs, decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t); + + // Compound operators + constexpr auto operator+=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; + constexpr auto operator-=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; + constexpr auto operator*=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; + constexpr auto operator/=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; + constexpr auto operator%=(decimal_fast32_t rhs) noexcept -> decimal_fast32_t&; + + // Mixed type compound operators + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&); + + // Increment and decrement + constexpr auto operator++() noexcept -> decimal_fast32_t&; + constexpr auto operator++(int) noexcept -> decimal_fast32_t; + constexpr auto operator--() noexcept -> decimal_fast32_t&; + constexpr auto operator--(int) noexcept -> decimal_fast32_t; + + // 3.2.2.4 Conversion to integral type + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator detail::builtin_int128_t() const noexcept; + explicit constexpr operator detail::builtin_uint128_t() const noexcept; + #endif + + // 3.2.6 Conversion to a floating-point type + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + + // Conversion to another decimal type + template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> + constexpr operator Decimal() const noexcept; + + template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> + explicit constexpr operator Decimal() const noexcept; + + friend constexpr auto direct_init(significand_type significand, exponent_type exponent, bool sign) noexcept -> decimal_fast32_t; + friend constexpr auto direct_init(const detail::decimal_fast32_t_components& x) noexcept -> decimal_fast32_t; + + // or extensions that need to be friends + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto copysignd32f(decimal_fast32_t mag, decimal_fast32_t sgn) noexcept -> decimal_fast32_t; + friend constexpr auto scalbnd32f(decimal_fast32_t num, int exp) noexcept -> decimal_fast32_t; + friend constexpr auto scalblnd32f(decimal_fast32_t num, long exp) noexcept -> decimal_fast32_t; + + template + friend constexpr auto detail::d32_fma_impl(T x, T y, T z) noexcept -> T; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + // Specific decimal functionality + friend constexpr auto samequantumd32f(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> bool; + friend constexpr auto quantexpd32f(decimal_fast32_t x) noexcept -> int; + friend constexpr auto quantized32f(decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t; +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +template && detail::is_integral_v, bool>> +constexpr decimal_fast32_t::decimal_fast32_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept +{ + using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; + + minimum_coefficient_size min_coeff {coeff}; + + const auto is_negative {static_cast(resultant_sign)}; + sign_ = is_negative; + + // Normalize in the constructor, so we never have to worry about it again + detail::normalize(min_coeff, exp, is_negative); + + significand_ = static_cast(min_coeff); + + const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias}; + + // decimal32_t exponent holds 8 bits + if (biased_exp > detail::max_biased_exp_v) + { + significand_ = detail::d32_fast_inf; + } + else if (biased_exp >= 0) + { + exponent_ = static_cast(biased_exp); + } + else + { + // Flush denorms to zero + significand_ = static_cast(0); + exponent_ = static_cast(detail::bias); + sign_ = false; + } +} + +template && detail::is_integral_v, bool>> +constexpr decimal_fast32_t::decimal_fast32_t(const T1 coeff, const T2 exp) noexcept : decimal_fast32_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +constexpr decimal_fast32_t::decimal_fast32_t(const bool value) noexcept : decimal_fast32_t(static_cast(value), 0, false) {} + +template , bool>> +constexpr decimal_fast32_t::decimal_fast32_t(const Integer val) noexcept : decimal_fast32_t{val, 0} {} + +constexpr auto direct_init(const decimal_fast32_t::significand_type significand, const decimal_fast32_t::exponent_type exponent, const bool sign = false) noexcept -> decimal_fast32_t +{ + decimal_fast32_t val; + val.significand_ = significand; + val.exponent_ = exponent; + val.sign_ = sign; + + return val; +} + +constexpr auto direct_init(const detail::decimal_fast32_t_components& x) noexcept -> decimal_fast32_t +{ + decimal_fast32_t val; + val.significand_ = x.sig; + val.exponent_ = static_cast(static_cast(x.exp) + detail::bias_v); + val.sign_ = x.sign; + + return val; +} + +namespace detail { + +template +class numeric_limits_impl32f +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_absent; + static constexpr bool has_denorm_loss = false; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 7; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -95; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 96; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal_fast32_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal_fast32_t { return {UINT32_C(9'999'999), max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal_fast32_t { return {UINT32_C(9'999'999), max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal_fast32_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal_fast32_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_inf, UINT8_C((0))); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_qnan, UINT8_C((0))); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast32_t { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_snan, UINT8_C((0))); } + + // With denorm absent returns the same value as min + static constexpr auto denorm_min () -> boost::decimal::decimal_fast32_t { return min(); } +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl32f::is_specialized; +template constexpr bool numeric_limits_impl32f::is_signed; +template constexpr bool numeric_limits_impl32f::is_integer; +template constexpr bool numeric_limits_impl32f::is_exact; +template constexpr bool numeric_limits_impl32f::has_infinity; +template constexpr bool numeric_limits_impl32f::has_quiet_NaN; +template constexpr bool numeric_limits_impl32f::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl32f::has_denorm; +template constexpr bool numeric_limits_impl32f::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl32f::round_style; +template constexpr bool numeric_limits_impl32f::is_iec559; +template constexpr bool numeric_limits_impl32f::is_bounded; +template constexpr bool numeric_limits_impl32f::is_modulo; +template constexpr int numeric_limits_impl32f::digits; +template constexpr int numeric_limits_impl32f::digits10; +template constexpr int numeric_limits_impl32f::max_digits10; +template constexpr int numeric_limits_impl32f::radix; +template constexpr int numeric_limits_impl32f::min_exponent; +template constexpr int numeric_limits_impl32f::min_exponent10; +template constexpr int numeric_limits_impl32f::max_exponent; +template constexpr int numeric_limits_impl32f::max_exponent10; +template constexpr bool numeric_limits_impl32f::traps; +template constexpr bool numeric_limits_impl32f::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl32f {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // Namespace std + +namespace boost { +namespace decimal { + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +template , bool>> +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::decimal_fast32_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + significand_ = detail::d32_fast_qnan; + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + significand_ = detail::d32_fast_inf; + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + *this = decimal_fast32_t {components.mantissa, components.exponent, components.sign}; + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +constexpr auto signbit(const decimal_fast32_t val) noexcept -> bool +{ + return val.sign_; +} + +constexpr auto isinf(const decimal_fast32_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ == detail::d32_fast_inf; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnan(const decimal_fast32_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ >= detail::d32_fast_qnan; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto issignaling(const decimal_fast32_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ >= detail::d32_fast_snan; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnormal(const decimal_fast32_t val) noexcept -> bool +{ + return (val.significand_ != 0) + #ifndef BOOST_DECIMAL_FAST_MATH + && isfinite(val) && (val.exponent_ > static_cast(detail::precision_v - 1)) + #endif + ; +} + +constexpr auto isfinite(const decimal_fast32_t val) noexcept -> bool +{ + return val.significand_ < detail::d32_fast_inf; +} + +BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast32_t& val) noexcept -> bool +{ + return val.significand_ >= detail::d32_fast_inf; +} + +constexpr auto operator==(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + return fast_equality_impl(lhs, rhs); +} + +constexpr auto operator!=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + return fast_inequality_impl(lhs, rhs); +} + +constexpr auto operator<(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + return fast_less_impl(lhs, rhs); +} + +constexpr auto operator<=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + return rhs < lhs; +} + +constexpr auto operator>=(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator==(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +template +constexpr auto operator!=(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator<(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(rhs) ? false : !less_impl(rhs, lhs) && lhs != rhs; + #else + return !less_impl(rhs, lhs) && lhs != rhs; + #endif +} + +template +constexpr auto operator<=(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(lhs) ? false : !(rhs < lhs); + #else + return !(rhs < lhs); + #endif +} + +template +constexpr auto operator<=(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(rhs) ? false : !(rhs < lhs); + #else + return !(rhs < lhs); + #endif +} + +template +constexpr auto operator>(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(lhs) ? false : rhs < lhs; + #else + return rhs < lhs; + #endif +} + +template +constexpr auto operator>(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(rhs) ? false : rhs < lhs; + #else + return rhs < lhs; + #endif +} + +template +constexpr auto operator>=(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(lhs) ? false : !(lhs < rhs); + #else + return !(lhs < rhs); // LCOV_EXCL_LINE + #endif +} + +template +constexpr auto operator>=(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return isnan(rhs) ? false : !(lhs < rhs); + #else + return !(lhs < rhs); + #endif +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif + +constexpr auto operator+(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + return rhs; +} + +constexpr auto operator-(decimal_fast32_t lhs) noexcept -> decimal_fast32_t +{ + lhs.sign_ = !lhs.sign_; + return lhs; +} + +constexpr auto operator+(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return direct_init(detail::d32_fast_qnan, UINT8_C((0))); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::add_impl(lhs, rhs); +} + +template +constexpr auto operator+(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; + + return detail::add_impl( + detail::decimal_fast32_t_components{lhs.significand_, lhs.biased_exponent(), lhs.sign_}, + detail::decimal_fast32_t_components{final_sig_rhs, exp_rhs, (rhs < 0)} + ); +} + +template +constexpr auto operator+(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + return rhs + lhs; +} + +constexpr auto operator-(const decimal_fast32_t lhs, decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return direct_init(detail::d32_fast_qnan, UINT8_C((0))); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + rhs.sign_ = !rhs.sign_; + + return detail::add_impl(lhs, rhs); +} + +template +constexpr auto operator-(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + auto final_sig_rhs {static_cast(detail::make_positive_unsigned(sig_rhs))}; + + return detail::add_impl( + detail::decimal_fast32_t_components{lhs.significand_, lhs.biased_exponent(), lhs.sign_}, + detail::decimal_fast32_t_components{final_sig_rhs, exp_rhs, !(rhs < 0)} + ); +} + +template +constexpr auto operator-(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; + + exp_type exp_lhs {0}; + detail::normalize(sig_lhs, exp_lhs); + auto final_sig_lhs {static_cast(detail::make_positive_unsigned(sig_lhs))}; + + return detail::add_impl( + detail::decimal_fast32_t_components{final_sig_lhs, exp_lhs, (lhs < 0)}, + detail::decimal_fast32_t_components{rhs.significand_, rhs.biased_exponent(), !rhs.sign_} + ); +} + +constexpr auto operator*(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs) || !isfinite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return direct_init(detail::d32_fast_qnan, UINT8_C(0)); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::mul_impl(lhs, rhs); +} + +template +constexpr auto operator*(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + + // We don't know if the original value of rhs fits into the decimal_fast32_t significand type + // but once it's normalized it's guaranteed to fit + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::mul_impl(lhs.significand_, lhs.biased_exponent(), lhs.sign_, + final_sig_rhs, exp_rhs, (rhs < 0)); +} + +template +constexpr auto operator*(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + return rhs * lhs; +} + +constexpr auto div_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs, decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal_fast32_t zero {0, 0}; + + const bool sign {lhs.isneg() != rhs.isneg()}; + constexpr decimal_fast32_t nan {direct_init(detail::d32_fast_qnan, UINT8_C(0), false)}; + constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal_fast32_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + #else + static_cast(r); + #endif + + q = detail::generic_div_impl(lhs, rhs); +} + +constexpr auto mod_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs, const decimal_fast32_t& q, decimal_fast32_t& r) noexcept -> void +{ + constexpr decimal_fast32_t zero {0, 0}; + + // https://en.cppreference.com/w/cpp/numeric/math/fmod + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator/(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + decimal_fast32_t q {}; + decimal_fast32_t r {}; + div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal_fast32_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast32_t zero {0, 0}; + constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + const detail::decimal_fast32_t_components lhs_components {lhs.significand_, lhs.biased_exponent(), lhs.sign_}; + exp_type exp_rhs {}; + const detail::decimal_fast32_t_components rhs_components {detail::shrink_significand(detail::make_positive_unsigned(rhs), exp_rhs), exp_rhs, rhs < 0}; + + return detail::generic_div_impl(lhs_components, rhs_components); +} + +template +constexpr auto operator/(const Integer lhs, const decimal_fast32_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t) +{ + using exp_type = decimal_fast32_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast32_t zero {0, 0}; + constexpr decimal_fast32_t inf {direct_init(detail::d32_fast_inf, UINT8_C(0), false)}; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + exp_type lhs_exp {}; + const auto lhs_sig {detail::make_positive_unsigned(detail::shrink_significand(lhs, lhs_exp))}; + const detail::decimal_fast32_t_components lhs_components {lhs_sig, lhs_exp, lhs < 0}; + const detail::decimal_fast32_t_components rhs_components {rhs.significand_, rhs.biased_exponent(), rhs.isneg()}; + + return detail::generic_div_impl(lhs_components, rhs_components); +} + +constexpr auto operator%(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + decimal_fast32_t q {}; + decimal_fast32_t r {}; + div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal_fast32_t::operator%=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& +{ + *this = *this % rhs; + return *this; +} + +constexpr auto decimal_fast32_t::operator+=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& +{ + *this = *this + rhs; + return *this; +} + +constexpr auto decimal_fast32_t::operator-=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& +{ + *this = *this - rhs; + return *this; +} + +constexpr auto decimal_fast32_t::operator*=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& +{ + *this = *this * rhs; + return *this; +} + +constexpr auto decimal_fast32_t::operator/=(const decimal_fast32_t rhs) noexcept -> decimal_fast32_t& +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal_fast32_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal_fast32_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal_fast32_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) +{ + *this = *this * rhs; // LCOV_EXCL_LINE : False negative + return *this; +} + +template +constexpr auto decimal_fast32_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast32_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto decimal_fast32_t::operator++() noexcept -> decimal_fast32_t& +{ + constexpr decimal_fast32_t one(1, 0); + *this = *this + one; + return *this; +} + +constexpr auto decimal_fast32_t::operator++(int) noexcept -> decimal_fast32_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal_fast32_t::operator--() noexcept -> decimal_fast32_t& +{ + constexpr decimal_fast32_t one(1, 0); + *this = *this - one; + return *this; +} + +constexpr auto decimal_fast32_t::operator--(int) noexcept -> decimal_fast32_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +constexpr decimal_fast32_t::operator bool() const noexcept +{ + constexpr decimal_fast32_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal_fast32_t::operator int() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator unsigned() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator unsigned long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator long long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator unsigned long long() const noexcept +{ + return to_integral(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal_fast32_t::operator detail::builtin_int128_t() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast32_t::operator detail::builtin_uint128_t() const noexcept +{ + return to_integral(*this); +} + +#endif + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::operator long double() const noexcept +{ + // The precision and range of double already exceeds what decimal_fast32_t can provide + return static_cast(to_float(*this)); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal_fast32_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal_fast32_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal_fast32_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal_fast32_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +template && (detail::decimal_val_v > detail::decimal_val_v), bool>> +constexpr decimal_fast32_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> +constexpr decimal_fast32_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +constexpr auto scalblnd32f(const decimal_fast32_t num, const long exp) noexcept -> decimal_fast32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal_fast32_t zero {0, 0}; + + if (num == zero || exp == 0 || !isfinite(num)) + { + return num; + } + #endif + + const auto res {decimal_fast32_t(num.significand_, num.biased_exponent() + exp, num.sign_)}; + + return res; +} + +constexpr auto scalbnd32f(const decimal_fast32_t num, const int expval) noexcept -> decimal_fast32_t +{ + return scalblnd32f(num, static_cast(expval)); +} + +constexpr auto copysignd32f(decimal_fast32_t mag, const decimal_fast32_t sgn) noexcept -> decimal_fast32_t +{ + mag.sign_ = sgn.sign_; + return mag; +} + +// Effects: determines if the quantum exponents of x and y are the same. +// If both x and y are NaN, or infinity, they have the same quantum exponents; +// if exactly one operand is infinity or exactly one operand is NaN, they do not have the same quantum exponents. +// The samequantum functions raise no exception. +constexpr auto samequantumd32f(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if ((lhs_fp == FP_NAN && rhs_fp == FP_NAN) || (lhs_fp == FP_INFINITE && rhs_fp == FP_INFINITE)) + { + return true; + } + if ((lhs_fp == FP_NAN || rhs_fp == FP_INFINITE) || (rhs_fp == FP_NAN || lhs_fp == FP_INFINITE)) + { + return false; + } + #endif + + return lhs.unbiased_exponent() == rhs.unbiased_exponent(); +} + +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd32f(const decimal_fast32_t x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +// Returns: a number that is equal in value (except for any rounding) and sign to x, +// and which has an exponent set to be equal to the exponent of y. +// If the exponent is being increased, the value is correctly rounded according to the current rounding mode; +// if the result does not have the same value, as x, the "inexact" floating-point exception is raised. +// If the exponent is being decreased and the significand of the result has more digits than the type would allow, +// the "invalid" floating-point exception is raised and the result is NaN. +// If one or both operands are NaN, the result is NaN. +// Otherwise, if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. +// If both operands are infinity, the result is DEC_INFINITY, with the same sign as x, converted to the type of x. +// The quantize functions do not signal underflow. +constexpr auto quantized32f(const decimal_fast32_t lhs, const decimal_fast32_t rhs) noexcept -> decimal_fast32_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + // Return the correct type of nan + if (isnan(lhs)) + { + return lhs; + } + else if (isnan(rhs)) + { + return rhs; + } + + // If one is infinity then return a signaling NAN + if (isinf(lhs) != isinf(rhs)) + { + return direct_init(detail::d32_fast_snan, UINT8_C(0)); + } + else if (isinf(lhs) && isinf(rhs)) + { + return lhs; + } + #endif + + return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal_fast32_t::decimal_fast32_t(const char* str, const std::size_t len) +{ + if (str == nullptr || len == 0) + { + *this = direct_init(detail::d32_fast_qnan, UINT8_C((0))); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal_fast32_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + *this = direct_init(detail::d32_fast_qnan, UINT8_C((0))); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal_fast32_t::decimal_fast32_t(const char* str) : decimal_fast32_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal_fast32_t::decimal_fast32_t(const std::string& str) : decimal_fast32_t(str.c_str(), str.size()) {} +#else +constexpr decimal_fast32_t::decimal_fast32_t(std::string_view str) : decimal_fast32_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif //BOOST_DECIMAL_decimal_fast32_t_HPP diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index 72ed77f79..23aa5efa6 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -1,10 +1,1692 @@ -// Copyright 2025 Matt Borland +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DECIMAL_DECIMAL_FAST64_T_HPP -#define BOOST_DECIMAL_DECIMAL_FAST64_T_HPP +#ifndef BOOST_DECIMAL_decimal_fast64_t_HPP +#define BOOST_DECIMAL_decimal_fast64_t_HPP -#include +#include +#include +#include +#include +#include +#include "detail/int128.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif // BOOST_DECIMAL_DECIMAL_FAST64_T_HPP +#ifndef BOOST_DECIMAL_BUILD_MODULE + +#include +#include + +#endif + +namespace boost { +namespace decimal { + +namespace detail { + +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d64_fast_inf {UINT64_C(0b1) << 61U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d64_fast_qnan {UINT64_C(0b11) << 61U}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto d64_fast_snan {UINT64_C(0b111) << 61U}; + +template +constexpr auto to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + +template +constexpr auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + +template +constexpr auto d64_fma_impl(T x, T y, T z) noexcept -> T; + +template +constexpr auto write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + +} // namespace detail + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) // Structure was padded due to alignment specifier +#endif + +BOOST_DECIMAL_EXPORT class alignas(8) decimal_fast64_t final +{ +public: + using significand_type = std::uint64_t; + using exponent_type = std::uint16_t; + using biased_exponent_type = std::int32_t; + +private: + // In regular decimal64_t we have to decode the significand end exponent + // Here we will store them directly to avoid the overhead of decoding + + significand_type significand_ {}; + exponent_type exponent_ {}; + bool sign_ {}; + char pad_[5] {}; + + constexpr auto isneg() const noexcept -> bool + { + return sign_; + } + + constexpr auto full_significand() const noexcept -> significand_type + { + return significand_; + } + + constexpr auto unbiased_exponent() const noexcept -> exponent_type + { + return exponent_; + } + + constexpr auto biased_exponent() const noexcept -> biased_exponent_type + { + return static_cast(exponent_) - detail::bias_v; + } + + constexpr auto to_components() const noexcept -> detail::decimal_fast64_t_components + { + return {full_significand(), biased_exponent(), isneg()}; + } + + // Equality template between any integer type and decimal32_t + template + friend constexpr auto mixed_equality_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_equality_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + // Template to compare operator< for any integer type and decimal32_t + template + friend constexpr auto less_impl(Decimal lhs, Integer rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && detail::is_integral_v), bool>; + + template + friend constexpr auto mixed_decimal_less_impl(Decimal1 lhs, Decimal2 rhs) noexcept + -> std::enable_if_t<(detail::is_decimal_floating_point_v && + detail::is_decimal_floating_point_v), bool>; + + template + friend constexpr auto to_integral(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_integral_v, TargetType, TargetType); + + template + friend BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, Decimal, detail::is_floating_point_v, TargetType, TargetType); + + template + friend constexpr auto to_decimal(Decimal val) noexcept -> TargetType; + + friend constexpr auto d64_fast_div_impl(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs, decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void; + + template + friend constexpr auto ilogb(T d) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, int); + + template + friend constexpr auto logb(T num) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T); + + friend constexpr auto not_finite(decimal_fast64_t val) noexcept -> bool; + + template + friend constexpr auto to_dpd_d64(DecimalType val) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t); + + template + friend constexpr auto detail::add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; + + template + friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_equality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_inequality_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + BOOST_DECIMAL_FORCE_INLINE friend constexpr auto fast_less_equal_impl(const DecimalType& lhs, const DecimalType& rhs) noexcept -> bool; + + template + friend constexpr auto detail::nextafter_impl(DecimalType val, bool direction) noexcept -> DecimalType; + + template + friend constexpr auto detail::to_chars_scientific_impl(char* first, char* last, const TargetDecimalType& value, chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_fixed_impl(char* first, char* last, const TargetDecimalType& value, const chars_format fmt) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::to_chars_cohort_preserving_scientific(char* first, char* last, const TargetDecimalType& value) noexcept -> to_chars_result; + + template + friend constexpr auto detail::d64_fma_impl(T x, T y, T z) noexcept -> T; + + template + friend constexpr auto detail::write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType); + + template + friend constexpr auto read_payload(T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_fast_type_v, T, typename T::significand_type); + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + constexpr decimal_fast64_t(const char* str, std::size_t len); + #endif + + friend constexpr auto nan_conversion(const decimal_fast64_t value) noexcept -> decimal_fast64_t + { + constexpr auto convert_nan_mask {detail::d64_fast_qnan ^ detail::d64_fast_snan}; + + decimal_fast64_t return_value {value}; + return_value.significand_ ^= convert_nan_mask; + + return return_value; + } + + template + friend constexpr Decimal detail::check_non_finite(Decimal lhs, Decimal rhs) noexcept; + + template + friend constexpr Decimal detail::check_non_finite(Decimal x) noexcept; + +public: + constexpr decimal_fast64_t() noexcept = default; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast64_t(T1 coeff, T2 exp, detail::construction_sign_wrapper resultant_sign = construction_sign::positive) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast64_t(T1, T2, bool) noexcept { static_assert(detail::is_unsigned_v, "Construction from signed integer, exponent, and sign is ambiguous, so it is disallowed. You must use an Unsigned Integer for the coefficient to construct from {coefficient, exponent, sign}"); } + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template && detail::is_integral_v, bool> = true> + #endif + constexpr decimal_fast64_t(T1 coeff, T2 exp) noexcept; + + explicit constexpr decimal_fast64_t(bool value) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS) + explicit + #endif + constexpr decimal_fast64_t(Integer val) noexcept; + + #ifdef BOOST_DECIMAL_HAS_CONCEPTS + template + #else + template , bool> = true> + #endif + #if !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_CONVERSIONS) && !defined(BOOST_DECIMAL_ALLOW_IMPLICIT_FLOAT_CONVERSIONS) + explicit + #endif + BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t(Float val) noexcept; + + #ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit constexpr decimal_fast64_t(long double val) noexcept = delete; + #endif + + friend constexpr auto direct_init_d64(decimal_fast64_t::significand_type significand, decimal_fast64_t::exponent_type exponent, bool sign) noexcept -> decimal_fast64_t; + + #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + + explicit constexpr decimal_fast64_t(const char* str); + + #ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW + explicit inline decimal_fast64_t(const std::string& str); + #else + explicit constexpr decimal_fast64_t(std::string_view str); + #endif + + #endif // BOOST_DECIMAL_DISABLE_CLIB + + // Classification functions + friend constexpr auto signbit(decimal_fast64_t val) noexcept -> bool; + friend constexpr auto isinf(decimal_fast64_t val) noexcept -> bool; + friend constexpr auto isnan(decimal_fast64_t val) noexcept -> bool; + friend constexpr auto issignaling(decimal_fast64_t val) noexcept -> bool; + friend constexpr auto isnormal(decimal_fast64_t val) noexcept -> bool; + friend constexpr auto isfinite(decimal_fast64_t val) noexcept -> bool; + + // Comparison operator + friend constexpr auto operator==(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + friend constexpr auto operator!=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + friend constexpr auto operator<(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + friend constexpr auto operator<=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + friend constexpr auto operator>(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + friend constexpr auto operator>=(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> bool; + + // Mixed type comparison operators + template + friend constexpr auto operator==(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator==(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator!=(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator<=(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + template + friend constexpr auto operator>=(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool); + + // C++20 Spaceship operator + #ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + friend constexpr auto operator<=>(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> std::partial_ordering; + + template + friend constexpr auto operator<=>(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + + template + friend constexpr auto operator<=>(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering); + #endif + + // Conversions + explicit constexpr operator bool() const noexcept; + explicit constexpr operator int() const noexcept; + explicit constexpr operator unsigned() const noexcept; + explicit constexpr operator long() const noexcept; + explicit constexpr operator unsigned long() const noexcept; + explicit constexpr operator long long() const noexcept; + explicit constexpr operator unsigned long long() const noexcept; + + #ifdef BOOST_DECIMAL_HAS_INT128 + explicit constexpr operator detail::builtin_int128_t() const noexcept; + explicit constexpr operator detail::builtin_uint128_t() const noexcept; + #endif + + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept; + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept; + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept; + #endif + + #ifdef BOOST_DECIMAL_HAS_FLOAT16 + explicit constexpr operator std::float16_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT32 + explicit constexpr operator std::float32_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_FLOAT64 + explicit constexpr operator std::float64_t() const noexcept; + #endif + #ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 + explicit constexpr operator std::bfloat16_t() const noexcept; + #endif + + // Conversion to other decimal type + template && (detail::decimal_val_v > detail::decimal_val_v), bool> = true> + constexpr operator Decimal() const noexcept; + + template && (detail::decimal_val_v <= detail::decimal_val_v), bool> = true> + explicit constexpr operator Decimal() const noexcept; + + // Unary Operators + friend constexpr auto operator+(decimal_fast64_t val) noexcept -> decimal_fast64_t; + friend constexpr auto operator-(decimal_fast64_t val) noexcept -> decimal_fast64_t; + + // Basic arithmetic operators + friend constexpr auto operator+(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; + friend constexpr auto operator-(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; + friend constexpr auto operator*(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; + friend constexpr auto operator/(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs) noexcept -> decimal_fast64_t; + friend constexpr auto operator%(decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t; + + // Mixed type arithmetic operators + template + friend constexpr auto operator+(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator+(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator-(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator-(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator*(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator*(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator/(decimal_fast64_t lhs, Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + template + friend constexpr auto operator/(Integer lhs, decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t); + + // Compound Operators + constexpr auto operator+=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; + constexpr auto operator-=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; + constexpr auto operator*=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; + constexpr auto operator/=(decimal_fast64_t rhs) noexcept -> decimal_fast64_t&; + + // Mixed type compound operators + template + constexpr auto operator+=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); + + template + constexpr auto operator-=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); + + template + constexpr auto operator*=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); + + template + constexpr auto operator/=(Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&); + + // Increment and decrement + constexpr auto operator++() noexcept -> decimal_fast64_t&; + constexpr auto operator++(int) noexcept -> decimal_fast64_t; + constexpr auto operator--() noexcept -> decimal_fast64_t&; + constexpr auto operator--(int) noexcept -> decimal_fast64_t; + + // Cmath friend functions + template + friend constexpr auto frexp10(T num, int* expptr) noexcept -> typename T::significand_type; + + friend constexpr auto copysignd64f(decimal_fast64_t mag, decimal_fast64_t sgn) noexcept -> decimal_fast64_t; + friend constexpr auto scalbnd64f(decimal_fast64_t num, int exp) noexcept -> decimal_fast64_t; + friend constexpr auto scalblnd64f(decimal_fast64_t num, long exp) noexcept -> decimal_fast64_t; + friend constexpr auto quantexpd64f(decimal_fast64_t x) noexcept -> int; +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal_fast64_t::decimal_fast64_t(T1 coeff, T2 exp, const detail::construction_sign_wrapper resultant_sign) noexcept +{ + using minimum_coefficient_size = std::conditional_t<(sizeof(T1) > sizeof(significand_type)), T1, significand_type>; + + minimum_coefficient_size min_coeff {coeff}; + + const auto is_negative {static_cast(resultant_sign)}; + sign_ = is_negative; + + // Normalize the value, so we don't have to worry about it with operations + detail::normalize(min_coeff, exp, is_negative); + + significand_ = static_cast(min_coeff); + + const auto biased_exp {significand_ == 0U ? 0 : exp + detail::bias_v}; + + if (biased_exp > detail::max_biased_exp_v) + { + significand_ = detail::d64_fast_inf; + } + else if (biased_exp >= 0) + { + exponent_ = static_cast(biased_exp); + } + else + { + // Flush denorms to zero + significand_ = static_cast(0); + exponent_ = static_cast(detail::bias_v); + sign_ = false; + } +} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template && detail::is_integral_v, bool>> +#endif +constexpr decimal_fast64_t::decimal_fast64_t(const T1 coeff, const T2 exp) noexcept : decimal_fast64_t(detail::make_positive_unsigned(coeff), exp, coeff < 0) {} + +constexpr decimal_fast64_t::decimal_fast64_t(const bool value) noexcept : decimal_fast64_t(static_cast(value), 0, false) {} + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +constexpr decimal_fast64_t::decimal_fast64_t(const Integer val) noexcept : decimal_fast64_t{val, 0} {} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +#ifdef BOOST_DECIMAL_HAS_CONCEPTS +template +#else +template , bool>> +#endif +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::decimal_fast64_t(const Float val) noexcept +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val != val) + { + significand_ = detail::d64_fast_qnan; + } + else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + { + significand_ = detail::d64_fast_inf; + } + else + #endif + { + const auto components {detail::ryu::floating_point_to_fd128(val)}; + *this = decimal_fast64_t {components.mantissa, components.exponent, components.sign}; + } +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +constexpr auto direct_init_d64(const decimal_fast64_t::significand_type significand, + const decimal_fast64_t::exponent_type exponent, + const bool sign) noexcept -> decimal_fast64_t +{ + decimal_fast64_t val {}; + val.significand_ = significand; + val.exponent_ = exponent; + val.sign_ = sign; + + return val; +} + +namespace detail { + +template +class numeric_limits_impl64f +{ +public: + + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = true; + + // These members were deprecated in C++23 + #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = true; + #endif + + static constexpr std::float_round_style round_style = std::round_indeterminate; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = 16; + static constexpr int digits10 = digits; + static constexpr int max_digits10 = digits; + static constexpr int radix = 10; + static constexpr int min_exponent = -383; + static constexpr int min_exponent10 = min_exponent; + static constexpr int max_exponent = 384; + static constexpr int max_exponent10 = max_exponent; + static constexpr bool traps = std::numeric_limits::traps; + static constexpr bool tinyness_before = true; + + // Member functions + static constexpr auto (min) () -> boost::decimal::decimal_fast64_t { return {UINT32_C(1), min_exponent}; } + static constexpr auto (max) () -> boost::decimal::decimal_fast64_t { return {UINT64_C(9'999'999'999'999'999), max_exponent - digits + 1}; } + static constexpr auto lowest () -> boost::decimal::decimal_fast64_t { return {UINT64_C(9'999'999'999'999'999), max_exponent - digits + 1, construction_sign::negative}; } + static constexpr auto epsilon () -> boost::decimal::decimal_fast64_t { return {UINT32_C(1), -digits + 1}; } + static constexpr auto round_error () -> boost::decimal::decimal_fast64_t { return epsilon(); } + static constexpr auto infinity () -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( + boost::decimal::detail::d64_fast_inf, 0, false); } + static constexpr auto quiet_NaN () -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( + boost::decimal::detail::d64_fast_qnan, 0, false); } + static constexpr auto signaling_NaN() -> boost::decimal::decimal_fast64_t { return boost::decimal::direct_init_d64( + boost::decimal::detail::d64_fast_snan, 0, false); } + static constexpr auto denorm_min () -> boost::decimal::decimal_fast64_t { return min(); } +}; + +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl64f::is_specialized; +template constexpr bool numeric_limits_impl64f::is_signed; +template constexpr bool numeric_limits_impl64f::is_integer; +template constexpr bool numeric_limits_impl64f::is_exact; +template constexpr bool numeric_limits_impl64f::has_infinity; +template constexpr bool numeric_limits_impl64f::has_quiet_NaN; +template constexpr bool numeric_limits_impl64f::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl64f::has_denorm; +template constexpr bool numeric_limits_impl64f::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl64f::round_style; +template constexpr bool numeric_limits_impl64f::is_iec559; +template constexpr bool numeric_limits_impl64f::is_bounded; +template constexpr bool numeric_limits_impl64f::is_modulo; +template constexpr int numeric_limits_impl64f::digits; +template constexpr int numeric_limits_impl64f::digits10; +template constexpr int numeric_limits_impl64f::max_digits10; +template constexpr int numeric_limits_impl64f::radix; +template constexpr int numeric_limits_impl64f::min_exponent; +template constexpr int numeric_limits_impl64f::min_exponent10; +template constexpr int numeric_limits_impl64f::max_exponent; +template constexpr int numeric_limits_impl64f::max_exponent10; +template constexpr bool numeric_limits_impl64f::traps; +template constexpr bool numeric_limits_impl64f::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl64f {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // namespace std + +namespace boost { +namespace decimal { + +constexpr auto signbit(const decimal_fast64_t val) noexcept -> bool +{ + return val.sign_; +} + +constexpr auto isinf(const decimal_fast64_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ == detail::d64_fast_inf; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnan(const decimal_fast64_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ >= detail::d64_fast_qnan; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto issignaling(const decimal_fast64_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + return val.significand_ >= detail::d64_fast_snan; + #else + static_cast(val); + return false; + #endif +} + +constexpr auto isnormal(const decimal_fast64_t val) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (val.exponent_ <= static_cast(detail::precision_v - 1)) + { + return false; + } + + return (val.significand_ != 0) && isfinite(val); + #else + return val.significand_ != 0; + #endif +} + +constexpr auto isfinite(const decimal_fast64_t val) noexcept -> bool +{ + return val.significand_ < detail::d64_fast_inf; +} + +BOOST_DECIMAL_FORCE_INLINE constexpr auto not_finite(const decimal_fast64_t val) noexcept -> bool +{ + return val.significand_ >= detail::d64_fast_inf; +} + +constexpr auto operator==(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + return fast_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(lhs, rhs); +} + +template +constexpr auto operator==(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return mixed_equality_impl(rhs, lhs); +} + +constexpr auto operator!=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + return fast_inequality_impl(lhs, rhs); +} + +template +constexpr auto operator!=(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +template +constexpr auto operator!=(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return !(lhs == rhs); +} + +constexpr auto operator<(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + return fast_less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return less_impl(lhs, rhs); +} + +template +constexpr auto operator<(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !less_impl(rhs, lhs) && lhs != rhs; +} + +constexpr auto operator<=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +template +constexpr auto operator<=(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(rhs < lhs); +} + +constexpr auto operator>(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +template +constexpr auto operator>(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + return rhs < lhs; +} + +constexpr auto operator>=(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> bool +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs) || isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(lhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +template +constexpr auto operator>=(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, bool) +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (isnan(rhs)) + { + return false; + } + #endif + + return !(lhs < rhs); +} + +#ifdef BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator<=>(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> std::partial_ordering +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +template +constexpr auto operator<=>(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, std::partial_ordering) +{ + if (lhs < rhs) + { + return std::partial_ordering::less; + } + else if (lhs > rhs) + { + return std::partial_ordering::greater; + } + else if (lhs == rhs) + { + return std::partial_ordering::equivalent; + } + + return std::partial_ordering::unordered; +} + +#endif // BOOST_DECIMAL_HAS_SPACESHIP_OPERATOR + +constexpr auto operator+(const decimal_fast64_t val) noexcept -> decimal_fast64_t +{ + return val; +} + +constexpr auto operator-(decimal_fast64_t val) noexcept -> decimal_fast64_t +{ + val.sign_ = !val.sign_; + return val; +} + +constexpr decimal_fast64_t::operator bool() const noexcept +{ + constexpr decimal_fast64_t zero {0, 0}; + return *this != zero; +} + +constexpr decimal_fast64_t::operator int() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator unsigned() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator unsigned long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator long long() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator unsigned long long() const noexcept +{ + return to_integral(*this); +} + +#ifdef BOOST_DECIMAL_HAS_INT128 + +constexpr decimal_fast64_t::operator detail::builtin_int128_t() const noexcept +{ + return to_integral(*this); +} + +constexpr decimal_fast64_t::operator detail::builtin_uint128_t() const noexcept +{ + return to_integral(*this); +} + +#endif // BOOST_DECIMAL_HAS_INT128 + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator float() const noexcept +{ + return to_float(*this); +} + +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator double() const noexcept +{ + return to_float(*this); +} + +#ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE +BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::operator long double() const noexcept +{ + return to_float(*this); +} +#endif + +#ifdef BOOST_DECIMAL_HAS_FLOAT16 +constexpr decimal_fast64_t::operator std::float16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT32 +constexpr decimal_fast64_t::operator std::float32_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_FLOAT64 +constexpr decimal_fast64_t::operator std::float64_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif +#ifdef BOOST_DECIMAL_HAS_BRAINFLOAT16 +constexpr decimal_fast64_t::operator std::bfloat16_t() const noexcept +{ + return static_cast(to_float(*this)); +} +#endif + +template && (detail::decimal_val_v > detail::decimal_val_v), bool>> +constexpr decimal_fast64_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +template && (detail::decimal_val_v <= detail::decimal_val_v), bool>> +constexpr decimal_fast64_t::operator Decimal() const noexcept +{ + return to_decimal(*this); +} + +constexpr auto operator+(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) != signbit(rhs)) + { + return direct_init_d64(detail::d64_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::add_impl(lhs, rhs); +} + +template +constexpr auto operator+(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::add_impl( + detail::decimal_fast64_t_components{lhs.significand_, lhs.biased_exponent(), lhs.sign_}, + detail::decimal_fast64_t_components{final_sig_rhs, exp_rhs, (rhs < 0)} + ); +} + +template +constexpr auto operator+(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + return rhs + lhs; +} + +constexpr auto operator-(const decimal_fast64_t lhs, decimal_fast64_t rhs) noexcept -> decimal_fast64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if (isinf(lhs) && isinf(rhs) && signbit(lhs) == signbit(rhs)) + { + return direct_init_d64(detail::d64_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + rhs.sign_ = !rhs.sign_; + + return detail::add_impl(lhs, rhs); +} + +template +constexpr auto operator-(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto sig_rhs {static_cast(detail::make_positive_unsigned(rhs))}; + + exp_type exp_rhs {0}; + detail::normalize(sig_rhs, exp_rhs); + const auto final_sig_rhs {static_cast(sig_rhs)}; + + return detail::add_impl( + detail::decimal_fast64_t_components{lhs.significand_, lhs.biased_exponent(), lhs.sign_}, + detail::decimal_fast64_t_components{final_sig_rhs, exp_rhs, !(rhs < 0)} + ); +} + +template +constexpr auto operator-(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(rhs)) + { + return detail::check_non_finite(rhs); + } + #endif + + auto sig_lhs {static_cast(detail::make_positive_unsigned(lhs))}; + + exp_type exp_lhs {0}; + detail::normalize(sig_lhs, exp_lhs); + const auto final_sig_lhs {static_cast(sig_lhs)}; + + return detail::add_impl( + detail::decimal_fast64_t_components{final_sig_lhs, exp_lhs, (lhs < 0)}, + detail::decimal_fast64_t_components{rhs.significand_, rhs.biased_exponent(), !rhs.sign_} + ); +} + +constexpr auto operator*(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs) || not_finite(rhs)) + { + if ((isinf(lhs) && rhs == 0) || (isinf(rhs) && lhs == 0)) + { + return direct_init_d64(detail::d64_fast_qnan, 0, false); + } + + return detail::check_non_finite(lhs, rhs); + } + #endif + + return detail::d64_mul_impl(lhs, rhs); +} + +template +constexpr auto operator*(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = decimal_fast64_t::biased_exponent_type; + + #ifndef BOOST_DECIMAL_FAST_MATH + if (not_finite(lhs)) + { + return detail::check_non_finite(lhs); + } + #endif + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type rhs_exp {0}; + detail::normalize(rhs_sig, rhs_exp); + auto final_rhs_sig {static_cast(rhs_sig)}; + + return detail::d64_mul_impl( + lhs.significand_, lhs.biased_exponent(), lhs.sign_, + final_rhs_sig, rhs_exp, (rhs < 0) + ); +} + +template +constexpr auto operator*(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + return rhs * lhs; +} + +constexpr auto d64_fast_div_impl(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs, decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void +{ + const bool sign {lhs.isneg() != rhs.isneg()}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast64_t zero {0, 0}; + constexpr decimal_fast64_t nan {direct_init_d64(detail::d64_fast_qnan, 0, false)}; + constexpr decimal_fast64_t inf {direct_init_d64(detail::d64_fast_inf, 0, false)}; + + const auto lhs_fp {fpclassify(lhs)}; + const auto rhs_fp {fpclassify(rhs)}; + + if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL) + { + if (lhs_fp == FP_NAN || rhs_fp == FP_NAN) + { + // Operations on an SNAN return a QNAN with the same payload + decimal_fast64_t return_nan {}; + if (lhs_fp == rhs_fp) + { + // They are both NANs + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return_nan = nan_conversion(rhs); + } + else + { + return_nan = lhs_signaling ? nan_conversion(lhs) : lhs; + } + } + else if (lhs_fp == FP_NAN) + { + return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs; + } + else + { + return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs; + } + + q = return_nan; + r = return_nan; + + return; + } + + switch (lhs_fp) + { + case FP_INFINITE: + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } + return; + case FP_ZERO: + if (rhs_fp == FP_ZERO) + { + q = nan; + r = nan; + } + else + { + q = sign ? -zero : zero; + r = sign ? -zero : zero; + } + return; + default: + static_cast(lhs); + } + + switch (rhs_fp) + { + case FP_ZERO: + q = inf; + r = zero; + return; + case FP_INFINITE: + q = sign ? -zero : zero; + r = lhs; + return; + default: + static_cast(rhs); + } + } + #else + static_cast(r); + #endif + + #ifdef BOOST_DECIMAL_DEBUG + std::cerr << "sig lhs: " << sig_lhs + << "\nexp lhs: " << exp_lhs + << "\nsig rhs: " << sig_rhs + << "\nexp rhs: " << exp_rhs << std::endl; + #endif + + using unsigned_int128_type = boost::int128::uint128_t; + + // If rhs is greater than we need to offset the significands to get the correct values + // e.g. 4/8 is 0 but 40/8 yields 5 in integer maths + constexpr auto offset {std::numeric_limits::digits10 - detail::precision_v}; + constexpr auto tens_needed {detail::pow10(static_cast(offset))}; + const auto big_sig_lhs {static_cast(lhs.significand_) * tens_needed}; + + const auto res_sig {big_sig_lhs / rhs.significand_}; + const auto res_exp {(lhs.biased_exponent() - offset) - rhs.biased_exponent()}; + + q = decimal_fast64_t{res_sig, res_exp, sign}; +} + +constexpr auto d64_fast_mod_impl(const decimal_fast64_t lhs, const decimal_fast64_t rhs, const decimal_fast64_t& q, decimal_fast64_t& r) noexcept -> void +{ + constexpr decimal_fast64_t zero {0, 0}; + + // https://en.cppreference.com/w/cpp/numeric/math/fmod + auto q_trunc {q > zero ? floor(q) : ceil(q)}; + r = lhs - (q_trunc * rhs); +} + +constexpr auto operator/(const decimal_fast64_t& lhs, const decimal_fast64_t& rhs) noexcept -> decimal_fast64_t +{ + decimal_fast64_t q {}; + decimal_fast64_t r {}; + + d64_fast_div_impl(lhs, rhs, q, r); + + return q; +} + +template +constexpr auto operator/(const decimal_fast64_t lhs, const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = detail::decimal_fast64_t_components::biased_exponent_type; + + const bool sign {lhs.isneg() != (rhs < 0)}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast64_t zero {0, 0}; + constexpr decimal_fast64_t inf {direct_init_d64(detail::d64_fast_inf, 0, false)}; + + const auto lhs_fp {fpclassify(lhs)}; + + switch (lhs_fp) + { + case FP_NAN: + return issignaling(lhs) ? nan_conversion(lhs) : lhs;; + case FP_INFINITE: + return lhs; + case FP_ZERO: + return sign ? -zero : zero; + default: + static_cast(lhs); + } + + if (rhs == 0) + { + return sign ? -inf : inf; + } + #endif + + const detail::decimal_fast64_t_components lhs_components {lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()}; + + auto rhs_sig {static_cast(detail::make_positive_unsigned(rhs))}; + exp_type rhs_exp {}; + detail::decimal_fast64_t_components rhs_components {detail::shrink_significand(rhs_sig, rhs_exp), rhs_exp, rhs < 0}; + + return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); +} + +template +constexpr auto operator/(const Integer lhs, const decimal_fast64_t rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t) +{ + using promoted_significand_type = detail::promote_significand_t; + using exp_type = detail::decimal_fast64_t_components::biased_exponent_type; + + const bool sign {(lhs < 0) != rhs.isneg()}; + + #ifndef BOOST_DECIMAL_FAST_MATH + // Check pre-conditions + constexpr decimal_fast64_t zero {0, 0}; + constexpr decimal_fast64_t inf {direct_init_d64(detail::d64_fast_inf, 0, false)}; + + const auto rhs_fp {fpclassify(rhs)}; + + switch (rhs_fp) + { + case FP_NAN: + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + case FP_INFINITE: + return sign ? -zero : zero; + case FP_ZERO: + return sign ? -inf : inf; + default: + static_cast(lhs); + } + #endif + + const detail::decimal_fast64_t_components rhs_components {rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; + + auto lhs_sig {static_cast(detail::make_positive_unsigned(lhs))}; + exp_type lhs_exp {}; + const detail::decimal_fast64_t_components lhs_components {detail::shrink_significand(lhs_sig, lhs_exp), lhs_exp, lhs < 0}; + + return detail::d64_generic_div_impl(lhs_components, rhs_components, sign); +} + +constexpr auto operator%(const decimal_fast64_t lhs, const decimal_fast64_t rhs) noexcept -> decimal_fast64_t +{ + decimal_fast64_t q {}; + decimal_fast64_t r {}; + d64_fast_div_impl(lhs, rhs, q, r); + + if (BOOST_DECIMAL_LIKELY(!isnan(q))) + { + d64_fast_mod_impl(lhs, rhs, q, r); + } + + return r; +} + +constexpr auto decimal_fast64_t::operator+=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & +{ + *this = *this + rhs; + return *this; +} + +constexpr auto decimal_fast64_t::operator-=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & +{ + *this = *this - rhs; + return *this; +} + +constexpr auto decimal_fast64_t::operator*=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & +{ + *this = *this * rhs; + return *this; +} + +constexpr auto decimal_fast64_t::operator/=(const decimal_fast64_t rhs) noexcept -> decimal_fast64_t & +{ + *this = *this / rhs; + return *this; +} + +template +constexpr auto decimal_fast64_t::operator+=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) +{ + *this = *this + rhs; + return *this; +} + +template +constexpr auto decimal_fast64_t::operator-=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) +{ + *this = *this - rhs; + return *this; +} + +template +constexpr auto decimal_fast64_t::operator*=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) +{ + *this = *this * rhs; + return *this; +} + +template +constexpr auto decimal_fast64_t::operator/=(const Integer rhs) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal_fast64_t&) +{ + *this = *this / rhs; + return *this; +} + +constexpr auto decimal_fast64_t::operator++() noexcept -> decimal_fast64_t& +{ + constexpr decimal_fast64_t one {1, 0}; + *this = *this + one; + return *this; +} + +constexpr auto decimal_fast64_t::operator++(int) noexcept -> decimal_fast64_t +{ + const auto temp {*this}; + ++(*this); + return temp; +} + +constexpr auto decimal_fast64_t::operator--() noexcept -> decimal_fast64_t& +{ + constexpr decimal_fast64_t one {1, 0}; + *this = *this - one; + return *this; +} + +constexpr auto decimal_fast64_t::operator--(int) noexcept -> decimal_fast64_t +{ + const auto temp {*this}; + --(*this); + return temp; +} + +// Effects: if x is finite, returns its quantum exponent. +// Otherwise, a domain error occurs and INT_MIN is returned. +constexpr auto quantexpd64f(const decimal_fast64_t x) noexcept -> int +{ + #ifndef BOOST_DECIMAL_FAST_MATH + if (!isfinite(x)) + { + return INT_MIN; + } + #endif + + return static_cast(x.unbiased_exponent()); +} + +constexpr auto scalblnd64f(decimal_fast64_t num, const long exp) noexcept -> decimal_fast64_t +{ + #ifndef BOOST_DECIMAL_FAST_MATH + constexpr decimal_fast64_t zero {0, 0}; + + if (num == zero || exp == 0 || not_finite(num)) + { + return num; + } + #endif + + num = decimal_fast64_t(num.significand_, num.biased_exponent() + exp, num.sign_); + + return num; +} + +constexpr auto scalbnd64f(const decimal_fast64_t num, const int expval) noexcept -> decimal_fast64_t +{ + return scalblnd64f(num, static_cast(expval)); +} + +constexpr auto copysignd64f(decimal_fast64_t mag, const decimal_fast64_t sgn) noexcept -> decimal_fast64_t +{ + mag.sign_ = sgn.sign_; + return mag; +} + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +constexpr decimal_fast64_t::decimal_fast64_t(const char* str, const std::size_t len) +{ + if (str == nullptr || len == 0) + { + *this = direct_init_d64(detail::d64_fast_qnan, 0, false); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + return; // LCOV_EXCL_LINE + } + + // Normally plus signs aren't allowed + auto first {str}; + if (*first == '+') + { + ++first; + } + + decimal_fast64_t v; + const auto r {detail::from_chars_general_impl(first, str + len, v, chars_format::general)}; + if (r) + { + *this = v; + } + else + { + *this = direct_init_d64(detail::d64_fast_qnan, 0, false); + BOOST_DECIMAL_THROW_EXCEPTION(std::runtime_error("Can not construct from invalid string")); + } +} + +constexpr decimal_fast64_t::decimal_fast64_t(const char* str) : decimal_fast64_t(str, detail::strlen(str)) {} + +#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW +inline decimal_fast64_t::decimal_fast64_t(const std::string& str) : decimal_fast64_t(str.c_str(), str.size()) {} +#else +constexpr decimal_fast64_t::decimal_fast64_t(std::string_view str) : decimal_fast64_t(str.data(), str.size()) {} +#endif + +#endif // BOOST_DECIMAL_DISABLE_CLIB + +} // namespace decimal +} // namespace boost + +#endif //BOOST_DECIMAL_decimal_fast64_t_HPP diff --git a/include/boost/decimal/detail/add_impl.hpp b/include/boost/decimal/detail/add_impl.hpp index d18bf667f..813a65e75 100644 --- a/include/boost/decimal/detail/add_impl.hpp +++ b/include/boost/decimal/detail/add_impl.hpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #include "int128.hpp" #ifndef BOOST_DECIMAL_BUILD_MODULE @@ -20,455 +23,356 @@ namespace boost { namespace decimal { namespace detail { -template -constexpr auto d32_add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType -{ - // Each of the significands is maximally 23 bits. - // Rather than doing division to get proper alignment we will promote to 64 bits - // And do a single mul followed by an add - using add_type = std::int_fast64_t; - using promoted_sig_type = std::uint_fast64_t; - - promoted_sig_type big_lhs {lhs.full_significand()}; - promoted_sig_type big_rhs {rhs.full_significand()}; - auto lhs_exp {lhs.biased_exponent()}; - const auto rhs_exp {rhs.biased_exponent()}; - - // Align to larger exponent - if (lhs_exp != rhs_exp) - { - constexpr auto max_shift {detail::make_positive_unsigned(detail::precision_v + 1)}; - const auto shift {detail::make_positive_unsigned(lhs_exp - rhs_exp)}; - - if (shift > max_shift) - { - return big_lhs != 0U && (lhs_exp > rhs_exp) ? - ReturnType{lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()} : - ReturnType{rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; - } - else if (lhs_exp < rhs_exp) - { - big_rhs *= detail::pow10(shift); - lhs_exp = rhs_exp - static_cast(shift); - } - else - { - big_lhs *= detail::pow10(shift); - lhs_exp -= static_cast(shift); - } - } - - // Perform signed addition with overflow protection - const auto signed_lhs {detail::make_signed_value(static_cast(big_lhs), lhs.isneg())}; - const auto signed_rhs {detail::make_signed_value(static_cast(big_rhs), rhs.isneg())}; - - const auto new_sig {signed_lhs + signed_rhs}; - - return ReturnType{new_sig, lhs_exp}; -} +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) // Conditional expression is constant +#endif template -constexpr auto d32_fast_add_only_impl(const T& lhs, const T& rhs) noexcept -> ReturnType +constexpr auto add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType { // Each of the significands is maximally 23 bits. // Rather than doing division to get proper alignment we will promote to 64 bits // And do a single mul followed by an add - using promoted_sig_type = std::uint_fast64_t; - - int max_result_digits_overage {1}; + using add_type = std::conditional_t < 64, std::int_fast64_t, int128::int128_t>; + using promoted_sig_type = std::conditional_t < 64, std::uint_fast64_t, int128::uint128_t>; promoted_sig_type big_lhs {lhs.full_significand()}; promoted_sig_type big_rhs {rhs.full_significand()}; auto lhs_exp {lhs.biased_exponent()}; - const auto rhs_exp {rhs.biased_exponent()}; + auto rhs_exp {rhs.biased_exponent()}; // Align to larger exponent if (lhs_exp != rhs_exp) { - constexpr auto max_shift {detail::make_positive_unsigned(detail::precision_v + 1)}; + constexpr auto max_shift {detail::make_positive_unsigned(std::numeric_limits::digits10 - detail::precision_v - 1)}; const auto shift {detail::make_positive_unsigned(lhs_exp - rhs_exp)}; if (shift > max_shift) { - return big_lhs != 0U && (lhs_exp > rhs_exp) ? - ReturnType{lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()} : - ReturnType{rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; - } - - if (lhs_exp < rhs_exp) - { - big_rhs *= detail::pow10(shift); - lhs_exp = rhs_exp - static_cast(shift); - } - else - { - big_lhs *= detail::pow10(shift); - lhs_exp -= static_cast(shift); - } - - max_result_digits_overage = static_cast(shift); - } - - auto res_sig {big_lhs + big_rhs}; - - constexpr promoted_sig_type max_non_normalized_value {9'999'999U}; - if (res_sig > max_non_normalized_value) - { - constexpr promoted_sig_type max_non_compensated_value {99'999'999U}; - if (res_sig > max_non_compensated_value) - { - const auto offset_power {max_result_digits_overage == 1 ? 1 : max_result_digits_overage - 1}; - const auto offset {detail::pow10(static_cast(offset_power))}; - res_sig /= offset; - lhs_exp += offset_power; - } - - lhs_exp += detail::fenv_round(res_sig, false); - } + auto round {_boost_decimal_global_rounding_mode}; - BOOST_DECIMAL_ASSERT(res_sig >= 1'000'000U || res_sig == 0U); - BOOST_DECIMAL_ASSERT(res_sig <= max_non_normalized_value || res_sig == 0U); + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION - return ReturnType{static_cast(res_sig), lhs_exp, false}; -} - -template -constexpr auto d32_add_impl(T lhs_sig, U lhs_exp, bool lhs_sign, - T rhs_sig, U rhs_exp, bool rhs_sign) noexcept -> ReturnType -{ - // Each of the significands is maximally 23 bits. - // Rather than doing division to get proper alignment we will promote to 64 bits - // And do a single mul followed by an add - using add_type = std::int_fast64_t; - using promoted_sig_type = std::uint_fast64_t; + if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + round = fegetround(); + } - promoted_sig_type big_lhs {lhs_sig}; - promoted_sig_type big_rhs {rhs_sig}; + #endif - // Align to larger exponent - if (lhs_exp != rhs_exp) - { - constexpr auto max_shift {detail::make_positive_unsigned(detail::precision_v + 1)}; - const auto shift {detail::make_positive_unsigned(lhs_exp - rhs_exp)}; - - if (shift > max_shift) - { - return lhs_sig != 0U && (lhs_exp > rhs_exp) ? ReturnType{lhs_sig, lhs_exp, lhs_sign} : ReturnType{rhs_sig, rhs_exp, rhs_sign}; + if (BOOST_DECIMAL_LIKELY(round != rounding_mode::fe_dec_downward && round != rounding_mode::fe_dec_upward)) + { + return big_lhs != 0U && (lhs_exp > rhs_exp) ? + ReturnType{lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()} : + ReturnType{rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; + } + else if (round == rounding_mode::fe_dec_downward) + { + // If we are subtracting even disparate numbers we need to round down + // E.g. "5e+95"_DF - "4e-100"_DF == "4.999999e+95"_DF + const auto use_lhs {big_lhs != 0U && (lhs_exp > rhs_exp)}; + + // Need to check for the case where we have 1e+95 - anything = 9.99999... without losing a nine + if (use_lhs) + { + if (big_rhs != 0U && (lhs.isneg() != rhs.isneg())) + { + if (is_power_of_10(big_lhs)) + { + --big_lhs; + big_lhs *= 10U; + big_lhs += 9U; + --lhs_exp; + } + else + { + --big_lhs; + } + } + + return ReturnType{big_lhs, lhs_exp, lhs.isneg()}; + } + else + { + if (big_lhs != 0U && (lhs.isneg() != rhs.isneg())) + { + if (is_power_of_10(big_rhs)) + { + --big_rhs; + big_rhs *= 10U; + big_rhs += 9U; + --rhs_exp; + } + else + { + --big_rhs; + } + } + + return ReturnType{big_rhs, rhs_exp, rhs.isneg()}; + } + } + else + { + // rounding mode == fe_dec_upward + // Unconditionally round up. Could be 5e+95 + 4e-100 -> 5.000001e+95 + const bool use_lhs {big_lhs != 0U && (lhs_exp > rhs_exp)}; + + if (use_lhs) + { + if (big_rhs != 0U) + { + if (lhs.isneg() != rhs.isneg()) + { + if (is_power_of_10(big_lhs)) + { + --big_lhs; + big_lhs *= 10U; + big_lhs += 9U; + --lhs_exp; + } + else + { + --big_lhs; + } + } + else + { + ++big_lhs; + } + } + + return ReturnType{big_lhs, lhs_exp, lhs.isneg()} ; + } + else + { + if (big_lhs != 0U) + { + if (rhs.isneg() != lhs.isneg()) + { + --big_rhs; + big_rhs *= 10U; + big_rhs += 9U; + --rhs_exp; + } + else + { + ++big_rhs; + } + } + + return ReturnType{big_rhs, rhs_exp, rhs.isneg()}; + } + } } if (lhs_exp < rhs_exp) { big_rhs *= detail::pow10(shift); - lhs_exp = rhs_exp - static_cast(shift); + lhs_exp = rhs_exp - static_cast(shift); } else { big_lhs *= detail::pow10(shift); - lhs_exp -= static_cast(shift); + lhs_exp -= static_cast(shift); } } // Perform signed addition with overflow protection - const auto signed_lhs {detail::make_signed_value(static_cast(big_lhs), lhs_sign)}; - const auto signed_rhs {detail::make_signed_value(static_cast(big_rhs), rhs_sign)}; + const auto signed_lhs {detail::make_signed_value(static_cast(big_lhs), lhs.isneg())}; + const auto signed_rhs {detail::make_signed_value(static_cast(big_rhs), rhs.isneg())}; const auto new_sig {signed_lhs + signed_rhs}; + const auto return_sig {detail::make_positive_unsigned(new_sig)}; - return {new_sig, lhs_exp}; + return ReturnType{return_sig, lhs_exp, new_sig < 0}; } template -constexpr auto d64_add_impl(const T& lhs, const T& rhs) noexcept -> ReturnType +constexpr auto d128_add_impl_new(const T& lhs, const T& rhs) noexcept -> ReturnType { - // Each of the significands is maximally 23 bits. - // Rather than doing division to get proper alignment we will promote to 64 bits - // And do a single mul followed by an add - using add_type = boost::int128::int128_t; - using promoted_sig_type = boost::int128::uint128_t; + using promoted_sig_type = u256; - promoted_sig_type big_lhs {lhs.full_significand()}; - promoted_sig_type big_rhs {rhs.full_significand()}; + auto big_lhs {lhs.full_significand()}; + auto big_rhs {rhs.full_significand()}; auto lhs_exp {lhs.biased_exponent()}; - const auto rhs_exp {rhs.biased_exponent()}; + auto rhs_exp {rhs.biased_exponent()}; + promoted_sig_type promoted_lhs {big_lhs}; + promoted_sig_type promoted_rhs {big_rhs}; // Align to larger exponent if (lhs_exp != rhs_exp) { - constexpr auto max_shift {detail::make_positive_unsigned(detail::precision_v + 1)}; + constexpr auto max_shift {detail::make_positive_unsigned(std::numeric_limits::digits10 - detail::precision_v - 1)}; const auto shift {detail::make_positive_unsigned(lhs_exp - rhs_exp)}; if (shift > max_shift) { - return lhs.full_significand() != 0U && (lhs_exp > rhs_exp) ? - ReturnType{lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()} : - ReturnType{rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; - } + auto round {_boost_decimal_global_rounding_mode}; - if (lhs_exp < rhs_exp) - { - big_rhs *= detail::pow10(shift); - lhs_exp = rhs_exp - static_cast(shift); - } - else - { - big_lhs *= detail::pow10(shift); - lhs_exp -= static_cast(shift); - } - } - - // Perform signed addition with overflow protection - const auto signed_lhs {detail::make_signed_value(static_cast(big_lhs), lhs.isneg())}; - const auto signed_rhs {detail::make_signed_value(static_cast(big_rhs), rhs.isneg())}; - - const auto new_sig {signed_lhs + signed_rhs}; - - return ReturnType{new_sig, lhs_exp}; -} - -template -constexpr auto d64_add_impl(T lhs_sig, U lhs_exp, bool lhs_sign, - T rhs_sig, U rhs_exp, bool rhs_sign, - bool abs_lhs_bigger) noexcept -> ReturnType -{ - using add_type = std::int_fast64_t; - - auto delta_exp {lhs_exp > rhs_exp ? lhs_exp - rhs_exp : rhs_exp - lhs_exp}; - auto signed_sig_lhs {static_cast(detail::make_signed_value(lhs_sig, lhs_sign))}; - auto signed_sig_rhs {static_cast(detail::make_signed_value(rhs_sig, rhs_sign))}; - - #ifdef BOOST_DECIMAL_DEBUG_ADD - std::cerr << "Starting sig lhs: " << lhs_sig - << "\nStarting exp lhs: " << lhs_exp - << "\nStarting sig rhs: " << rhs_sig - << "\nStarting exp rhs: " << rhs_exp << std::endl; - #endif - - if (delta_exp > detail::precision_v + 1) - { - // If the difference in exponents is more than the digits of accuracy - // we return the larger of the two - // - // e.g. 1e20 + 1e-20 = 1e20 - - return abs_lhs_bigger ? ReturnType{lhs_sig, lhs_exp, lhs_sign} : - ReturnType{rhs_sig, rhs_exp, rhs_sign}; - } - - // The two numbers can be added together without special handling - // - // If we can add to the lhs sig rather than dividing we can save some precision - // 32-bit signed int can have 9 digits and our normalized significand has 7 - - auto& sig_bigger {abs_lhs_bigger ? signed_sig_lhs : signed_sig_rhs}; - auto& exp_bigger {abs_lhs_bigger ? lhs_exp : rhs_exp}; - auto& sig_smaller {abs_lhs_bigger ? signed_sig_rhs : signed_sig_lhs}; - auto& sign_smaller {abs_lhs_bigger ? rhs_sign : lhs_sign}; - - if (delta_exp <= 2) - { - sig_bigger *= pow10(static_cast(delta_exp)); - exp_bigger -= delta_exp; - delta_exp = 0; - } - else - { - sig_bigger *= 100; - delta_exp -= 2; - exp_bigger -= 2; - - if (delta_exp > 1) - { - sig_smaller /= pow10(static_cast(delta_exp - 1)); - delta_exp = 1; - } - - if (delta_exp == 1) - { - detail::fenv_round(sig_smaller, sign_smaller); - } - } - - // Cast the results to signed types so that we can apply a sign at the end if necessary - // Both of the significands are maximally 24 bits, so they fit into a 32-bit signed type just fine - const auto new_sig {sig_bigger + sig_smaller}; - const auto new_exp {exp_bigger}; - const auto new_sign {new_sig < 0}; - const auto res_sig {detail::make_positive_unsigned(new_sig)}; - - #ifdef BOOST_DECIMAL_DEBUG_ADD - std::cerr << "Final sig lhs: " << lhs_sig - << "\nFinal sig rhs: " << rhs_sig - << "\nResult sig: " << new_sig << std::endl; - #endif - - return {res_sig, new_exp, new_sign}; -} - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // If constexpr macro only works for C++17 and above -#endif - -template -constexpr auto d128_add_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, - T2 rhs_sig, U2 rhs_exp, bool rhs_sign) noexcept -> ReturnType -{ - const bool sign {lhs_sign}; + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION - auto delta_exp {lhs_exp > rhs_exp ? lhs_exp - rhs_exp : rhs_exp - lhs_exp}; - - if (delta_exp > detail::precision_v + 1) - { - // If the difference in exponents is more than the digits of accuracy - // we return the larger of the two - // - // e.g. 1e20 + 1e-20 = 1e20 + if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + round = fegetround(); + } - return {lhs_sig, lhs_exp, lhs_sign}; - } + #endif - if (delta_exp == detail::precision_v + 1) - { - // Only need to see if we need to add one to the - // significand of the bigger value - // - // e.g. 1.234567e5 + 9.876543e-2 = 1.234568e5 - - BOOST_DECIMAL_IF_CONSTEXPR (std::numeric_limits::digits10 > std::numeric_limits::digits10) - { - constexpr boost::int128::uint128_t max_value {UINT64_C(0xF684DF56C3E0), UINT64_C(0x1BC6C73200000000)}; - if (rhs_sig >= max_value) + if (BOOST_DECIMAL_LIKELY(round != rounding_mode::fe_dec_downward && round != rounding_mode::fe_dec_upward)) { - ++lhs_sig; + return big_lhs != 0U && (lhs_exp > rhs_exp) ? + ReturnType{lhs.full_significand(), lhs.biased_exponent(), lhs.isneg()} : + ReturnType{rhs.full_significand(), rhs.biased_exponent(), rhs.isneg()}; + } + else if (round == rounding_mode::fe_dec_downward) + { + // If we are subtracting even disparate numbers we need to round down + // E.g. "5e+95"_DF - "4e-100"_DF == "4.999999e+95"_DF + const auto use_lhs {big_lhs != 0U && (lhs_exp > rhs_exp)}; + + // Need to check for the case where we have 1e+95 - anything = 9.99999... without losing a nine + if (use_lhs) + { + if (big_rhs != 0U && (lhs.isneg() != rhs.isneg())) + { + if (is_power_of_10(big_lhs)) + { + --big_lhs; + big_lhs *= 10U; + big_lhs += 9U; + --lhs_exp; + } + else + { + --big_lhs; + } + } + + return ReturnType{big_lhs, lhs_exp, lhs.isneg()}; + } + else + { + if (big_lhs != 0U && (lhs.isneg() != rhs.isneg())) + { + if (is_power_of_10(big_rhs)) + { + --big_rhs; + big_rhs *= 10U; + big_rhs += 9U; + --rhs_exp; + } + else + { + --big_rhs; + } + } + + return ReturnType{big_rhs, rhs_exp, rhs.isneg()}; + } + } + else + { + // rounding mode == fe_dec_upward + // Unconditionally round up. Could be 5e+95 + 4e-100 -> 5.000001e+95 + const bool use_lhs {big_lhs != 0U && (lhs_exp > rhs_exp)}; + + if (use_lhs) + { + if (big_rhs != 0U) + { + if (lhs.isneg() != rhs.isneg()) + { + if (is_power_of_10(big_lhs)) + { + --big_lhs; + big_lhs *= 10U; + big_lhs += 9U; + --lhs_exp; + } + else + { + --big_lhs; + } + } + else + { + ++big_lhs; + } + } + + return ReturnType{big_lhs, lhs_exp, lhs.isneg()} ; + } + else + { + if (big_lhs != 0U) + { + if (rhs.isneg() != lhs.isneg()) + { + --big_rhs; + big_rhs *= 10U; + big_rhs += 9U; + --rhs_exp; + } + else + { + ++big_rhs; + } + } + + return ReturnType{big_rhs, rhs_exp, rhs.isneg()}; + } } - - return {lhs_sig, lhs_exp, lhs_sign}; - } - else - { - return {lhs_sig, lhs_exp, lhs_sign}; } - } - // The two numbers can be added together without special handling - // - // If we can add to the lhs sig rather than dividing we can save some precision - // 64-bit sign int can have 19 digits, and our normalized significand has 16 - - if (delta_exp <= 3) - { - lhs_sig *= detail::pow10(static_cast(delta_exp)); - lhs_exp -= delta_exp; - } - else - { - lhs_sig *= 1000U; - delta_exp -= 3; - lhs_exp -= 3; + const auto shift_pow10 {detail::pow10_256(shift)}; - if (delta_exp > 1) + if (lhs_exp < rhs_exp) { - rhs_sig /= pow10(static_cast(delta_exp - 1)); - delta_exp = 1; + promoted_rhs *= shift_pow10; + lhs_exp = rhs_exp - static_cast(shift); } - - if (delta_exp == 1) + else { - detail::fenv_round(rhs_sig, rhs_sign); + promoted_lhs *= shift_pow10; + lhs_exp -= static_cast(shift); } } + + u256 return_sig {}; + bool return_sign {}; + const auto lhs_sign {lhs.isneg()}; + const auto rhs_sign {rhs.isneg()}; - const auto new_sig {static_cast(lhs_sig) + - static_cast(rhs_sig)}; - const auto new_exp {lhs_exp}; - - #ifdef BOOST_DECIMAL_DEBUG_ADD_128 - std::cerr << "Res Sig: " << static_cast(new_sig) - << "\nRes Exp: " << new_exp - << "\nRes Neg: " << sign << std::endl; - #endif - - return {new_sig, new_exp, sign}; -} - -template -constexpr auto d128_add_impl(T lhs_sig, U lhs_exp, bool lhs_sign, - T rhs_sig, U rhs_exp, bool rhs_sign, - bool abs_lhs_bigger) noexcept -> ReturnType -{ - auto delta_exp {lhs_exp > rhs_exp ? lhs_exp - rhs_exp : rhs_exp - lhs_exp}; - - #ifdef BOOST_DECIMAL_DEBUG_ADD - std::cerr << "Starting sig lhs: " << lhs_sig - << "\nStarting exp lhs: " << lhs_exp - << "\nStarting sig rhs: " << rhs_sig - << "\nStarting exp rhs: " << rhs_exp << std::endl; - #endif - - if (delta_exp > detail::precision_v + 1) + if (lhs_sign && !rhs_sign) { - // If the difference in exponents is more than the digits of accuracy - // we return the larger of the two - // - // e.g. 1e20 + 1e-20 = 1e20 - - return abs_lhs_bigger ? ReturnType{lhs_sig, lhs_exp, lhs_sign} : - ReturnType{rhs_sig, rhs_exp, rhs_sign}; + // -lhs + rhs = rhs - lhs + return_sign = i256_sub(promoted_rhs, promoted_lhs, return_sig); } - - // The two numbers can be added together without special handling - // - // If we can add to the lhs sig rather than dividing we can save some precision - // 32-bit signed int can have 9 digits and our normalized significand has 7 - - auto& sig_bigger {abs_lhs_bigger ? lhs_sig : rhs_sig}; - auto& exp_bigger {abs_lhs_bigger ? lhs_exp : rhs_exp}; - auto& sig_smaller {abs_lhs_bigger ? rhs_sig : lhs_sig}; - auto& sign_smaller {abs_lhs_bigger ? rhs_sign : lhs_sign}; - auto& sign_bigger {abs_lhs_bigger ? lhs_sign : rhs_sign}; - - if (delta_exp <= 2) + else if (!lhs_sign && rhs_sign) { - sig_bigger *= pow10(static_cast(delta_exp)); - exp_bigger -= delta_exp; - delta_exp = 0; + // lhs - rhs + return_sign = i256_sub(promoted_lhs, promoted_rhs, return_sig); } else { - sig_bigger *= 100U; - delta_exp -= 2; - exp_bigger -= 2; - - if (delta_exp > 1) - { - sig_smaller /= pow10(static_cast(delta_exp - 1)); - delta_exp = 1; - } + // lhs + rhs or -lhs + -rhs + return_sig = promoted_lhs + promoted_rhs; + return_sign = lhs_sign && rhs_sign; + } - if (delta_exp == 1) + BOOST_DECIMAL_IF_CONSTEXPR (detail::decimal_val_v == 128) + { + // In the regular 128-bit case there's a chance the high words are empty, + // and we can just convert to 128-bit arithmetic now + if (return_sig[2] == 0U && return_sig[3] == 0U) { - detail::fenv_round(sig_smaller, sign_smaller); + return ReturnType{static_cast(return_sig), lhs_exp, return_sign}; } } - // Cast the results to signed types so that we can apply a sign at the end if necessary - // Both of the significands are maximally 24 bits, so they fit into a 32-bit signed type just fine - auto signed_sig_lhs {detail::make_signed_value(sig_bigger, sign_bigger)}; - auto signed_sig_rhs {detail::make_signed_value(sig_smaller, sign_smaller)}; - - const auto new_sig {signed_sig_lhs + signed_sig_rhs}; - const auto new_exp {exp_bigger}; - const auto new_sign {new_sig < 0}; - const auto res_sig {detail::make_positive_unsigned(new_sig)}; - - #ifdef BOOST_DECIMAL_DEBUG_ADD - std::cerr << "Final sig lhs: " << lhs_sig - << "\nFinal sig rhs: " << rhs_sig - << "\nResult sig: " << new_sig << std::endl; - #endif - - return {res_sig, new_exp, new_sign}; + return ReturnType{return_sig, lhs_exp, return_sign}; } #ifdef _MSC_VER diff --git a/include/boost/decimal/detail/attributes.hpp b/include/boost/decimal/detail/attributes.hpp index 6f1aefe83..4f979905a 100644 --- a/include/boost/decimal/detail/attributes.hpp +++ b/include/boost/decimal/detail/attributes.hpp @@ -89,8 +89,8 @@ constexpr auto max_significand_v() noexcept template >= 128, bool> = true> constexpr auto max_significand_v() noexcept { - return decimal_val_v == 128 ? boost::int128::uint128_t{UINT64_C(0b1111111111'1111111111'1111111111'1111111111'111111), UINT64_MAX} : - boost::int128::uint128_t{UINT64_C(542101086242752), UINT64_C(4003012203950112767)}; + // 34x 9s + return BOOST_DECIMAL_DETAIL_INT128_UINT128_C(9999999999999999999999999999999999); } template @@ -110,49 +110,49 @@ constexpr auto is_fast_type_v() noexcept -> bool } // namespace impl template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto storage_width_v = impl::storage_width_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto storage_width_v = impl::storage_width_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto precision_v = impl::precision_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto precision_v = impl::precision_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto bias_v = impl::bias_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto bias_v = impl::bias_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_biased_exp_v = impl::max_biased_exp_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_biased_exp_v = impl::max_biased_exp_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto emax_v = impl::emax_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto emax_v = impl::emax_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto emin_v = impl::emin_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto emin_v = impl::emin_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto etiny_v = -impl::bias_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto etiny_v = -impl::bias_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto combination_field_width_v = impl::combination_field_width_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto combination_field_width_v = impl::combination_field_width_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto trailing_significand_field_width_v = impl::trailing_significand_field_width_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto trailing_significand_field_width_v = impl::trailing_significand_field_width_v(); template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_significand_v = impl::max_significand_v(); +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_significand_v = impl::max_significand_v(); // sign + decimal digits + '.' + 'e' + '+/-' + max digits of exponent + null term template , bool> = true> -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_string_length_v = impl::max_string_length_v(); - -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto storage_width {storage_width_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto precision {precision_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto bias {bias_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_biased_exp {max_biased_exp_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto emax {emax_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto emin {emin_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto etiny {etiny_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto combination_field_width {combination_field_width_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_significand {max_significand_v}; -BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_string_length {max_string_length_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_string_length_v = impl::max_string_length_v(); + +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto storage_width {storage_width_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto precision {precision_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto bias {bias_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_biased_exp {max_biased_exp_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto emax {emax_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto emin {emin_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto etiny {etiny_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto combination_field_width {combination_field_width_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_significand {max_significand_v}; +BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto max_string_length {max_string_length_v}; } //namespace detail } //namespace decimal diff --git a/include/boost/decimal/detail/bit_layouts.hpp b/include/boost/decimal/detail/bit_layouts.hpp index 8bc05fb2a..e9742a2a9 100644 --- a/include/boost/decimal/detail/bit_layouts.hpp +++ b/include/boost/decimal/detail/bit_layouts.hpp @@ -110,6 +110,7 @@ struct IEEEl2bits #define BOOST_DECIMAL_LDBL_BITS 64 #else // Unsupported long double representation +# define BOOST_DECIMAL_LDBL_BITS 0 # define BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE #endif diff --git a/include/boost/decimal/detail/buffer_sizing.hpp b/include/boost/decimal/detail/buffer_sizing.hpp index fb5638cfd..f26e1e959 100644 --- a/include/boost/decimal/detail/buffer_sizing.hpp +++ b/include/boost/decimal/detail/buffer_sizing.hpp @@ -30,7 +30,7 @@ constexpr int get_real_precision(const int my_precision = -1) noexcept return my_precision == -1 ? std::numeric_limits::max_digits10 : my_precision; } -// We don't need to use the full digit counting since the range of the exponents is well defined +// We don't need to use the full digit counting since the range of the exponents is well-defined template constexpr auto buffer_length_exp(Int x) noexcept -> std::enable_if_t::max_exponent >= 1000, int> { diff --git a/include/boost/decimal/detail/chars_format.hpp b/include/boost/decimal/detail/chars_format.hpp index d32102096..d85f29d92 100644 --- a/include/boost/decimal/detail/chars_format.hpp +++ b/include/boost/decimal/detail/chars_format.hpp @@ -17,6 +17,7 @@ BOOST_DECIMAL_EXPORT enum class chars_format : unsigned scientific = 1 << 0, fixed = 1 << 1, hex = 1 << 2, + cohort_preserving_scientific = 1 << 3, general = fixed | scientific }; diff --git a/include/boost/decimal/detail/check_non_finite.hpp b/include/boost/decimal/detail/check_non_finite.hpp index ec20a207e..20da0cfac 100644 --- a/include/boost/decimal/detail/check_non_finite.hpp +++ b/include/boost/decimal/detail/check_non_finite.hpp @@ -17,31 +17,58 @@ namespace decimal { namespace detail { // Prioritizes checking for nans and then checks for infs +// Per IEEE 754 section 7.2 any operation on a sNaN returns qNaN template -constexpr auto check_non_finite(Decimal lhs, Decimal rhs) noexcept - -> std::enable_if_t, Decimal> +constexpr Decimal check_non_finite(Decimal lhs, Decimal rhs) noexcept { - constexpr Decimal zero {0, 0}; + static_assert(is_decimal_floating_point_v, "Types must both be decimal types"); if (isnan(lhs)) { - return lhs; + // 3 Cases: + // 1) LHS is QNAN and RHS is SNAN -> Return RHS payload as QNAN + // 2) LHS is SNAN and RHS is QNAN -> Return LHS payload as QNAN + // 3) LHS is NAN and RHS is NAN -> Return LHS payload as QNAN + + const bool lhs_signaling {issignaling(lhs)}; + const bool rhs_signaling {issignaling(rhs)}; + + if (!lhs_signaling && rhs_signaling) + { + return nan_conversion(rhs); + } + + return lhs_signaling ? nan_conversion(lhs) : lhs; + } else if (isnan(rhs)) { - return rhs; + return issignaling(rhs) ? nan_conversion(rhs) : rhs; } if (isinf(lhs)) { return lhs; } - else if (isinf(rhs)) + else { + BOOST_DECIMAL_ASSERT(isinf(rhs)); return rhs; } +} + +template +constexpr Decimal check_non_finite(Decimal x) noexcept +{ + static_assert(is_decimal_floating_point_v, "Types must be a decimal type"); + + if (isnan(x)) + { + return issignaling(x) ? nan_conversion(x) : x; + } - return zero; + BOOST_DECIMAL_ASSERT(isinf(x)); + return x; } } //namespace detail diff --git a/include/boost/decimal/detail/cmath/abs.hpp b/include/boost/decimal/detail/cmath/abs.hpp index b7da73126..e0fca14c6 100644 --- a/include/boost/decimal/detail/cmath/abs.hpp +++ b/include/boost/decimal/detail/cmath/abs.hpp @@ -22,7 +22,14 @@ BOOST_DECIMAL_EXPORT template constexpr auto abs BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const T rhs) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - return signbit(rhs) ? -rhs : rhs; + if (BOOST_DECIMAL_LIKELY(!isnan(rhs))) + { + return signbit(rhs) ? -rhs : rhs; + } + else + { + return issignaling(rhs) ? nan_conversion(rhs) : rhs; + } } } // namespace decimal diff --git a/include/boost/decimal/detail/cmath/acos.hpp b/include/boost/decimal/detail/cmath/acos.hpp index a54e2d566..a70df1e5d 100644 --- a/include/boost/decimal/detail/cmath/acos.hpp +++ b/include/boost/decimal/detail/cmath/acos.hpp @@ -72,19 +72,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto acos(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::acos_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/acosh.hpp b/include/boost/decimal/detail/cmath/acosh.hpp index 81dba6fbe..f1e514e86 100644 --- a/include/boost/decimal/detail/cmath/acosh.hpp +++ b/include/boost/decimal/detail/cmath/acosh.hpp @@ -119,19 +119,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto acosh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::acosh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/asin.hpp b/include/boost/decimal/detail/cmath/asin.hpp index 24ddfacf8..eecaf665f 100644 --- a/include/boost/decimal/detail/cmath/asin.hpp +++ b/include/boost/decimal/detail/cmath/asin.hpp @@ -1,4 +1,5 @@ -// Copyright 2024 Matt Borland +// Copyright 2024 - 2025 Matt Borland +// Copyright 2024 - 2025 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -41,29 +42,42 @@ constexpr auto asin_impl(const T x) noexcept return x; } - const auto absx {fabs(x)}; - T result {}; + const auto absx { fabs(x) }; - if (absx <= std::numeric_limits::epsilon()) + T result { }; + + constexpr T cbrt_eps { cbrt(std::numeric_limits::epsilon()) }; + + constexpr T one { 1 }; + + if (absx <= cbrt_eps) { - result = absx; + result = absx * (one + (absx / 6) * absx); } - else if (absx <= T{5, -1}) + else if (absx <= T { 5, -1 }) { result = asin_series(absx); } - else if (absx <= T{1, 0}) - { - constexpr T half_pi {numbers::pi_v / 2}; - result = half_pi - 2 * asin_series(sqrt((1 - absx) / 2)); - } else { - #ifndef BOOST_DECIMAL_FAST_MATH - result = std::numeric_limits::quiet_NaN(); - #else - result = T{0}; - #endif + constexpr T half_pi { numbers::pi_v / 2 }; + + if (absx < one) + { + result = half_pi - 2 * asin_series(sqrt((1 - absx) / 2)); + } + else if (absx > one) + { + #ifndef BOOST_DECIMAL_FAST_MATH + result = std::numeric_limits::quiet_NaN(); + #else + result = T{0}; + #endif + } + else + { + result = half_pi; + } } // arcsin(-x) == -arcsin(x) @@ -81,19 +95,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto asin(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::asin_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/asinh.hpp b/include/boost/decimal/detail/cmath/asinh.hpp index 1bd10ed52..039c127dc 100644 --- a/include/boost/decimal/detail/cmath/asinh.hpp +++ b/include/boost/decimal/detail/cmath/asinh.hpp @@ -87,19 +87,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto asinh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::asinh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/assoc_laguerre.hpp b/include/boost/decimal/detail/cmath/assoc_laguerre.hpp index bb1f3383a..ee8c810e6 100644 --- a/include/boost/decimal/detail/cmath/assoc_laguerre.hpp +++ b/include/boost/decimal/detail/cmath/assoc_laguerre.hpp @@ -69,19 +69,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto assoc_laguerre(const unsigned n, const unsigned m, const T x) BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::assoc_laguerre_impl(n, m, static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/assoc_legendre.hpp b/include/boost/decimal/detail/cmath/assoc_legendre.hpp index 0fbfadfda..5a058cf58 100644 --- a/include/boost/decimal/detail/cmath/assoc_legendre.hpp +++ b/include/boost/decimal/detail/cmath/assoc_legendre.hpp @@ -98,19 +98,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto assoc_legendre(const unsigned n, const unsigned m, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::assoc_legendre_impl(n, m, static_cast(x), pow(1 - static_cast(x)*static_cast(x), diff --git a/include/boost/decimal/detail/cmath/atan.hpp b/include/boost/decimal/detail/cmath/atan.hpp index f5b7ab3b2..f9581f948 100644 --- a/include/boost/decimal/detail/cmath/atan.hpp +++ b/include/boost/decimal/detail/cmath/atan.hpp @@ -48,7 +48,7 @@ constexpr auto atan_impl(const T x) noexcept #ifndef BOOST_DECIMAL_FAST_MATH else if (fpc == FP_INFINITE) { - result = my_pi_half; // LCOV_EXCL_LINE False negative + result = my_pi_half; } #endif else @@ -84,7 +84,7 @@ constexpr auto atan_impl(const T x) noexcept if(!is_smallish) { - constexpr T my_pi_over_six { numbers::pi_v / static_cast(INT8_C(6)) }; + constexpr T my_pi_over_six { numbers::pi_v / 6 }; result += my_pi_over_six; } @@ -104,19 +104,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto atan(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::atan_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/atan2.hpp b/include/boost/decimal/detail/cmath/atan2.hpp index bd2d03a2b..d1de750d7 100644 --- a/include/boost/decimal/detail/cmath/atan2.hpp +++ b/include/boost/decimal/detail/cmath/atan2.hpp @@ -152,19 +152,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto atan2(const T y, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::atan2_impl(static_cast(y), static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/atanh.hpp b/include/boost/decimal/detail/cmath/atanh.hpp index e428a6704..8f1fd13c8 100644 --- a/include/boost/decimal/detail/cmath/atanh.hpp +++ b/include/boost/decimal/detail/cmath/atanh.hpp @@ -107,19 +107,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto atanh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::atanh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/beta.hpp b/include/boost/decimal/detail/cmath/beta.hpp index 133c1bc1a..eb06013a2 100644 --- a/include/boost/decimal/detail/cmath/beta.hpp +++ b/include/boost/decimal/detail/cmath/beta.hpp @@ -41,19 +41,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto beta(const T y, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::beta_impl(static_cast(y), static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/cbrt.hpp b/include/boost/decimal/detail/cmath/cbrt.hpp index 8784926ed..97e13065d 100644 --- a/include/boost/decimal/detail/cmath/cbrt.hpp +++ b/include/boost/decimal/detail/cmath/cbrt.hpp @@ -61,7 +61,7 @@ constexpr auto cbrt_impl(const T x) noexcept remove_trailing_zeros(gn) }; - const bool is_pure { static_cast(zeros_removal.trimmed_number) == 1U }; + const bool is_pure { zeros_removal.trimmed_number == 1U }; if(is_pure) { @@ -131,14 +131,14 @@ constexpr auto cbrt_impl(const T x) noexcept (five + gx * (seventy + gx * 56)) / (numbers::cbrt2_v * (fourteen + gx * (seventy + gx * 20))); - // Perform 2, 3 or 4 Newton-Raphson iterations depending on precision. + // Perform 3, 4 or 5 Newton-Raphson iterations depending on precision. // Note from above, we start with slightly more than 2 decimal digits // of accuracy. constexpr int iter_loops { - std::numeric_limits::digits10 < 10 ? 2 - : std::numeric_limits::digits10 < 20 ? 3 : 4 + std::numeric_limits::digits10 < 10 ? 3 + : std::numeric_limits::digits10 < 20 ? 4 : 5 }; for (int idx = 0; idx < iter_loops; ++idx) @@ -184,19 +184,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto cbrt(const T val) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::cbrt_impl(static_cast(val))); } diff --git a/include/boost/decimal/detail/cmath/comparetotal.hpp b/include/boost/decimal/detail/cmath/comparetotal.hpp new file mode 100644 index 000000000..9cf4648ed --- /dev/null +++ b/include/boost/decimal/detail/cmath/comparetotal.hpp @@ -0,0 +1,163 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_CMATH_TOTAL_ORDER_HPP +#define BOOST_DECIMAL_DETAIL_CMATH_TOTAL_ORDER_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace decimal { + +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal32_t x) noexcept -> int; +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal_fast32_t x) noexcept -> int; +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal64_t x) noexcept -> int; +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal_fast64_t x) noexcept -> int; +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal128_t x) noexcept -> int; +BOOST_DECIMAL_EXPORT constexpr auto quantexp(decimal_fast128_t x) noexcept -> int; + +namespace detail { + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) // Conditional expression is constant +#endif + +template +constexpr auto total_ordering_impl(const T x, const T y) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, T, bool) +{ + // Part d: Check for unordered values + const auto x_nan {isnan(x)}; + const auto x_neg {signbit(x)}; + const auto y_nan {isnan(y)}; + const auto y_neg {signbit(y)}; + + if (x_nan && x_neg && !y_nan) + { + // d.1 + return true; + } + if (!x_nan && y_nan && !y_neg) + { + // d.2 + return true; + } + if (x_nan && y_nan) + { + // d.3.i + if (x_neg && !y_neg) + { + return true; + } + // d.3.ii + const auto x_signaling {issignaling(x)}; + const auto y_signaling {issignaling(y)}; + if (x_signaling || y_signaling) + { + if (x_signaling && !y_signaling) + { + return !x_neg; + } + else if (!x_signaling && y_signaling) + { + return y_neg; + } + } + // d.3.iii + const auto x_payload {read_payload(x)}; + const auto y_payload {read_payload(y)}; + + if (x_payload != y_payload) + { + if (!x_neg && !y_neg) + { + return x_payload < y_payload; + } + else if (x_neg && y_neg) + { + return x_payload > y_payload; + } + else if (x_neg && !y_neg) + { + return true; + } + else + { + return false; + } + } + + return false; + } + + if (x < y) + { + // part a + return true; + } + else if (x > y) + { + // part b + return false; + } + else + { + if (x == 0 && y == 0) + { + if (x_neg && !y_neg) + { + // c.1 + return true; + } + else if (!x_neg && y_neg) + { + // c.2 + return false; + } + } + + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_ieee_type_v) + { + if (x_neg && y_neg) + { + // c.3.i + return quantexp(x) >= quantexp(y); + } + else + { + // c.3.ii + return quantexp(x) <= quantexp(y); + } + } + else + { + // Since things are normalized this will always be true + return true; + } + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace detail + +BOOST_DECIMAL_EXPORT template +constexpr auto comparetotal(const T1 lhs, const T2 rhs) noexcept + BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, T1, detail::is_decimal_floating_point_v, T2, bool) +{ + using larger_type = std::conditional_t >= detail::decimal_val_v, T1, T2>; + return detail::total_ordering_impl(static_cast(lhs), static_cast(rhs)); +} + +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_CMATH_TOTAL_ORDER_HPP diff --git a/include/boost/decimal/detail/cmath/cos.hpp b/include/boost/decimal/detail/cmath/cos.hpp index 8f4d4c256..40aad502b 100644 --- a/include/boost/decimal/detail/cmath/cos.hpp +++ b/include/boost/decimal/detail/cmath/cos.hpp @@ -65,7 +65,7 @@ constexpr auto cos_impl(const T x) noexcept const T two_x = x * 2; const auto k = static_cast(two_x / numbers::pi_v); - const auto n = static_cast(k % static_cast(UINT8_C(4))); + const auto n = k % static_cast(UINT8_C(4)); const T two_r { two_x - (numbers::pi_v * k) }; @@ -122,19 +122,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto cos(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::cos_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/cosh.hpp b/include/boost/decimal/detail/cmath/cosh.hpp index 794f01b3a..a48e912b5 100644 --- a/include/boost/decimal/detail/cmath/cosh.hpp +++ b/include/boost/decimal/detail/cmath/cosh.hpp @@ -87,19 +87,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto cosh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::cosh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/ellint_1.hpp b/include/boost/decimal/detail/cmath/ellint_1.hpp index 0208a6443..ec0c88cdd 100644 --- a/include/boost/decimal/detail/cmath/ellint_1.hpp +++ b/include/boost/decimal/detail/cmath/ellint_1.hpp @@ -168,19 +168,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto ellint_1(const T k, const T phi) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::ellint_1_impl(static_cast(k), static_cast(phi))); } @@ -189,19 +177,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto comp_ellint_1(const T k) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::comp_ellint_1_impl(static_cast(k))); } diff --git a/include/boost/decimal/detail/cmath/ellint_2.hpp b/include/boost/decimal/detail/cmath/ellint_2.hpp index 607053559..9d4887afa 100644 --- a/include/boost/decimal/detail/cmath/ellint_2.hpp +++ b/include/boost/decimal/detail/cmath/ellint_2.hpp @@ -166,19 +166,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto ellint_2(const T k, const T phi) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::ellint_2_impl(static_cast(k), static_cast(phi))); } @@ -187,19 +175,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto comp_ellint_2(const T k) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::comp_ellint_2_impl(static_cast(k))); } diff --git a/include/boost/decimal/detail/cmath/erf.hpp b/include/boost/decimal/detail/cmath/erf.hpp index ba5a0f6d4..088e0bf67 100644 --- a/include/boost/decimal/detail/cmath/erf.hpp +++ b/include/boost/decimal/detail/cmath/erf.hpp @@ -150,11 +150,11 @@ constexpr auto erf_calc_impl(const T z, bool invert) noexcept -> T constexpr T Y {UINT64_C(1044948577880859375), -18}; constexpr std::array P = { T{UINT64_C(8343058921465319890), -20}, - T{UINT64_C(3380972830755654137), -19, true}, - T{UINT64_C(5096027344060672046), -20, true}, - T{UINT64_C(9049063461585377944), -21, true}, - T{UINT64_C(4894686514647986692), -22, true}, - T{UINT64_C(2003056263661518778), -23, true} + T{UINT64_C(3380972830755654137), -19, construction_sign::negative}, + T{UINT64_C(5096027344060672046), -20, construction_sign::negative}, + T{UINT64_C(9049063461585377944), -21, construction_sign::negative}, + T{UINT64_C(4894686514647986692), -22, construction_sign::negative}, + T{UINT64_C(2003056263661518778), -23, construction_sign::negative} }; constexpr std::array Q = { T{UINT64_C(1), 0}, @@ -183,7 +183,7 @@ constexpr auto erf_calc_impl(const T z, bool invert) noexcept -> T // Maximum Relative Change in Control Points: 5.110e-03 constexpr T Y {UINT64_C(4059357643127441406), -19}; constexpr std::array P = { - T{UINT64_C(9809059221628120317), -20, true}, + T{UINT64_C(9809059221628120317), -20, construction_sign::negative}, T{UINT64_C(1599890899229691413), -19}, T{UINT64_C(2223598216199357124), -19}, T{UINT64_C(1273039217035773623), -19}, @@ -214,7 +214,7 @@ constexpr auto erf_calc_impl(const T z, bool invert) noexcept -> T constexpr T Y {UINT64_C(5067281723022460937), -19}; constexpr std::array P = { - T{UINT64_C(2435004762076984022), -20, true}, + T{UINT64_C(2435004762076984022), -20, construction_sign::negative}, T{UINT64_C(3435226879356714513), -20}, T{UINT64_C(5054208243055449495), -20}, T{UINT64_C(2574793259177573882), -20}, @@ -277,13 +277,13 @@ constexpr auto erf_calc_impl(const T z, bool invert) noexcept -> T constexpr std::array P = { T{UINT64_C(5934387930080502141), -21}, T{UINT64_C(2806662310090897139), -20}, - T{UINT64_C(1415978352045830500), -19, true}, - T{UINT64_C(9780882011543005488), -19, true}, - T{UINT64_C(5473515277960120494), -18, true}, - T{UINT64_C(1386773046602453266), -17, true}, - T{UINT64_C(2712749487205398217), -17, true}, - T{UINT64_C(2925451527470094615), -17, true}, - T{UINT64_C(1688657744997996769), -17, true} + T{UINT64_C(1415978352045830500), -19, construction_sign::negative}, + T{UINT64_C(9780882011543005488), -19, construction_sign::negative}, + T{UINT64_C(5473515277960120494), -18, construction_sign::negative}, + T{UINT64_C(1386773046602453266), -17, construction_sign::negative}, + T{UINT64_C(2712749487205398217), -17, construction_sign::negative}, + T{UINT64_C(2925451527470094615), -17, construction_sign::negative}, + T{UINT64_C(1688657744997996769), -17, construction_sign::negative} }; constexpr std::array Q = { T{UINT64_C(1), 0}, @@ -380,13 +380,13 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no constexpr decimal128_t Y {UINT64_C(10841522216796875), -16}; constexpr std::array P = { decimal128_t{int128::uint128_t{UINT64_C(239754751511176), UINT64_C(15346977608939294094)}, -35}, - decimal128_t{int128::uint128_t{UINT64_C(192712955706190), UINT64_C(2786476198819993080)}, -34, true}, - decimal128_t{int128::uint128_t{UINT64_C(315600174339923), UINT64_C(3061015393610667132)}, -35, true}, - decimal128_t{int128::uint128_t{UINT64_C(61091917605891), UINT64_C(1019303663574361383)}, -35, true}, - decimal128_t{int128::uint128_t{UINT64_C(436787460032112), UINT64_C(1788731756814597798)}, -37, true}, - decimal128_t{int128::uint128_t{UINT64_C(306994537534154), UINT64_C(5857517254794866796)}, -38, true}, - decimal128_t{int128::uint128_t{UINT64_C(91970165438019), UINT64_C(5861580289485811316)}, -39, true}, - decimal128_t{int128::uint128_t{UINT64_C(186725770436288), UINT64_C(13306862545778890572)}, -41, true} + decimal128_t{int128::uint128_t{UINT64_C(192712955706190), UINT64_C(2786476198819993080)}, -34, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(315600174339923), UINT64_C(3061015393610667132)}, -35, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(61091917605891), UINT64_C(1019303663574361383)}, -35, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(436787460032112), UINT64_C(1788731756814597798)}, -37, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(306994537534154), UINT64_C(5857517254794866796)}, -38, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(91970165438019), UINT64_C(5861580289485811316)}, -39, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(186725770436288), UINT64_C(13306862545778890572)}, -41, construction_sign::negative} }; constexpr std::array Q = { decimal128_t{UINT64_C(1)}, @@ -418,7 +418,7 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no // Maximum Relative Change in Control Points: 6.127e-05 constexpr decimal128_t Y {int128::uint128_t{UINT64_C(201595030518654), UINT64_C(473630177736155136)}, -34}; constexpr std::array P = { - decimal128_t{int128::uint128_t{UINT64_C(347118283305744), UINT64_C(13376242280388530596)}, -35, true}, + decimal128_t{int128::uint128_t{UINT64_C(347118283305744), UINT64_C(13376242280388530596)}, -35, construction_sign::negative}, decimal128_t{int128::uint128_t{UINT64_C(108837567018829), UINT64_C(8949668339020089396)}, -34}, decimal128_t{int128::uint128_t{UINT64_C(205156638136972), UINT64_C(8479374702376111038)}, -34}, decimal128_t{int128::uint128_t{UINT64_C(165456838044201), UINT64_C(8069456678105518694)}, -34}, @@ -453,7 +453,7 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no // Maximum Relative Change in Control Points: 6.104e-05 constexpr decimal128_t Y {int128::uint128_t{UINT64_C(247512601803296), UINT64_C(15871045498809073664)}, -34}; constexpr std::array P = { - decimal128_t{int128::uint128_t{UINT64_C(157190807096733), UINT64_C(3137315625382477952)}, -35, true}, + decimal128_t{int128::uint128_t{UINT64_C(157190807096733), UINT64_C(3137315625382477952)}, -35, construction_sign::negative}, decimal128_t{int128::uint128_t{UINT64_C(470641968793799), UINT64_C(4414359042974488606)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(91817523159857), UINT64_C(7399250419088684648)}, -34}, decimal128_t{int128::uint128_t{UINT64_C(72372915581218), UINT64_C(10309284290091665052)}, -34}, @@ -487,7 +487,7 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no // Max Error found at long double precision = 1.998462e-35 constexpr decimal128_t Y {int128::uint128_t{UINT64_C(272406602338080), UINT64_C(4210402105957662720)}, -34}; constexpr std::array P = { - decimal128_t{int128::uint128_t{UINT64_C(109088969685101), UINT64_C(16218967400415836944)}, -35, true}, + decimal128_t{int128::uint128_t{UINT64_C(109088969685101), UINT64_C(16218967400415836944)}, -35, construction_sign::negative}, decimal128_t{int128::uint128_t{UINT64_C(179904028726584), UINT64_C(15631322379863663306)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(388449429341863), UINT64_C(3427022958736033442)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(295897921010371), UINT64_C(1587344243601439264)}, -35}, @@ -523,7 +523,7 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no // Max Error found at long double precision = 5.794737e-36 constexpr decimal128_t Y {int128::uint128_t{UINT64_C(286754050062812), UINT64_C(9099170110843895808)}, -34}; constexpr std::array P = { - decimal128_t{int128::uint128_t{UINT64_C(489057861995043), UINT64_C(13133699014237994112)}, -36, true}, + decimal128_t{int128::uint128_t{UINT64_C(489057861995043), UINT64_C(13133699014237994112)}, -36, construction_sign::negative}, decimal128_t{int128::uint128_t{UINT64_C(78716949829450), UINT64_C(16506161309933484600)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(163541727676567), UINT64_C(6172848388919604508)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(116849098118354), UINT64_C(5575376344146644276)}, -35}, @@ -558,7 +558,7 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no // Max Error found at long double precision = 1.747062e-36 constexpr decimal128_t Y {int128::uint128_t{UINT64_C(292937225141646), UINT64_C(6920050031251800064)}, -34}; constexpr std::array P = { - decimal128_t{int128::uint128_t{UINT64_C(182706965924257), UINT64_C(1687510779571187718)}, -36, true}, + decimal128_t{int128::uint128_t{UINT64_C(182706965924257), UINT64_C(1687510779571187718)}, -36, construction_sign::negative}, decimal128_t{int128::uint128_t{UINT64_C(56892448168985), UINT64_C(572440462241151398)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(80518338580783), UINT64_C(5160816315849708842)}, -35}, decimal128_t{int128::uint128_t{UINT64_C(442730178280838), UINT64_C(9281603077550627672)}, -36}, @@ -698,16 +698,16 @@ constexpr auto erf_calc_impl(const decimal128_t z, bool invert) no constexpr std::array P = { decimal128_t{int128::uint128_t{UINT64_C(499232842962978), UINT64_C(8830380466473645912)}, -37}, decimal128_t{int128::uint128_t{UINT64_C(174252455201786), UINT64_C(2479322227425103044)}, -36}, - decimal128_t{int128::uint128_t{UINT64_C(135772070143446), UINT64_C(11134505343181509494)}, -34, true}, - decimal128_t{int128::uint128_t{UINT64_C(491581404144094), UINT64_C(17408157071053090076)}, -34, true}, - decimal128_t{int128::uint128_t{UINT64_C(483680789016642), UINT64_C(16561429108077906378)}, -33, true}, - decimal128_t{int128::uint128_t{UINT64_C(118068225278210), UINT64_C(1054524085213991420)}, -32, true}, - decimal128_t{int128::uint128_t{UINT64_C(494099073316133), UINT64_C(5874532072246990782)}, -32, true}, - decimal128_t{int128::uint128_t{UINT64_C(78131897092350), UINT64_C(2017084479481280073)}, -31, true}, - decimal128_t{int128::uint128_t{UINT64_C(170135756926931), UINT64_C(10167058340138167254)}, -31, true}, - decimal128_t{int128::uint128_t{UINT64_C(148055281207309), UINT64_C(5898340572591612296)}, -31, true}, - decimal128_t{int128::uint128_t{UINT64_C(147262609119790), UINT64_C(18318474967693923790)}, -31, true}, - decimal128_t{int128::uint128_t{UINT64_C(325548278155557), UINT64_C(11031073479106502338)}, -32, true} + decimal128_t{int128::uint128_t{UINT64_C(135772070143446), UINT64_C(11134505343181509494)}, -34, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(491581404144094), UINT64_C(17408157071053090076)}, -34, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(483680789016642), UINT64_C(16561429108077906378)}, -33, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(118068225278210), UINT64_C(1054524085213991420)}, -32, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(494099073316133), UINT64_C(5874532072246990782)}, -32, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(78131897092350), UINT64_C(2017084479481280073)}, -31, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(170135756926931), UINT64_C(10167058340138167254)}, -31, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(148055281207309), UINT64_C(5898340572591612296)}, -31, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(147262609119790), UINT64_C(18318474967693923790)}, -31, construction_sign::negative}, + decimal128_t{int128::uint128_t{UINT64_C(325548278155557), UINT64_C(11031073479106502338)}, -32, construction_sign::negative} }; constexpr std::array Q = { decimal128_t{1}, @@ -803,19 +803,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto erf(const T z) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::erf_impl(static_cast(z))); } @@ -824,19 +812,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto erfc(const T z) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::erfc_impl(static_cast(z))); } diff --git a/include/boost/decimal/detail/cmath/exp.hpp b/include/boost/decimal/detail/cmath/exp.hpp index 03113d15f..34429ebe6 100644 --- a/include/boost/decimal/detail/cmath/exp.hpp +++ b/include/boost/decimal/detail/cmath/exp.hpp @@ -77,7 +77,7 @@ constexpr auto exp_impl(T x) noexcept { if (nf2 < 64) { - result *= T { static_cast(UINT64_C(1) << static_cast(nf2)), 0 }; + result *= T { UINT64_C(1) << static_cast(nf2), 0 }; } else { @@ -96,19 +96,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto exp(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::exp_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/exp2.hpp b/include/boost/decimal/detail/cmath/exp2.hpp index c7dcd51d6..ff9170ed0 100644 --- a/include/boost/decimal/detail/cmath/exp2.hpp +++ b/include/boost/decimal/detail/cmath/exp2.hpp @@ -30,19 +30,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto exp2(const T num) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::exp2_impl(static_cast(num))); } diff --git a/include/boost/decimal/detail/cmath/expm1.hpp b/include/boost/decimal/detail/cmath/expm1.hpp index 858236d3f..9647c5977 100644 --- a/include/boost/decimal/detail/cmath/expm1.hpp +++ b/include/boost/decimal/detail/cmath/expm1.hpp @@ -86,19 +86,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto expm1(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::expm1_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/floor.hpp b/include/boost/decimal/detail/cmath/floor.hpp index 14ec7d72e..730922660 100644 --- a/include/boost/decimal/detail/cmath/floor.hpp +++ b/include/boost/decimal/detail/cmath/floor.hpp @@ -14,6 +14,7 @@ #include #include "../int128.hpp" #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -30,7 +31,7 @@ constexpr auto floor BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (const T val) noex using DivType = typename T::significand_type; constexpr T zero {0, 0}; - constexpr T neg_one {1U, 0, true}; + constexpr T neg_one {1U, 0, construction_sign::negative}; const auto fp {fpclassify(val)}; switch (fp) diff --git a/include/boost/decimal/detail/cmath/fma.hpp b/include/boost/decimal/detail/cmath/fma.hpp index 5b30fc340..8c9ede307 100644 --- a/include/boost/decimal/detail/cmath/fma.hpp +++ b/include/boost/decimal/detail/cmath/fma.hpp @@ -33,8 +33,8 @@ using components_type = std::conditional_t::value template constexpr auto d32_fma_impl(T x, T y, T z) noexcept -> T { - using T_components_type = components_type; - using exp_type = typename T::biased_exponent_type; + using promoted_type = std::conditional_t::value, decimal64_t, decimal_fast64_t>; + using promoted_components = components_type; // Apply the add #ifndef BOOST_DECIMAL_FAST_MATH @@ -47,14 +47,10 @@ constexpr auto d32_fma_impl(T x, T y, T z) noexcept -> T } #endif - int exp_lhs {}; - auto sig_lhs = frexp10(x, &exp_lhs); + const auto x_components {x.to_components()}; + const auto y_components {y.to_components()}; - int exp_rhs {}; - auto sig_rhs = frexp10(y, &exp_rhs); - - auto first_res = detail::mul_impl(sig_lhs, static_cast(exp_lhs), x < 0, - sig_rhs, static_cast(exp_rhs), y < 0); + auto first_res {detail::mul_impl(x_components, y_components)}; // Apply the mul on the carried components // We still create the result as a decimal type to check for non-finite values and comparisons, @@ -72,19 +68,18 @@ constexpr auto d32_fma_impl(T x, T y, T z) noexcept -> T } #endif - int exp_z {}; - auto sig_z = frexp10(z, &exp_z); - detail::normalize(first_res.sig, first_res.exp); + auto z_components {static_cast(z.to_components())}; + detail::expand_significand(z_components.sig, z_components.exp); + detail::expand_significand(first_res.sig, first_res.exp); - return detail::d32_add_impl(first_res.sig, first_res.exp, first_res.sign, - sig_z, static_cast(exp_z), z < 0); + return detail::add_impl(first_res, z_components); } template constexpr auto d64_fma_impl(T x, T y, T z) noexcept -> T { - using T_components_type = components_type; - using exp_type = typename T::biased_exponent_type; + using promoted_type = std::conditional_t::value, decimal128_t, decimal_fast128_t>; + using promoted_components = components_type; // Apply the add #ifndef BOOST_DECIMAL_FAST_MATH @@ -97,14 +92,10 @@ constexpr auto d64_fma_impl(T x, T y, T z) noexcept -> T } #endif - int exp_lhs {}; - auto sig_lhs = frexp10(x, &exp_lhs); - - int exp_rhs {}; - auto sig_rhs = frexp10(y, &exp_rhs); + const auto x_components {x.to_components()}; + const auto y_components {y.to_components()}; - auto first_res = detail::d64_mul_impl(sig_lhs, static_cast(exp_lhs), x < 0, - sig_rhs, static_cast(exp_rhs), y < 0); + auto first_res {detail::mul_impl(x_components, y_components)}; // Apply the mul on the carried components // We still create the result as a decimal type to check for non-finite values and comparisons, @@ -121,15 +112,11 @@ constexpr auto d64_fma_impl(T x, T y, T z) noexcept -> T } #endif - const bool abs_lhs_bigger {abs(complete_lhs) > abs(z)}; - - int exp_z {}; - auto sig_z = frexp10(z, &exp_z); - detail::normalize(first_res.sig, first_res.exp); + auto z_components {static_cast(z.to_components())}; + detail::expand_significand(z_components.sig, z_components.exp); + detail::expand_significand(first_res.sig, first_res.exp); - return detail::d64_add_impl(first_res.sig, first_res.exp, first_res.sign, - sig_z, static_cast(exp_z), z < 0, - abs_lhs_bigger); + return detail::d128_add_impl_new(first_res, z_components); } template @@ -179,7 +166,7 @@ BOOST_DECIMAL_EXPORT constexpr auto fma(const decimal32_t x, const decimal32_t y return detail::d32_fma_impl(x, y, z); } -BOOST_DECIMAL_EXPORT constexpr auto fma(decimal64_t x, decimal64_t y, decimal64_t z) noexcept -> decimal64_t +BOOST_DECIMAL_EXPORT constexpr auto fma(const decimal64_t x, const decimal64_t y, const decimal64_t z) noexcept -> decimal64_t { return detail::d64_fma_impl(x, y, z); } diff --git a/include/boost/decimal/detail/cmath/fmax.hpp b/include/boost/decimal/detail/cmath/fmax.hpp index 5f376efd6..c7c8ed800 100644 --- a/include/boost/decimal/detail/cmath/fmax.hpp +++ b/include/boost/decimal/detail/cmath/fmax.hpp @@ -28,12 +28,29 @@ constexpr auto fmax(const T1 lhs, const T2 rhs) noexcept #ifndef BOOST_DECIMAL_FAST_MATH if (isnan(lhs) && !isnan(rhs)) { - return static_cast(rhs); + if (issignaling(lhs)) + { + return nan_conversion(lhs); + } + else + { + return static_cast(rhs); + } } - else if ((!isnan(lhs) && isnan(rhs)) || - (isnan(lhs) && isnan(rhs))) + else if ((!isnan(lhs) && isnan(rhs)) || (isnan(lhs) && isnan(rhs))) { - return static_cast(lhs); + if (issignaling(lhs)) + { + return nan_conversion(lhs); + } + else if (issignaling(rhs)) + { + return nan_conversion(rhs); + } + else + { + return static_cast(lhs); + } } #endif diff --git a/include/boost/decimal/detail/cmath/fmin.hpp b/include/boost/decimal/detail/cmath/fmin.hpp index 5d94fd87b..70baa715c 100644 --- a/include/boost/decimal/detail/cmath/fmin.hpp +++ b/include/boost/decimal/detail/cmath/fmin.hpp @@ -27,12 +27,29 @@ constexpr auto fmin(const T1 lhs, const T2 rhs) noexcept #ifndef BOOST_DECIMAL_FAST_MATH if (isnan(lhs) && !isnan(rhs)) { - return static_cast(rhs); + if (issignaling(lhs)) + { + return nan_conversion(lhs); + } + else + { + return static_cast(rhs); + } } - else if ((!isnan(lhs) && isnan(rhs)) || - (isnan(lhs) && isnan(rhs))) + else if ((!isnan(lhs) && isnan(rhs)) || (isnan(lhs) && isnan(rhs))) { - return static_cast(lhs); + if (issignaling(lhs)) + { + return nan_conversion(lhs); + } + else if (issignaling(rhs)) + { + return nan_conversion(rhs); + } + else + { + return static_cast(lhs); + } } #endif diff --git a/include/boost/decimal/detail/cmath/frexp.hpp b/include/boost/decimal/detail/cmath/frexp.hpp index 97ccac53a..a95833281 100644 --- a/include/boost/decimal/detail/cmath/frexp.hpp +++ b/include/boost/decimal/detail/cmath/frexp.hpp @@ -57,15 +57,7 @@ constexpr auto frexp_impl(const T v, int* expon) noexcept if(b_neg) { result_frexp = -result_frexp; } - auto t = - static_cast - ( - static_cast - ( - static_cast(ilogb(result_frexp) - detail::bias) * INT32_C(1000) - ) - / INT32_C(301) - ); + auto t = static_cast(ilogb(result_frexp) - detail::bias) * INT32_C(1000) / 301; result_frexp *= detail::pow_2_impl(-t); @@ -104,19 +96,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto frexp(const T v, int* expon) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::frexp_impl(static_cast(v), expon)); } diff --git a/include/boost/decimal/detail/cmath/hermite.hpp b/include/boost/decimal/detail/cmath/hermite.hpp index 2a26f107d..cf6724ad5 100644 --- a/include/boost/decimal/detail/cmath/hermite.hpp +++ b/include/boost/decimal/detail/cmath/hermite.hpp @@ -61,19 +61,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto hermite(const unsigned n, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::hermite_impl(n, static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/ilogb.hpp b/include/boost/decimal/detail/cmath/ilogb.hpp index b2e972840..b11ca8206 100644 --- a/include/boost/decimal/detail/cmath/ilogb.hpp +++ b/include/boost/decimal/detail/cmath/ilogb.hpp @@ -28,16 +28,16 @@ constexpr auto ilogb(const T d) noexcept if (fpc == FP_ZERO) { - result = static_cast(FP_ILOGB0); + result = FP_ILOGB0; } #ifndef BOOST_DECIMAL_FAST_MATH else if (fpc == FP_INFINITE) { - result = static_cast(INT_MAX); + result = INT_MAX; } else if (fpc == FP_NAN) { - result = static_cast(FP_ILOGBNAN); + result = FP_ILOGBNAN; } #endif else diff --git a/include/boost/decimal/detail/cmath/impl/asin_impl.hpp b/include/boost/decimal/detail/cmath/impl/asin_impl.hpp index f14dd681b..8d120442c 100644 --- a/include/boost/decimal/detail/cmath/impl/asin_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/asin_impl.hpp @@ -9,6 +9,7 @@ #include #include "../../int128.hpp" #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -43,9 +44,9 @@ struct asin_table_imp // Estimated max error: 7.3651618860008751e-11 static constexpr d32_coeffs_t d32_coeffs = {{ decimal32_t {UINT64_C(263887099755925), -15}, - decimal32_t {UINT64_C(43491393212832818), -17, true}, + decimal32_t {UINT64_C(43491393212832818), -17, construction_sign::negative}, decimal32_t {UINT64_C(38559884786102105), -17}, - decimal32_t {UINT64_C(13977130653211101), -17, true}, + decimal32_t {UINT64_C(13977130653211101), -17, construction_sign::negative}, decimal32_t {UINT64_C(54573213517731915), -18}, decimal32_t {UINT64_C(64851743877986187), -18}, decimal32_t {UINT64_C(11606701725692841), -19}, @@ -57,9 +58,9 @@ struct asin_table_imp static constexpr d32_fast_coeffs_t d32_fast_coeffs = {{ decimal_fast32_t {UINT64_C(263887099755925), -15}, - decimal_fast32_t {UINT64_C(43491393212832818), -17, true}, + decimal_fast32_t {UINT64_C(43491393212832818), -17, construction_sign::negative}, decimal_fast32_t {UINT64_C(38559884786102105), -17}, - decimal_fast32_t {UINT64_C(13977130653211101), -17, true}, + decimal_fast32_t {UINT64_C(13977130653211101), -17, construction_sign::negative}, decimal_fast32_t {UINT64_C(54573213517731915), -18}, decimal_fast32_t {UINT64_C(64851743877986187), -18}, decimal_fast32_t {UINT64_C(11606701725692841), -19}, @@ -73,15 +74,15 @@ struct asin_table_imp // Estimated max error: 6.0872797932519911178133457751215133e-19 static constexpr d64_coeffs_t d64_coeffs = {{ decimal64_t {UINT64_C(2201841632531125594), -18}, - decimal64_t {UINT64_C(9319383818485265142), -18, true}, + decimal64_t {UINT64_C(9319383818485265142), -18, construction_sign::negative}, decimal64_t {UINT64_C(1876826158920611297), -17}, - decimal64_t {UINT64_C(2351630530022519158), -17, true}, + decimal64_t {UINT64_C(2351630530022519158), -17, construction_sign::negative}, decimal64_t {UINT64_C(2046603318375014621), -17}, - decimal64_t {UINT64_C(1304427904865204196), -17, true}, + decimal64_t {UINT64_C(1304427904865204196), -17, construction_sign::negative}, decimal64_t {UINT64_C(6308794339076719731), -18}, - decimal64_t {UINT64_C(2333806156857836980), -18, true}, + decimal64_t {UINT64_C(2333806156857836980), -18, construction_sign::negative}, decimal64_t {UINT64_C(6826985955727270693), -19}, - decimal64_t {UINT64_C(1326415745606167277), -19, true}, + decimal64_t {UINT64_C(1326415745606167277), -19, construction_sign::negative}, decimal64_t {UINT64_C(2747750823768175476), -20}, decimal64_t {UINT64_C(2660509753516203115), -20}, decimal64_t {UINT64_C(3977122944636320545), -22}, @@ -97,15 +98,15 @@ struct asin_table_imp static constexpr d64_fast_coeffs_t d64_fast_coeffs = {{ decimal_fast64_t {UINT64_C(2201841632531125594), -18}, - decimal_fast64_t {UINT64_C(9319383818485265142), -18, true}, + decimal_fast64_t {UINT64_C(9319383818485265142), -18, construction_sign::negative}, decimal_fast64_t {UINT64_C(1876826158920611297), -17}, - decimal_fast64_t {UINT64_C(2351630530022519158), -17, true}, + decimal_fast64_t {UINT64_C(2351630530022519158), -17, construction_sign::negative}, decimal_fast64_t {UINT64_C(2046603318375014621), -17}, - decimal_fast64_t {UINT64_C(1304427904865204196), -17, true}, + decimal_fast64_t {UINT64_C(1304427904865204196), -17, construction_sign::negative}, decimal_fast64_t {UINT64_C(6308794339076719731), -18}, - decimal_fast64_t {UINT64_C(2333806156857836980), -18, true}, + decimal_fast64_t {UINT64_C(2333806156857836980), -18, construction_sign::negative}, decimal_fast64_t {UINT64_C(6826985955727270693), -19}, - decimal_fast64_t {UINT64_C(1326415745606167277), -19, true}, + decimal_fast64_t {UINT64_C(1326415745606167277), -19, construction_sign::negative}, decimal_fast64_t {UINT64_C(2747750823768175476), -20}, decimal_fast64_t {UINT64_C(2660509753516203115), -20}, decimal_fast64_t {UINT64_C(3977122944636320545), -22}, @@ -123,27 +124,27 @@ struct asin_table_imp // Estimated max error: 1.084502473818005718919720519483941e-34 static constexpr d128_coeffs_t d128_coeffs = {{ decimal128_t {int128::uint128_t{UINT64_C(236367828732266), UINT64_C(4865873281479238114)}, -31}, - decimal128_t {int128::uint128_t{UINT64_C(218966359248756), UINT64_C(1393338271545593644)}, -30, true}, + decimal128_t {int128::uint128_t{UINT64_C(218966359248756), UINT64_C(1393338271545593644)}, -30, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(98104038983693), UINT64_C(4819646069944316372)}, -29}, - decimal128_t {int128::uint128_t{UINT64_C(282853615727310), UINT64_C(10104044375051504970)}, -29, true}, + decimal128_t {int128::uint128_t{UINT64_C(282853615727310), UINT64_C(10104044375051504970)}, -29, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(58930987436658), UINT64_C(3829646337759276014)}, -28}, - decimal128_t {int128::uint128_t{UINT64_C(94467942291578), UINT64_C(14212526794757587650)}, -28, true}, + decimal128_t {int128::uint128_t{UINT64_C(94467942291578), UINT64_C(14212526794757587650)}, -28, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(121156109355190), UINT64_C(6171523396929956760)}, -28}, - decimal128_t {int128::uint128_t{UINT64_C(127640043209581), UINT64_C(8369619306382995314)}, -28, true}, + decimal128_t {int128::uint128_t{UINT64_C(127640043209581), UINT64_C(8369619306382995314)}, -28, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(112556984011870), UINT64_C(14401172681696800280)}, -28}, - decimal128_t {int128::uint128_t{UINT64_C(84240716950351), UINT64_C(10152945328926072964)}, -28, true}, + decimal128_t {int128::uint128_t{UINT64_C(84240716950351), UINT64_C(10152945328926072964)}, -28, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(540724366020485), UINT64_C(8813105586620168570)}, -29}, - decimal128_t {int128::uint128_t{UINT64_C(300054630162323), UINT64_C(4862687399308912842)}, -29, true}, + decimal128_t {int128::uint128_t{UINT64_C(300054630162323), UINT64_C(4862687399308912842)}, -29, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(144827005285082), UINT64_C(4790810090757542758)}, -29}, - decimal128_t {int128::uint128_t{UINT64_C(61085784025333), UINT64_C(3908625641731373429)}, -29, true}, + decimal128_t {int128::uint128_t{UINT64_C(61085784025333), UINT64_C(3908625641731373429)}, -29, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(225929173229512), UINT64_C(18404095637827467688)}, -30}, - decimal128_t {int128::uint128_t{UINT64_C(73452862511516), UINT64_C(2655967943189644664)}, -30, true}, + decimal128_t {int128::uint128_t{UINT64_C(73452862511516), UINT64_C(2655967943189644664)}, -30, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(210254502661653), UINT64_C(14174199201997297032)}, -31}, - decimal128_t {int128::uint128_t{UINT64_C(530269670900176), UINT64_C(3023877239296322874)}, -32, true}, + decimal128_t {int128::uint128_t{UINT64_C(530269670900176), UINT64_C(3023877239296322874)}, -32, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(117870705400334), UINT64_C(8785618254907029456)}, -32}, - decimal128_t {int128::uint128_t{UINT64_C(230285265351731), UINT64_C(8107756519153341434)}, -33, true}, + decimal128_t {int128::uint128_t{UINT64_C(230285265351731), UINT64_C(8107756519153341434)}, -33, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(397318429350031), UINT64_C(567549410172969484)}, -34}, - decimal128_t {int128::uint128_t{UINT64_C(54772616787306), UINT64_C(4168475956004989379)}, -34, true}, + decimal128_t {int128::uint128_t{UINT64_C(54772616787306), UINT64_C(4168475956004989379)}, -34, construction_sign::negative}, decimal128_t {int128::uint128_t{UINT64_C(79509164538790), UINT64_C(17928590725399689320)}, -35}, decimal128_t {int128::uint128_t{UINT64_C(534376054761824), UINT64_C(1987644731805023176)}, -36}, decimal128_t {int128::uint128_t{UINT64_C(92204817966183), UINT64_C(17576450582561384882)}, -37}, @@ -167,27 +168,27 @@ struct asin_table_imp static constexpr d128_fast_coeffs_t d128_fast_coeffs = {{ decimal_fast128_t {int128::uint128_t{UINT64_C(236367828732266), UINT64_C(4865873281479238114)}, -31}, - decimal_fast128_t {int128::uint128_t{UINT64_C(218966359248756), UINT64_C(1393338271545593644)}, -30, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(218966359248756), UINT64_C(1393338271545593644)}, -30, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(98104038983693), UINT64_C(4819646069944316372)}, -29}, - decimal_fast128_t {int128::uint128_t{UINT64_C(282853615727310), UINT64_C(10104044375051504970)}, -29, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(282853615727310), UINT64_C(10104044375051504970)}, -29, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(58930987436658), UINT64_C(3829646337759276014)}, -28}, - decimal_fast128_t {int128::uint128_t{UINT64_C(94467942291578), UINT64_C(14212526794757587650)}, -28, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(94467942291578), UINT64_C(14212526794757587650)}, -28, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(121156109355190), UINT64_C(6171523396929956760)}, -28}, - decimal_fast128_t {int128::uint128_t{UINT64_C(127640043209581), UINT64_C(8369619306382995314)}, -28, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(127640043209581), UINT64_C(8369619306382995314)}, -28, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(112556984011870), UINT64_C(14401172681696800280)}, -28}, - decimal_fast128_t {int128::uint128_t{UINT64_C(84240716950351), UINT64_C(10152945328926072964)}, -28, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(84240716950351), UINT64_C(10152945328926072964)}, -28, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(540724366020485), UINT64_C(8813105586620168570)}, -29}, - decimal_fast128_t {int128::uint128_t{UINT64_C(300054630162323), UINT64_C(4862687399308912842)}, -29, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(300054630162323), UINT64_C(4862687399308912842)}, -29, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(144827005285082), UINT64_C(4790810090757542758)}, -29}, - decimal_fast128_t {int128::uint128_t{UINT64_C(61085784025333), UINT64_C(3908625641731373429)}, -29, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(61085784025333), UINT64_C(3908625641731373429)}, -29, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(225929173229512), UINT64_C(18404095637827467688)}, -30}, - decimal_fast128_t {int128::uint128_t{UINT64_C(73452862511516), UINT64_C(2655967943189644664)}, -30, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(73452862511516), UINT64_C(2655967943189644664)}, -30, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(210254502661653), UINT64_C(14174199201997297032)}, -31}, - decimal_fast128_t {int128::uint128_t{UINT64_C(530269670900176), UINT64_C(3023877239296322874)}, -32, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(530269670900176), UINT64_C(3023877239296322874)}, -32, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(117870705400334), UINT64_C(8785618254907029456)}, -32}, - decimal_fast128_t {int128::uint128_t{UINT64_C(230285265351731), UINT64_C(8107756519153341434)}, -33, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(230285265351731), UINT64_C(8107756519153341434)}, -33, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(397318429350031), UINT64_C(567549410172969484)}, -34}, - decimal_fast128_t {int128::uint128_t{UINT64_C(54772616787306), UINT64_C(4168475956004989379)}, -34, true}, + decimal_fast128_t {int128::uint128_t{UINT64_C(54772616787306), UINT64_C(4168475956004989379)}, -34, construction_sign::negative}, decimal_fast128_t {int128::uint128_t{UINT64_C(79509164538790), UINT64_C(17928590725399689320)}, -35}, decimal_fast128_t {int128::uint128_t{UINT64_C(534376054761824), UINT64_C(1987644731805023176)}, -36}, decimal_fast128_t {int128::uint128_t{UINT64_C(92204817966183), UINT64_C(17576450582561384882)}, -37}, diff --git a/include/boost/decimal/detail/cmath/impl/assoc_legendre_lookup.hpp b/include/boost/decimal/detail/cmath/impl/assoc_legendre_lookup.hpp index 17b8e9d8a..4a35f4c47 100644 --- a/include/boost/decimal/detail/cmath/impl/assoc_legendre_lookup.hpp +++ b/include/boost/decimal/detail/cmath/impl/assoc_legendre_lookup.hpp @@ -682,37 +682,37 @@ constexpr auto assoc_legendre_p0_lookup(unsigned n) -> T; template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal32_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d32_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d32_values[n]; } template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal_fast32_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d32_fast_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d32_fast_values[n]; } template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal64_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d64_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d64_values[n]; } template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal_fast64_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d64_fast_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d64_fast_values[n]; } template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal128_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d128_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d128_values[n]; } template <> constexpr auto assoc_legendre_p0_lookup(unsigned n) -> decimal_fast128_t { - return assoc_legendre_detail::assoc_legendre_lookup_table::d128_fast_values[static_cast(n)]; + return assoc_legendre_detail::assoc_legendre_lookup_table::d128_fast_values[n]; } } //namespace detail diff --git a/include/boost/decimal/detail/cmath/impl/atan_impl.hpp b/include/boost/decimal/detail/cmath/impl/atan_impl.hpp index 54e56dedb..2b31b426b 100644 --- a/include/boost/decimal/detail/cmath/impl/atan_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/atan_impl.hpp @@ -165,6 +165,43 @@ constexpr auto atan_series(decimal64_t x) noexcept return (x * top) / bot; } +template <> +constexpr auto atan_series(decimal_fast64_t x) noexcept +{ + // PadeApproximant[ArcTan[x]/x, {x, 0, {12, 12}}] + // FullSimplify[%] + // HornerForm[Numerator[Out[2]]] + // HornerForm[Denominator[Out[2]]] + + const decimal_fast64_t x2 { x * x }; + + const decimal_fast64_t + top + { + decimal_fast64_t { UINT64_C( 58561878375) } + + x2 * (decimal_fast64_t { UINT64_C(163192434405) } + + x2 * (decimal_fast64_t { UINT64_C(169269290190) } + + x2 * (decimal_fast64_t { UINT64_C(80191217106) } + + x2 * (decimal_fast64_t { UINT64_C(16979477515) } + + x2 * (decimal_fast64_t { UINT32_C(1296036105) } + + x2 * decimal_fast64_t { UINT32_C(15728640) }))))) + }; + + const decimal_fast64_t + bot + { + decimal_fast64_t { UINT64_C(58561878375) } + + x2 * (decimal_fast64_t { UINT64_C(182713060530) } + + x2 * (decimal_fast64_t { UINT64_C(218461268025) } + + x2 * (decimal_fast64_t { UINT64_C(124835010300) } + + x2 * (decimal_fast64_t { UINT64_C(34493884425) } + + x2 * (decimal_fast64_t { UINT32_C(4058104050) } + + x2 * decimal_fast64_t { UINT32_C(135270135) }))))) + }; + + return (x * top) / bot; +} + template <> constexpr auto atan_series(decimal128_t x) noexcept { diff --git a/include/boost/decimal/detail/cmath/impl/cos_impl.hpp b/include/boost/decimal/detail/cmath/impl/cos_impl.hpp index e07f3fea9..cc68d1716 100644 --- a/include/boost/decimal/detail/cmath/impl/cos_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/cos_impl.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -31,11 +32,11 @@ struct cos_table_imp {{ decimal32_t {UINT64_C(22805960529562646), -21}, decimal32_t {UINT64_C(39171880037888081), -22}, - decimal32_t {UINT64_C(1392392773950284), -18, true}, + decimal32_t {UINT64_C(1392392773950284), -18, construction_sign::negative}, decimal32_t {UINT64_C(17339629614857501), -22}, decimal32_t {UINT64_C(41666173896377827), -18}, decimal32_t {UINT64_C(77764646000512304), -24}, - decimal32_t {UINT64_C(50000000610949535), -17, true}, + decimal32_t {UINT64_C(50000000610949535), -17, construction_sign::negative}, decimal32_t {UINT64_C(18421494272283811), -26}, decimal32_t {UINT64_C(99999999999908662), -17} }}; @@ -44,11 +45,11 @@ struct cos_table_imp {{ decimal_fast32_t {UINT64_C(22805960529562646), -21}, decimal_fast32_t {UINT64_C(39171880037888081), -22}, - decimal_fast32_t {UINT64_C(1392392773950284), -18, true}, + decimal_fast32_t {UINT64_C(1392392773950284), -18, construction_sign::negative}, decimal_fast32_t {UINT64_C(17339629614857501), -22}, decimal_fast32_t {UINT64_C(41666173896377827), -18}, decimal_fast32_t {UINT64_C(77764646000512304), -24}, - decimal_fast32_t {UINT64_C(50000000610949535), -17, true}, + decimal_fast32_t {UINT64_C(50000000610949535), -17, construction_sign::negative}, decimal_fast32_t {UINT64_C(18421494272283811), -26}, decimal_fast32_t {UINT64_C(99999999999908662), -17} }}; @@ -59,15 +60,15 @@ struct cos_table_imp {{ decimal64_t {UINT64_C(1922641020040661424), -27}, decimal64_t {UINT64_C(4960385936049718134), -28}, - decimal64_t {UINT64_C(2763064713566851512), -25, true}, + decimal64_t {UINT64_C(2763064713566851512), -25, construction_sign::negative}, decimal64_t {UINT64_C(6633276621376137827), -28}, decimal64_t {UINT64_C(2480119161297283187), -23}, decimal64_t {UINT64_C(1600210781837650114), -28}, - decimal64_t {UINT64_C(1388888932852646133), -21, true}, + decimal64_t {UINT64_C(1388888932852646133), -21, construction_sign::negative}, decimal64_t {UINT64_C(8054772849254568869), -30}, decimal64_t {UINT64_C(4166666666572238908), -20}, decimal64_t {UINT64_C(6574164404618517322), -32}, - decimal64_t {UINT64_C(5000000000000023748), -19, true}, + decimal64_t {UINT64_C(5000000000000023748), -19, construction_sign::negative}, decimal64_t {UINT64_C(3367952043014273196), -35}, decimal64_t {UINT64_C(9999999999999999999), -19} }}; @@ -76,15 +77,15 @@ struct cos_table_imp {{ decimal_fast64_t {UINT64_C(1922641020040661424), -27}, decimal_fast64_t {UINT64_C(4960385936049718134), -28}, - decimal_fast64_t {UINT64_C(2763064713566851512), -25, true}, + decimal_fast64_t {UINT64_C(2763064713566851512), -25, construction_sign::negative}, decimal_fast64_t {UINT64_C(6633276621376137827), -28}, decimal_fast64_t {UINT64_C(2480119161297283187), -23}, decimal_fast64_t {UINT64_C(1600210781837650114), -28}, - decimal_fast64_t {UINT64_C(1388888932852646133), -21, true}, + decimal_fast64_t {UINT64_C(1388888932852646133), -21, construction_sign::negative}, decimal_fast64_t {UINT64_C(8054772849254568869), -30}, decimal_fast64_t {UINT64_C(4166666666572238908), -20}, decimal_fast64_t {UINT64_C(6574164404618517322), -32}, - decimal_fast64_t {UINT64_C(5000000000000023748), -19, true}, + decimal_fast64_t {UINT64_C(5000000000000023748), -19, construction_sign::negative}, decimal_fast64_t {UINT64_C(3367952043014273196), -35}, decimal_fast64_t {UINT64_C(9999999999999999999), -19} }}; diff --git a/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp b/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp index 5d168e2fd..b86584311 100644 --- a/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/ellint_impl.hpp @@ -135,7 +135,7 @@ constexpr auto agm(T phi, } } - p2 = static_cast(p2 << 1U); + p2 = p2 << 1U; if(fabs(cn_term) < break_check) { diff --git a/include/boost/decimal/detail/cmath/impl/pow_impl.hpp b/include/boost/decimal/detail/cmath/impl/pow_impl.hpp index 30a1700e9..8a066792a 100644 --- a/include/boost/decimal/detail/cmath/impl/pow_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/pow_impl.hpp @@ -86,7 +86,7 @@ constexpr auto pow_2_impl(int e2) noexcept -> std::enable_if_t(UINT64_C(1) << e2), 0 }; + result = T { UINT64_C(1) << e2, 0 }; } else { @@ -97,11 +97,11 @@ constexpr auto pow_2_impl(int e2) noexcept -> std::enable_if_t(static_cast(~e2) + 1U); + const auto e2_neg = static_cast(~e2) + 1U; if(e2 > -64) { - const T local_p2 { static_cast(UINT64_C(1) << e2_neg), 0 }; + const T local_p2 { UINT64_C(1) << e2_neg, 0 }; result = one / local_p2; } diff --git a/include/boost/decimal/detail/cmath/impl/riemann_zeta_impl.hpp b/include/boost/decimal/detail/cmath/impl/riemann_zeta_impl.hpp index 040ce979c..91599f1fd 100644 --- a/include/boost/decimal/detail/cmath/impl/riemann_zeta_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/riemann_zeta_impl.hpp @@ -354,7 +354,7 @@ constexpr auto riemann_zeta_decimal_order(T x) noexcept : 33 }; - return static_cast(n + order_bias); + return n + order_bias; } template diff --git a/include/boost/decimal/detail/cmath/impl/sin_impl.hpp b/include/boost/decimal/detail/cmath/impl/sin_impl.hpp index 827f83609..d90617753 100644 --- a/include/boost/decimal/detail/cmath/impl/sin_impl.hpp +++ b/include/boost/decimal/detail/cmath/impl/sin_impl.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -31,7 +32,7 @@ struct sin_table_imp { {{ decimal32_t {UINT64_C(76426704684128569), -19}, decimal32_t {UINT64_C(8163484279370784), -19}, - decimal32_t {UINT64_C(16704305092800237), -17, true}, + decimal32_t {UINT64_C(16704305092800237), -17, construction_sign::negative}, decimal32_t {UINT64_C(74622903795259856), -21}, decimal32_t {UINT64_C(9999946918542727), -16}, decimal32_t {UINT64_C(60055992690454536), -24} @@ -41,7 +42,7 @@ struct sin_table_imp { {{ decimal_fast32_t {UINT64_C(76426704684128569), -19}, decimal_fast32_t {UINT64_C(8163484279370784), -19}, - decimal_fast32_t {UINT64_C(16704305092800237), -17, true}, + decimal_fast32_t {UINT64_C(16704305092800237), -17, construction_sign::negative}, decimal_fast32_t {UINT64_C(74622903795259856), -21}, decimal_fast32_t {UINT64_C(9999946918542727), -16}, decimal_fast32_t {UINT64_C(60055992690454536), -24} @@ -51,34 +52,34 @@ struct sin_table_imp { // Estimated max error: 5.2301715421592162270336342660001217e-18 static constexpr std::array d64_coeffs = {{ - decimal64_t {UINT64_C(2306518628003855678), -26, true}, - decimal64_t {UINT64_C(5453073257634027470), -27, true}, + decimal64_t {UINT64_C(2306518628003855678), -26, construction_sign::negative}, + decimal64_t {UINT64_C(5453073257634027470), -27, construction_sign::negative}, decimal64_t {UINT64_C(2762996699568163845), -24}, - decimal64_t {UINT64_C(5023027013521532307), -27, true}, - decimal64_t {UINT64_C(1984096861383546182), -22, true}, - decimal64_t {UINT64_C(1026912296061211491), -27, true}, + decimal64_t {UINT64_C(5023027013521532307), -27, construction_sign::negative}, + decimal64_t {UINT64_C(1984096861383546182), -22, construction_sign::negative}, + decimal64_t {UINT64_C(1026912296061211491), -27, construction_sign::negative}, decimal64_t {UINT64_C(8333333562151404340), -21}, - decimal64_t {UINT64_C(3217043986646625014), -29, true}, - decimal64_t {UINT64_C(1666666666640042905), -19, true}, - decimal64_t {UINT64_C(1135995742940218051), -31, true}, + decimal64_t {UINT64_C(3217043986646625014), -29, construction_sign::negative}, + decimal64_t {UINT64_C(1666666666640042905), -19, construction_sign::negative}, + decimal64_t {UINT64_C(1135995742940218051), -31, construction_sign::negative}, decimal64_t {UINT64_C(1000000000000001896), -18}, - decimal64_t {UINT64_C(5230171542159216227), -36, true} + decimal64_t {UINT64_C(5230171542159216227), -36, construction_sign::negative} }}; static constexpr std::array d64_fast_coeffs = {{ - decimal_fast64_t {UINT64_C(2306518628003855678), -26, true}, - decimal_fast64_t {UINT64_C(5453073257634027470), -27, true}, + decimal_fast64_t {UINT64_C(2306518628003855678), -26, construction_sign::negative}, + decimal_fast64_t {UINT64_C(5453073257634027470), -27, construction_sign::negative}, decimal_fast64_t {UINT64_C(2762996699568163845), -24}, - decimal_fast64_t {UINT64_C(5023027013521532307), -27, true}, - decimal_fast64_t {UINT64_C(1984096861383546182), -22, true}, - decimal_fast64_t {UINT64_C(1026912296061211491), -27, true}, + decimal_fast64_t {UINT64_C(5023027013521532307), -27, construction_sign::negative}, + decimal_fast64_t {UINT64_C(1984096861383546182), -22, construction_sign::negative}, + decimal_fast64_t {UINT64_C(1026912296061211491), -27, construction_sign::negative}, decimal_fast64_t {UINT64_C(8333333562151404340), -21}, - decimal_fast64_t {UINT64_C(3217043986646625014), -29, true}, - decimal_fast64_t {UINT64_C(1666666666640042905), -19, true}, - decimal_fast64_t {UINT64_C(1135995742940218051), -31, true}, + decimal_fast64_t {UINT64_C(3217043986646625014), -29, construction_sign::negative}, + decimal_fast64_t {UINT64_C(1666666666640042905), -19, construction_sign::negative}, + decimal_fast64_t {UINT64_C(1135995742940218051), -31, construction_sign::negative}, decimal_fast64_t {UINT64_C(1000000000000001896), -18}, - decimal_fast64_t {UINT64_C(5230171542159216227), -36, true} + decimal_fast64_t {UINT64_C(5230171542159216227), -36, construction_sign::negative} }}; }; @@ -154,11 +155,11 @@ constexpr auto sin_series_expansion(decimal128_t x) noexcept // HornerForm[Denominator[Out[2]]] constexpr decimal128_t c0 { boost::int128::uint128_t { UINT64_C(72470724512963), UINT64_C(12010094287581601792) }, -1 }; - constexpr decimal128_t c1 { boost::int128::uint128_t { UINT64_C(111100426260665), UINT64_C(12001293056709775360) }, -2, true }; + constexpr decimal128_t c1 { boost::int128::uint128_t { UINT64_C(111100426260665), UINT64_C(12001293056709775360) }, -2, construction_sign::negative }; constexpr decimal128_t c2 { boost::int128::uint128_t { UINT64_C(448976101608303), UINT64_C(8651619847551332352) }, -4 }; - constexpr decimal128_t c3 { boost::int128::uint128_t { UINT64_C(73569920121966), UINT64_C(7922026052315602944) }, -5, true }; + constexpr decimal128_t c3 { boost::int128::uint128_t { UINT64_C(73569920121966), UINT64_C(7922026052315602944) }, -5, construction_sign::negative }; constexpr decimal128_t c4 { boost::int128::uint128_t { UINT64_C(56791565109495), UINT64_C(18025512837605806080) }, -7 }; - constexpr decimal128_t c5 { boost::int128::uint128_t { UINT64_C(208944907042123), UINT64_C(1905626912845279232) }, -10, true }; + constexpr decimal128_t c5 { boost::int128::uint128_t { UINT64_C(208944907042123), UINT64_C(1905626912845279232) }, -10, construction_sign::negative }; constexpr decimal128_t c6 { boost::int128::uint128_t { UINT64_C(301324799882787), UINT64_C(8861120840873566208) }, -13 }; constexpr decimal128_t d1 { boost::int128::uint128_t { UINT64_C(96841145942737), UINT64_C(12517245955660587008) }, -3 }; @@ -191,11 +192,11 @@ constexpr auto sin_series_expansion(decimal_fast128_t x) noex // HornerForm[Denominator[Out[2]]] constexpr decimal_fast128_t c0 { boost::int128::uint128_t { UINT64_C(72470724512963), UINT64_C(12010094287581601792) }, -1 }; - constexpr decimal_fast128_t c1 { boost::int128::uint128_t { UINT64_C(111100426260665), UINT64_C(12001293056709775360) }, -2, true }; + constexpr decimal_fast128_t c1 { boost::int128::uint128_t { UINT64_C(111100426260665), UINT64_C(12001293056709775360) }, -2, construction_sign::negative }; constexpr decimal_fast128_t c2 { boost::int128::uint128_t { UINT64_C(448976101608303), UINT64_C(8651619847551332352) }, -4 }; - constexpr decimal_fast128_t c3 { boost::int128::uint128_t { UINT64_C(73569920121966), UINT64_C(7922026052315602944) }, -5, true }; + constexpr decimal_fast128_t c3 { boost::int128::uint128_t { UINT64_C(73569920121966), UINT64_C(7922026052315602944) }, -5, construction_sign::negative }; constexpr decimal_fast128_t c4 { boost::int128::uint128_t { UINT64_C(56791565109495), UINT64_C(18025512837605806080) }, -7 }; - constexpr decimal_fast128_t c5 { boost::int128::uint128_t { UINT64_C(208944907042123), UINT64_C(1905626912845279232) }, -10, true }; + constexpr decimal_fast128_t c5 { boost::int128::uint128_t { UINT64_C(208944907042123), UINT64_C(1905626912845279232) }, -10, construction_sign::negative }; constexpr decimal_fast128_t c6 { boost::int128::uint128_t { UINT64_C(301324799882787), UINT64_C(8861120840873566208) }, -13 }; constexpr decimal_fast128_t d1 { boost::int128::uint128_t { UINT64_C(96841145942737), UINT64_C(12517245955660587008) }, -3 }; diff --git a/include/boost/decimal/detail/cmath/laguerre.hpp b/include/boost/decimal/detail/cmath/laguerre.hpp index 9186410a3..6ddac23e9 100644 --- a/include/boost/decimal/detail/cmath/laguerre.hpp +++ b/include/boost/decimal/detail/cmath/laguerre.hpp @@ -61,19 +61,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto laguerre(const unsigned n, const T x) BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::laguerre_impl(n, static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/ldexp.hpp b/include/boost/decimal/detail/cmath/ldexp.hpp index 79d94e1c5..d1dccbacf 100644 --- a/include/boost/decimal/detail/cmath/ldexp.hpp +++ b/include/boost/decimal/detail/cmath/ldexp.hpp @@ -64,19 +64,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto ldexp(const T v, const int e2) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::ldexp_impl(static_cast(v), e2)); } diff --git a/include/boost/decimal/detail/cmath/legendre.hpp b/include/boost/decimal/detail/cmath/legendre.hpp index f7417014a..ddc8a2d81 100644 --- a/include/boost/decimal/detail/cmath/legendre.hpp +++ b/include/boost/decimal/detail/cmath/legendre.hpp @@ -78,19 +78,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto legendre(const unsigned n, const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::legendre_impl(n, static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/lgamma.hpp b/include/boost/decimal/detail/cmath/lgamma.hpp index f4e845769..aaa8ce945 100644 --- a/include/boost/decimal/detail/cmath/lgamma.hpp +++ b/include/boost/decimal/detail/cmath/lgamma.hpp @@ -126,19 +126,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto lgamma(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::lgamma_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/log.hpp b/include/boost/decimal/detail/cmath/log.hpp index 39a246177..6dea61f01 100644 --- a/include/boost/decimal/detail/cmath/log.hpp +++ b/include/boost/decimal/detail/cmath/log.hpp @@ -80,19 +80,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto log(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::log_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/log10.hpp b/include/boost/decimal/detail/cmath/log10.hpp index 3e2f86bcd..49f3a95f4 100644 --- a/include/boost/decimal/detail/cmath/log10.hpp +++ b/include/boost/decimal/detail/cmath/log10.hpp @@ -63,7 +63,7 @@ constexpr auto log10_impl(const T x) noexcept remove_trailing_zeros(gn) }; - const bool is_pure { static_cast(zeros_removal.trimmed_number) == 1U }; + const bool is_pure { zeros_removal.trimmed_number == 1U }; if(is_pure) { @@ -131,19 +131,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto log10(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::log10_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/log1p.hpp b/include/boost/decimal/detail/cmath/log1p.hpp index 15c8131fd..d23de14f1 100644 --- a/include/boost/decimal/detail/cmath/log1p.hpp +++ b/include/boost/decimal/detail/cmath/log1p.hpp @@ -78,19 +78,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto log1p(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::log1p_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/log2.hpp b/include/boost/decimal/detail/cmath/log2.hpp index 94e8bd861..c4ce12981 100644 --- a/include/boost/decimal/detail/cmath/log2.hpp +++ b/include/boost/decimal/detail/cmath/log2.hpp @@ -36,19 +36,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto log2(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::log2_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/nan.hpp b/include/boost/decimal/detail/cmath/nan.hpp index 05629cc1d..953be4e2a 100644 --- a/include/boost/decimal/detail/cmath/nan.hpp +++ b/include/boost/decimal/detail/cmath/nan.hpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include #ifndef BOOST_DECIMAL_BUILD_MODULE @@ -22,36 +25,208 @@ namespace decimal { namespace detail { -template -constexpr auto nan_impl(const char* arg) noexcept -> TargetDecimalType +template +constexpr auto nan_impl(const char* arg) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType) { - char* endptr {}; - const auto val {strtod_impl(arg, &endptr)}; - return val & std::numeric_limits::quiet_NaN(); -} + using sig_type = typename TargetDecimalType::significand_type; -} //namespace detail + constexpr TargetDecimalType nan_type {is_snan ? std::numeric_limits::signaling_NaN() : + std::numeric_limits::quiet_NaN()}; -BOOST_DECIMAL_EXPORT constexpr auto nand32(const char* arg) noexcept -> decimal32_t + sig_type payload_value {}; + const auto r {from_chars_integer_impl(arg, arg + detail::strlen(arg), payload_value, 10)}; + + if (!r) + { + return nan_type; + } + else + { + return write_payload(payload_value); + } +} + +template +constexpr auto nan_impl(const char* arg) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_ieee_type_v, TargetDecimalType) { - return detail::nan_impl(arg); + using sig_type = typename TargetDecimalType::significand_type; + + constexpr TargetDecimalType nan_type {is_snan ? std::numeric_limits::signaling_NaN() : + std::numeric_limits::quiet_NaN()}; + + sig_type payload_value {}; + const auto r {from_chars_integer_impl(arg, arg + detail::strlen(arg), payload_value, 10)}; + + if (!r) + { + return nan_type; + } + else + { + return write_payload(payload_value); + } } +} //namespace detail + BOOST_DECIMAL_EXPORT template constexpr auto nan(const char* arg) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - return detail::nan_impl(arg); + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto nand32(const char* arg) noexcept -> decimal32_t +{ + return detail::nan_impl(arg); } BOOST_DECIMAL_EXPORT constexpr auto nand64(const char* arg) noexcept -> decimal64_t { - return detail::nan_impl(arg); + return detail::nan_impl(arg); } BOOST_DECIMAL_EXPORT constexpr auto nand128(const char* arg) noexcept -> decimal128_t { - return detail::nan_impl(arg); + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto nand32f(const char* arg) noexcept -> decimal_fast32_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto nand64f(const char* arg) noexcept -> decimal_fast64_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto nand128f(const char* arg) noexcept -> decimal_fast128_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT template +constexpr auto snan(const char* arg) noexcept + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand32(const char* arg) noexcept -> decimal32_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand64(const char* arg) noexcept -> decimal64_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand128(const char* arg) noexcept -> decimal128_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand32f(const char* arg) noexcept -> decimal_fast32_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand64f(const char* arg) noexcept -> decimal_fast64_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT constexpr auto snand128f(const char* arg) noexcept -> decimal_fast128_t +{ + return detail::nan_impl(arg); +} + +BOOST_DECIMAL_EXPORT template +constexpr auto read_payload(const T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_ieee_type_v, T, typename T::significand_type) +{ + const auto positive_value {signbit(value) ? -value : value}; + + if (!isnan(value)) + { + return 0U; + } + else if (issignaling(value)) + { + return positive_value.bits_ ^ std::numeric_limits::signaling_NaN().bits_; + } + else + { + return positive_value.bits_ ^ std::numeric_limits::quiet_NaN().bits_; + } +} + +namespace detail { + +template +constexpr auto get_qnan_mask(); + +template <> +constexpr auto get_qnan_mask() +{ + return d32_fast_qnan; +} + +template <> +constexpr auto get_qnan_mask() +{ + return d64_fast_qnan; +} + +template <> +constexpr auto get_qnan_mask() +{ + return d128_fast_qnan; +} + +template +constexpr auto get_snan_mask(); + +template <> +constexpr auto get_snan_mask() +{ + return d32_fast_snan; +} + +template <> +constexpr auto get_snan_mask() +{ + return d64_fast_snan; +} + +template <> +constexpr auto get_snan_mask() +{ + return d128_fast_snan; +} + +} // namespace detail + +BOOST_DECIMAL_EXPORT template +constexpr auto read_payload(const T value) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_fast_type_v, T, typename T::significand_type) +{ + if (!isnan(value)) + { + return 0U; + } + else if (issignaling(value)) + { + return value.significand_ ^ detail::get_snan_mask(); + } + else + { + return value.significand_ ^ detail::get_qnan_mask(); + } } } //namespace decimal diff --git a/include/boost/decimal/detail/cmath/next.hpp b/include/boost/decimal/detail/cmath/next.hpp index 022ca07b3..fbd15c8bd 100644 --- a/include/boost/decimal/detail/cmath/next.hpp +++ b/include/boost/decimal/detail/cmath/next.hpp @@ -34,9 +34,7 @@ constexpr auto nextafter_impl(const DecimalType val, const bool direction) noexc { constexpr DecimalType zero {0}; - // Val < direction = + - // Val > direction = - - const auto abs_val {abs(val)}; + const bool is_neg {val < 0}; if (val == zero) { @@ -44,32 +42,61 @@ constexpr auto nextafter_impl(const DecimalType val, const bool direction) noexc -std::numeric_limits::denorm_min()}; return min_val; } - else if (abs_val > zero && abs_val < std::numeric_limits::epsilon()) - { - auto exp {val.biased_exponent()}; - auto significand {val.full_significand()}; - direction ? ++significand : --significand; - return {significand, exp, val.isneg()}; - } + int exp {}; + auto sig {frexp10(val, &exp)}; + const auto removed_zeros(remove_trailing_zeros(sig)); - const auto val_eps {direction ? val + std::numeric_limits::epsilon() : - val - std::numeric_limits::epsilon()}; + // Our two boundaries + const bool is_pow_10 {removed_zeros.trimmed_number == 1U}; + const bool is_max_sig {sig == detail::max_significand_v}; - // If adding epsilon does nothing, then we need to manipulate the representation - if (val == val_eps) + if (!isnormal(val)) { - int exp {} ; - auto significand {frexp10(val, &exp)}; - - direction ? ++significand : --significand; + // Denorms need separate handling + sig = removed_zeros.trimmed_number; + exp += static_cast(removed_zeros.number_of_removed_zeros); + + if (removed_zeros.number_of_removed_zeros > 0) + { + // We need to shift an add + // 1 -> 11 instead of 2 since 11e-101 < 2e-100 starting at 1e-100 + sig *= 10U; + ++sig; + --exp; + } + else + { + ++sig; + } + + return DecimalType{sig, exp, is_neg}; + } - return DecimalType{significand, exp}; + if (direction) + { + // Val < direction = + + ++sig; + if (is_max_sig) + { + sig /= 10u; + ++exp; + } } else { - return val_eps; + // Val > direction = - + --sig; + if (is_pow_10) + { + // 1000 becomes 999 but needs to be 9999 + sig *= 10u; + sig += 9u; + --exp; + } } + + return DecimalType{sig, exp, is_neg}; } } // namespace detail diff --git a/include/boost/decimal/detail/cmath/pow.hpp b/include/boost/decimal/detail/cmath/pow.hpp index 13fd14874..0dc3f8f98 100644 --- a/include/boost/decimal/detail/cmath/pow.hpp +++ b/include/boost/decimal/detail/cmath/pow.hpp @@ -114,7 +114,7 @@ constexpr auto pow(const T b, const IntegralType p) noexcept // Here, a pure power-of-10 argument (b) gets a pure integral result. const int log10_val { exp10val + static_cast(zeros_removal.number_of_removed_zeros) }; - result = T { 1, static_cast(log10_val * static_cast(p)) }; + result = T { 1, log10_val * static_cast(p) }; } else { diff --git a/include/boost/decimal/detail/cmath/rescale.hpp b/include/boost/decimal/detail/cmath/rescale.hpp index 292bce565..6cdbfaeaf 100644 --- a/include/boost/decimal/detail/cmath/rescale.hpp +++ b/include/boost/decimal/detail/cmath/rescale.hpp @@ -58,20 +58,12 @@ constexpr auto rescale(const T val, const int precision = 0) noexcept if (sig_dig > precision) { - exp += detail::fenv_round(sig, isneg); + exp += detail::fenv_round(sig, isneg); } return {sig, exp, isneg}; } -BOOST_DECIMAL_EXPORT template -[[deprecated("Renamed to rescale to match existing literature")]] -constexpr auto trunc_to(T val, int precision = 0) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) -{ - return rescale(val, precision); -} - } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/cmath/riemann_zeta.hpp b/include/boost/decimal/detail/cmath/riemann_zeta.hpp index 490f63b8c..583de318d 100644 --- a/include/boost/decimal/detail/cmath/riemann_zeta.hpp +++ b/include/boost/decimal/detail/cmath/riemann_zeta.hpp @@ -205,19 +205,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto riemann_zeta(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::riemann_zeta_impl(static_cast(x))); } @@ -226,19 +214,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto riemann_zeta(const IntegralType n) noexcept BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_decimal_floating_point_v, T, detail::is_integral_v, IntegralType, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; // TODO(ckormanyos) Consider making an integral-argument specialization. // Some exact values are known. Some simplifications for small-n are possible. diff --git a/include/boost/decimal/detail/cmath/rint.hpp b/include/boost/decimal/detail/cmath/rint.hpp index c337a5158..1e01a4fd0 100644 --- a/include/boost/decimal/detail/cmath/rint.hpp +++ b/include/boost/decimal/detail/cmath/rint.hpp @@ -28,17 +28,15 @@ namespace decimal { namespace detail { -template -constexpr auto rint_impl(T1& sig, T2 exp, const bool sign) +template +constexpr auto rint_impl(T1& sig, T2 exp, const bool is_neg) { - using RoundType = std::conditional_t::value, decimal32_t, - std::conditional_t::value, decimal64_t, decimal128_t>>; - const T2 abs_exp { (exp < T2(0)) ? -exp : exp }; - sig /= detail::pow10(static_cast(abs_exp - 1)); + const auto res {detail::impl::divmod(sig, detail::pow10(static_cast(abs_exp - 1)))}; + sig = res.quotient; - detail::fenv_round(sig, sign); + detail::fenv_round(sig, is_neg, res.remainder != 0U); } // MSVC 14.1 warns of unary minus being applied to unsigned type from numeric_limits::min @@ -94,7 +92,7 @@ constexpr auto lrint_impl(const T num) noexcept -> Int return 0; } - detail::rint_impl(sig, expptr, is_neg); + detail::rint_impl(sig, expptr, is_neg); auto res {static_cast(sig)}; if (is_neg) @@ -144,7 +142,7 @@ constexpr auto rint(const T num) noexcept return is_neg ? -zero : zero; } - detail::rint_impl(sig, expptr, is_neg); + detail::rint_impl(sig, expptr, is_neg); return {sig, 0, is_neg}; } diff --git a/include/boost/decimal/detail/cmath/round.hpp b/include/boost/decimal/detail/cmath/round.hpp index 0ed3fc16f..bbb478306 100644 --- a/include/boost/decimal/detail/cmath/round.hpp +++ b/include/boost/decimal/detail/cmath/round.hpp @@ -43,11 +43,11 @@ constexpr auto round(const T num) noexcept T iptr {}; const auto x {modf(num, &iptr)}; - if (x >= half && iptr > 0) + if (x >= half) { ++iptr; } - else if (abs(x) >= half && iptr < 0) + else if (x <= -half) { --iptr; } diff --git a/include/boost/decimal/detail/cmath/sin.hpp b/include/boost/decimal/detail/cmath/sin.hpp index 586c10320..035447241 100644 --- a/include/boost/decimal/detail/cmath/sin.hpp +++ b/include/boost/decimal/detail/cmath/sin.hpp @@ -49,7 +49,7 @@ constexpr auto sin_impl(const T x) noexcept } else { - if(x > static_cast(INT8_C(0))) + if(x > 0) { // Perform argument reduction and subsequent scaling of the result. @@ -65,7 +65,7 @@ constexpr auto sin_impl(const T x) noexcept const T two_x = x * 2; const auto k = static_cast(two_x / numbers::pi_v); - const auto n = static_cast(k % static_cast(UINT8_C(4))); + const auto n = k % static_cast(4); const T two_r { two_x - (numbers::pi_v * k) }; @@ -149,19 +149,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto sin(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::sin_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/sinh.hpp b/include/boost/decimal/detail/cmath/sinh.hpp index 43d3783e2..7b6fd6569 100644 --- a/include/boost/decimal/detail/cmath/sinh.hpp +++ b/include/boost/decimal/detail/cmath/sinh.hpp @@ -88,19 +88,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto sinh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::sinh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/sqrt.hpp b/include/boost/decimal/detail/cmath/sqrt.hpp index 0908b7278..1135fd9ac 100644 --- a/include/boost/decimal/detail/cmath/sqrt.hpp +++ b/include/boost/decimal/detail/cmath/sqrt.hpp @@ -61,7 +61,7 @@ constexpr auto sqrt_impl(const T x) noexcept remove_trailing_zeros(gn) }; - const bool is_pure { static_cast(zeros_removal.trimmed_number) == 1U }; + const bool is_pure { zeros_removal.trimmed_number == 1U }; constexpr T one { 1 }; @@ -123,14 +123,14 @@ constexpr auto sqrt_impl(const T x) noexcept (one + gx * ((one + gx) * 20)) / (numbers::sqrt2_v * ((gx * 4) * (five + gx) + five)); - // Perform 2, 3 or 4 Newton-Raphson iterations depending on precision. + // Perform 3, 4 or 5 Newton-Raphson iterations depending on precision. // Note from above, we start with slightly more than 2 decimal digits // of accuracy. constexpr int iter_loops { - std::numeric_limits::digits10 < 10 ? 2 - : std::numeric_limits::digits10 < 20 ? 3 : 4 + std::numeric_limits::digits10 < 10 ? 3 + : std::numeric_limits::digits10 < 20 ? 4 : 5 }; for (int idx = 0; idx < iter_loops; ++idx) @@ -167,19 +167,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto sqrt(const T val) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::sqrt_impl(static_cast(val))); } diff --git a/include/boost/decimal/detail/cmath/tan.hpp b/include/boost/decimal/detail/cmath/tan.hpp index 2d63cc9cd..bcb32d657 100644 --- a/include/boost/decimal/detail/cmath/tan.hpp +++ b/include/boost/decimal/detail/cmath/tan.hpp @@ -70,7 +70,7 @@ constexpr auto tan_impl(const T x) noexcept const T two_x = x * 2; const auto k = static_cast(two_x / numbers::pi_v); - const auto n = static_cast(k % static_cast(UINT8_C(4))); + const auto n = k % static_cast(UINT8_C(4)); const T two_r { two_x - (numbers::pi_v * k) }; @@ -134,19 +134,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto tan(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::tan_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/tanh.hpp b/include/boost/decimal/detail/cmath/tanh.hpp index 8d6fbb10f..b8d0c2b4c 100644 --- a/include/boost/decimal/detail/cmath/tanh.hpp +++ b/include/boost/decimal/detail/cmath/tanh.hpp @@ -95,19 +95,7 @@ BOOST_DECIMAL_EXPORT template constexpr auto tanh(const T x) noexcept BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::tanh_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/cmath/tgamma.hpp b/include/boost/decimal/detail/cmath/tgamma.hpp index 5daa832a5..fe3222c5b 100644 --- a/include/boost/decimal/detail/cmath/tgamma.hpp +++ b/include/boost/decimal/detail/cmath/tgamma.hpp @@ -129,22 +129,10 @@ constexpr auto tgamma_impl(const T x) noexcept } // namespace detail BOOST_DECIMAL_EXPORT template -constexpr auto tgamma(const T x) noexcept - BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) +constexpr auto tgamma(const T x) noexcept // LCOV_EXCL_LINE + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) // LCOV_EXCL_LINE { - #if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 - - using evaluation_type = T; - - #elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 - - using evaluation_type = detail::promote_args_t; - - #else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2 - - using evaluation_type = detail::promote_args_t; - - #endif + using evaluation_type = detail::evaluation_type_t; return static_cast(detail::tgamma_impl(static_cast(x))); } diff --git a/include/boost/decimal/detail/comparison.hpp b/include/boost/decimal/detail/comparison.hpp index 196f24646..4f5aa4d0d 100644 --- a/include/boost/decimal/detail/comparison.hpp +++ b/include/boost/decimal/detail/comparison.hpp @@ -182,6 +182,12 @@ constexpr auto equal_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, BOOST_DECIMAL_ASSERT(lhs_sig >= 0U); BOOST_DECIMAL_ASSERT(rhs_sig >= 0U); + if (lhs_sig == 0U && rhs_sig == 0U) + { + // +0 == -0 + return true; + } + // We con compare signs right away if (lhs_sign != rhs_sign) { @@ -192,10 +198,6 @@ constexpr auto equal_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, // Check the value of delta exp to avoid to large a value for pow10 // Also if only one of the significands is 0 then we know the values have to be mismatched - if (lhs_sig == 0U && rhs_sig == 0U) - { - return true; - } if (delta_exp > detail::precision_v || delta_exp < -detail::precision_v) { return false; @@ -270,14 +272,20 @@ constexpr auto equal_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, template -constexpr auto equal_parts_impl(T1 lhs_sig, U1 lhs_exp, bool lhs_sign, - T2 rhs_sig, U2 rhs_exp, bool rhs_sign) noexcept -> std::enable_if_t, bool> +constexpr auto equal_parts_impl(T1 lhs_sig, U1 lhs_exp, const bool lhs_sign, + T2 rhs_sig, U2 rhs_exp, const bool rhs_sign) noexcept -> std::enable_if_t, bool> { using comp_type = std::conditional_t<(std::numeric_limits::digits10 > std::numeric_limits::digits10), T1, T2>; BOOST_DECIMAL_ASSERT(lhs_sig >= 0U); BOOST_DECIMAL_ASSERT(rhs_sig >= 0U); + if (lhs_sig == 0U && rhs_sig == 0U) + { + // +0 == -0 + return true; + } + auto new_lhs_sig {static_cast(lhs_sig)}; auto new_rhs_sig {static_cast(rhs_sig)}; diff --git a/include/boost/decimal/detail/components.hpp b/include/boost/decimal/detail/components.hpp index 46c9eb093..f7d2eb7e2 100644 --- a/include/boost/decimal/detail/components.hpp +++ b/include/boost/decimal/detail/components.hpp @@ -18,6 +18,18 @@ namespace detail { namespace impl { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) // Structure was padded due to alignment specifier +#endif + + +// Internal use only, and changes based on the types +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + template struct decimal_components { @@ -47,6 +59,12 @@ struct decimal_components { return sign; } + + template + explicit constexpr operator decimal_components() const + { + return decimal_components{static_cast(sig), static_cast(exp), sign}; + } }; } // namespace impl @@ -63,6 +81,14 @@ using decimal128_t_components = impl::decimal_components; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace detail } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/concepts.hpp b/include/boost/decimal/detail/concepts.hpp index f78c1c45f..50f5850d6 100644 --- a/include/boost/decimal/detail/concepts.hpp +++ b/include/boost/decimal/detail/concepts.hpp @@ -267,11 +267,11 @@ concept fast_decimal_floating_point_type = boost::decimal::detail::is_fast_type_ #define BOOST_DECIMAL_OUTPUT_ITER(I, T) boost::decimal::detail::concepts::output_iterator #define BOOST_DECIMAL_REQUIRES_ITER(X) requires X -#define BOOST_DECIMAL_REQUIRES(X, T) -> T requires X -#define BOOST_DECIMAL_REQUIRES_TWO(X1, T1, X2, T2) -> detail::promote_args_t requires X1 && X2 -#define BOOST_DECIMAL_REQUIRES_TWO_RETURN(X1, T1, X2, T2, ReturnType) -> ReturnType requires X1 && X2 -#define BOOST_DECIMAL_REQUIRES_THREE(X1, T1, X2, T2, X3, T3) -> detail::promote_args_t requires X1 && X2 && X3 -#define BOOST_DECIMAL_REQUIRES_RETURN(X, T, ReturnType) -> ReturnType requires X +#define BOOST_DECIMAL_REQUIRES(X, T) -> T requires (X) +#define BOOST_DECIMAL_REQUIRES_TWO(X1, T1, X2, T2) -> detail::promote_args_t requires (X1 && X2) +#define BOOST_DECIMAL_REQUIRES_TWO_RETURN(X1, T1, X2, T2, ReturnType) -> ReturnType requires (X1 && X2) +#define BOOST_DECIMAL_REQUIRES_THREE(X1, T1, X2, T2, X3, T3) -> detail::promote_args_t requires (X1 && X2 && X3) +#define BOOST_DECIMAL_REQUIRES_RETURN(X, T, ReturnType) -> ReturnType requires (X) #ifdef BOOST_DECIMAL_EXEC_COMPATIBLE #include diff --git a/include/boost/decimal/detail/config.hpp b/include/boost/decimal/detail/config.hpp index 850960098..2eb885cdb 100644 --- a/include/boost/decimal/detail/config.hpp +++ b/include/boost/decimal/detail/config.hpp @@ -32,7 +32,9 @@ #if __has_include() # if __cplusplus >= 201806L || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201806L)) -# include +# ifndef BOOST_DECIMAL_BUILD_MODULE +# include +# endif # define BOOST_DECIMAL_HAS_STDBIT # if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L) # define BOOST_DECIMAL_HAS_CONSTEXPR_BITCAST @@ -88,15 +90,17 @@ # ifndef BOOST_DECIMAL_BUILD_MODULE # include # endif -# if defined(_WIN64) +# if defined(_M_AMD64) # define BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS # else # define BOOST_DECIMAL_HAS_MSVC_32BIT_INTRINSICS # endif # if defined(__ADX__) && defined(BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS) # define BOOST_DECIMAL_ADD_CARRY _addcarryx_u64 +# define BOOST_DECIMAL_SUB_BORROW _subborrow_u64 # elif defined(BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS) # define BOOST_DECIMAL_ADD_CARRY _addcarry_u64 +# define BOOST_DECIMAL_SUB_BORROW _subborrow_u64 # endif #elif defined(__x86_64__) # ifndef BOOST_DECIMAL_BUILD_MODULE @@ -105,14 +109,21 @@ # define BOOST_DECIMAL_HAS_X64_INTRINSICS # ifdef __ADX__ # define BOOST_DECIMAL_ADD_CARRY _addcarryx_u64 +# define BOOST_DECIMAL_SUB_BORROW _subborrow_u64 # else # define BOOST_DECIMAL_ADD_CARRY _addcarry_u64 +# define BOOST_DECIMAL_SUB_BORROW _subborrow_u64 # endif #elif defined(__ARM_NEON__) # ifndef BOOST_DECIMAL_BUILD_MODULE # include # endif # define BOOST_DECIMAL_HAS_ARM_INTRINSICS +#elif defined(__i386__) +# ifndef BOOST_DECIMAL_BUILD_MODULE +# include +# endif +# define BOOST_DECIMAL_HAS_x86_INTRINSICS #else # define BOOST_DECIMAL_HAS_NO_INTRINSICS #endif @@ -228,6 +239,18 @@ typedef unsigned __int128 builtin_uint128_t; # endif #endif +// Clang < 12 will detect availability, but has issues +#ifdef BOOST_DECIMAL_HAS_BUILTIN_IS_CONSTANT_EVALUATED +# if defined(__clang__) && __clang_major__ < 12 +# ifdef BOOST_DECIMAL_HAS_BUILTIN_IS_CONSTANT_EVALUATED +# undef BOOST_DECIMAL_HAS_BUILTIN_IS_CONSTANT_EVALUATED +# endif +# ifdef BOOST_DECIMAL_HAS_IS_CONSTANT_EVALUATED +# undef BOOST_DECIMAL_HAS_IS_CONSTANT_EVALUATED +# endif +# endif +#endif + // // MSVC also supports __builtin_is_constant_evaluated if it's recent enough: // @@ -258,26 +281,6 @@ typedef unsigned __int128 builtin_uint128_t; # define BOOST_DECIMAL_NO_CONSTEVAL_DETECTION #endif -#if defined(__clang__) -# if defined __has_feature -# if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) -# define BOOST_DECIMAL_REDUCE_TEST_DEPTH -# endif -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_THREAD__) || defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) -# define BOOST_DECIMAL_REDUCE_TEST_DEPTH -# endif -#elif defined(_MSC_VER) -# if defined(_DEBUG) || defined(__SANITIZE_ADDRESS__) -# define BOOST_DECIMAL_REDUCE_TEST_DEPTH -# endif -#endif - -#if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && ((defined(UBSAN) && (UBSAN == 1))) -# define BOOST_DECIMAL_REDUCE_TEST_DEPTH -#endif - #if defined(__clang__) && __clang_major__ < 19 # define BOOST_DECIMAL_CLANG_STATIC static #else @@ -291,11 +294,11 @@ typedef unsigned __int128 builtin_uint128_t; #endif #if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L -# define BOOST_DECIMAL_CONSTEXPR_VARIABLE inline constexpr -# define BOOST_DECIMAL_CONSTEXPR_VARIABLE_SPECIALIZATION BOOST_DECIMAL_CONSTEXPR_VARIABLE +# define BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE inline constexpr +# define BOOST_DECIMAL_CONSTEXPR_VARIABLE_SPECIALIZATION BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE # define BOOST_DECIMAL_INLINE_VARIABLE inline #else -# define BOOST_DECIMAL_CONSTEXPR_VARIABLE static constexpr +# define BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE static constexpr # define BOOST_DECIMAL_CONSTEXPR_VARIABLE_SPECIALIZATION BOOST_DECIMAL_CLANG_STATIC constexpr # define BOOST_DECIMAL_INLINE_VARIABLE static #endif @@ -398,4 +401,18 @@ static_assert(std::is_same::value, "__float128 should b #endif +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L +# define BOOST_DECIMAL_HAS_CHAR8_T +#endif + +#if defined(__has_cpp_attribute) && __has_cpp_attribute(fallthrough) >= 201603L +# define BOOST_DECIMAL_FALLTHROUGH [[fallthrough]]; +#elif defined(__clang__) +# define BOOST_DECIMAL_FALLTHROUGH [[clang::fallthrough]]; +#elif defined(__GNUC__) +# define BOOST_DECIMAL_FALLTHROUGH __attribute__ ((fallthrough)); +#else +# define BOOST_DECIMAL_FALLTHROUGH +#endif + #endif // BOOST_DECIMAL_DETAIL_CONFIG_HPP diff --git a/include/boost/decimal/detail/construction_sign.hpp b/include/boost/decimal/detail/construction_sign.hpp new file mode 100644 index 000000000..3216931bd --- /dev/null +++ b/include/boost/decimal/detail/construction_sign.hpp @@ -0,0 +1,42 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_CONSTRUCTION_SIGN_HPP +#define BOOST_DECIMAL_DETAIL_CONSTRUCTION_SIGN_HPP + +namespace boost { +namespace decimal { + +enum class construction_sign : bool +{ + positive = false, + negative = true +}; + +namespace detail { + +class construction_sign_wrapper +{ +private: + + construction_sign value_; + +public: + + constexpr construction_sign_wrapper() noexcept = delete; + + constexpr construction_sign_wrapper(const construction_sign value) noexcept : value_{value} {} + + constexpr construction_sign_wrapper(const bool value) noexcept + : value_{ value ? construction_sign::negative : construction_sign::positive } {} + + constexpr operator bool() const noexcept { return static_cast(value_); } +}; + +} // namespace detail + +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_CONSTRUCTION_SIGN_HPP diff --git a/include/boost/decimal/detail/countl.hpp b/include/boost/decimal/detail/countl.hpp index 9b4f0a0e2..fe9fd5073 100644 --- a/include/boost/decimal/detail/countl.hpp +++ b/include/boost/decimal/detail/countl.hpp @@ -9,6 +9,7 @@ #include #ifndef BOOST_DECIMAL_BUILD_MODULE +#include "int128.hpp" #include #include #endif @@ -51,7 +52,7 @@ constexpr int countl_impl(unsigned long long x) noexcept #else -BOOST_DECIMAL_CONSTEXPR_VARIABLE int index64[64] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int index64[64] = { 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, @@ -92,12 +93,18 @@ constexpr int countl_impl(T x) noexcept template constexpr int countl_zero(T x) noexcept { - static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "Can only count with unsigned integers"); return impl::countl_impl(x); } +template <> +constexpr int countl_zero(const int128::uint128_t x) noexcept +{ + return int128::countl_zero(x); +} + } //namespace detail } //namespace decimal } //namespace boost diff --git a/include/boost/decimal/detail/div_impl.hpp b/include/boost/decimal/detail/div_impl.hpp index 688d936f1..245d45278 100644 --- a/include/boost/decimal/detail/div_impl.hpp +++ b/include/boost/decimal/detail/div_impl.hpp @@ -21,22 +21,25 @@ namespace detail { template BOOST_DECIMAL_FORCE_INLINE constexpr auto generic_div_impl(const T& lhs, const T& rhs) noexcept -> DecimalType { - bool sign {lhs.sign != rhs.sign}; - // If rhs is greater than we need to offset the significands to get the correct values // e.g. 4/8 is 0 but 40/8 yields 5 in integer maths - constexpr auto ten_pow_precision {detail::pow10(static_cast(detail::precision))}; - const auto big_sig_lhs {static_cast(lhs.sig) * ten_pow_precision}; + // + // By expanding the offset to all the way to the value of numeric_limits::digits10 + // we can recover more of what would become the fraction to achieve better rounding + + using div_type = std::uint64_t; - auto res_sig {big_sig_lhs / static_cast(rhs.sig)}; - auto res_exp {(lhs.exp - detail::precision) - rhs.exp}; + constexpr auto precision_offset {std::numeric_limits::digits10 - precision}; + constexpr auto ten_pow_offset {detail::pow10(static_cast(precision_offset))}; - #ifdef BOOST_DECIMAL_DEBUG - std::cerr << "\nres sig: " << res_sig_32 - << "\nres exp: " << res_exp << std::endl; - #endif + const auto big_sig_lhs {lhs.full_significand() * ten_pow_offset}; - if (res_sig == 0U) + const auto res_sig {big_sig_lhs / rhs.full_significand()}; + const auto res_exp {(lhs.biased_exponent() - precision_offset) - rhs.biased_exponent()}; + + // Normalizes sign handling + bool sign {lhs.isneg() != rhs.isneg()}; + if (BOOST_DECIMAL_UNLIKELY(res_sig == 0U)) { sign = false; } @@ -52,21 +55,15 @@ BOOST_DECIMAL_FORCE_INLINE constexpr auto d64_generic_div_impl(const T& lhs, con // If rhs is greater than we need to offset the significands to get the correct values // e.g. 4/8 is 0 but 40/8 yields 5 in integer maths - constexpr auto tens_needed {detail::pow10(static_cast(detail::precision_v))}; + constexpr auto offset {std::numeric_limits::digits10 - detail::precision_v}; + constexpr auto tens_needed {detail::pow10(static_cast(offset))}; const auto big_sig_lhs {static_cast(lhs.sig) * tens_needed}; const auto res_sig {big_sig_lhs / rhs.sig}; - const auto res_exp {(lhs.exp - detail::precision_v) - rhs.exp}; + const auto res_exp {(lhs.exp - offset) - rhs.exp}; // Let the constructor handle shrinking it back down and rounding correctly - if (res_sig < std::numeric_limits::max()) - { - return DecimalType{static_cast(res_sig), res_exp, sign}; - } - else - { - return DecimalType{res_sig, res_exp, sign}; - } + return DecimalType{res_sig, res_exp, sign}; } template diff --git a/include/boost/decimal/detail/fast_float/compute_float64.hpp b/include/boost/decimal/detail/fast_float/compute_float64.hpp index 8cd7f8cb8..dc454a36d 100644 --- a/include/boost/decimal/detail/fast_float/compute_float64.hpp +++ b/include/boost/decimal/detail/fast_float/compute_float64.hpp @@ -24,7 +24,7 @@ namespace decimal { namespace detail { namespace fast_float { -BOOST_DECIMAL_CONSTEXPR_VARIABLE double double_powers_of_ten[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE double double_powers_of_ten[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 }; diff --git a/include/boost/decimal/detail/fast_float/compute_float80_128.hpp b/include/boost/decimal/detail/fast_float/compute_float80_128.hpp index a00957918..1eebab5c9 100644 --- a/include/boost/decimal/detail/fast_float/compute_float80_128.hpp +++ b/include/boost/decimal/detail/fast_float/compute_float80_128.hpp @@ -23,7 +23,7 @@ namespace decimal { namespace detail { namespace fast_float { -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::array powers_of_ten_ld = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::array powers_of_ten_ld = { 1e0L, 1e1L, 1e2L, 1e3L, 1e4L, 1e5L, 1e6L, 1e7L, 1e8L, 1e9L, 1e10L, 1e11L, 1e12L, 1e13L, 1e14L, 1e15L, 1e16L, 1e17L, 1e18L, 1e19L, 1e20L, @@ -152,10 +152,8 @@ constexpr auto compute_float80_128(std::int64_t q, const Unsigned_Integer &w, if (BOOST_DECIMAL_UNLIKELY(ld == std::numeric_limits::infinity())) { - // LCOV_EXCL_START success = false; ld = 0.0L; - // LCOV_EXCL_STOP } return ld; diff --git a/include/boost/decimal/detail/fast_float/significand_tables.hpp b/include/boost/decimal/detail/fast_float/significand_tables.hpp index cad6cb993..afafa06ff 100644 --- a/include/boost/decimal/detail/fast_float/significand_tables.hpp +++ b/include/boost/decimal/detail/fast_float/significand_tables.hpp @@ -26,7 +26,7 @@ namespace fast_float { // 10^BOOST_DECIMAL_FASTFLOAT_LARGEST_POWER (inclusively). // The significand is truncated, and never rounded up. // Uses about 5KB. -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t significand_64[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t significand_64[] = { UINT64_C(0xa5ced43b7e3e9188), UINT64_C(0xcf42894a5dce35ea), UINT64_C(0x818995ce7aa0e1b2), UINT64_C(0xa1ebfb4219491a1f), UINT64_C(0xca66fa129f9b60a6), UINT64_C(0xfd00b897478238d0), @@ -349,7 +349,7 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t significand_64[] = { // A complement to significand_64 // complete to a 128-bit significand. // Uses about 5KB but is rarely accessed. -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t significand_128[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t significand_128[] = { UINT64_C(0x419ea3bd35385e2d), UINT64_C(0x52064cac828675b9), UINT64_C(0x7343efebd1940993), UINT64_C(0x1014ebe6c5f90bf8), UINT64_C(0xd41a26e077774ef6), UINT64_C(0x8920b098955522b4), diff --git a/include/boost/decimal/detail/fenv_rounding.hpp b/include/boost/decimal/detail/fenv_rounding.hpp index 603ddf95d..4674033e0 100644 --- a/include/boost/decimal/detail/fenv_rounding.hpp +++ b/include/boost/decimal/detail/fenv_rounding.hpp @@ -9,133 +9,270 @@ #include #include #include +#include +#include +#include "int128/cstdlib.hpp" namespace boost { namespace decimal { namespace detail { -#ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION +namespace impl { + +// These structs are for internal use only and change based on the type of T +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + +template +struct divmod_result +{ + T quotient; + T remainder; +}; + +template +struct divmod10_result +{ + T quotient; + std::uint64_t remainder; +}; + +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +template ::value, bool> = true> +constexpr auto divmod(T dividend, T divisor) noexcept -> divmod_result +{ + // Compilers usually can lump these together + const auto q {static_cast(dividend / divisor)}; + const auto r {static_cast(dividend % divisor)}; + return {q, r}; +} + +template ::value, bool> = true> +constexpr auto divmod(T dividend, T divisor) noexcept -> divmod_result +{ + T q {dividend / divisor}; + T r {dividend - q * divisor}; + return {q, r}; +} + +#ifdef BOOST_DECIMAL_DETAIL_INT128_HAS_INT128 + +constexpr auto divmod(const int128::uint128_t dividend, const int128::uint128_t divisor) -> divmod_result +{ + const auto builtin_num {static_cast(dividend)}; + const auto builtin_denom {static_cast(divisor)}; + return {builtin_num / builtin_denom, builtin_num % builtin_denom}; +} + +#endif + +constexpr auto divmod(const u256& lhs, const u256& rhs) noexcept +{ + return div_mod(lhs, rhs); +} + +template +constexpr auto divmod10(const T dividend) noexcept -> divmod10_result +{ + const auto q {static_cast(dividend / 10U)}; + const auto r {static_cast(dividend - q * 10U)}; + return {q, static_cast(r)}; +} + +constexpr auto divmod10(const u256& lhs) noexcept +{ + constexpr int128::uint128_t ten {10U}; + return div_mod(lhs, ten); +} -// Rounds the value provided and returns an offset of exponent values as required -template , bool> = true> -constexpr auto fenv_round(T& val, bool = false) noexcept -> int +constexpr auto divmod10(const int128::uint128_t lhs) noexcept -> divmod10_result +{ + constexpr std::uint32_t ten {10U}; + int128::uint128_t q {}; + int128::uint128_t r {}; + int128::detail::half_word_div(lhs, ten, q, r); + return {q, r.low}; +} + +template +constexpr auto fenv_round_impl(T& val, const bool is_neg, const bool sticky, const rounding_mode round = _boost_decimal_global_rounding_mode) noexcept -> int { using significand_type = std::conditional_t >= 128, int128::uint128_t, std::int64_t>; - const auto trailing_num {val % 10U}; - val /= 10U; - int exp_delta {1}; + int exp {1}; - if (trailing_num >= 5U) + auto div_res {divmod10(val)}; + val = div_res.quotient; + const auto trailing_num {div_res.remainder}; + + // Default rounding mode + switch (round) { - ++val; + case rounding_mode::fe_dec_to_nearest_from_zero: + if (trailing_num >= 5U) + { + ++val; + } + break; + case rounding_mode::fe_dec_downward: + if (is_neg && (trailing_num != 0U || sticky)) + { + ++val; + } + break; + case rounding_mode::fe_dec_to_nearest: + // Round to even or nearest + if (trailing_num > 5U || (trailing_num == 5U && (sticky || (static_cast(val) & 1U) == 1U))) + { + ++val; + } + break; + case rounding_mode::fe_dec_toward_zero: + // Do nothing + break; + case rounding_mode::fe_dec_upward: + if (!is_neg && (trailing_num != 0U || sticky)) + { + ++val; + } + break; + // LCOV_EXCL_START + default: + BOOST_DECIMAL_UNREACHABLE; + // LCOV_EXCL_STOP } - if (static_cast(val) > max_significand_v) + // If the significand was e.g. 99'999'999 rounding up + // would put it out of range again + if (BOOST_DECIMAL_UNLIKELY(static_cast(val) > max_significand_v())) { val /= 10U; - ++exp_delta; + ++exp; } - return exp_delta; + return exp; } -#else +} + +#ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION -template , bool> = true> -constexpr auto fenv_round(T& val, bool is_neg = false) noexcept -> int // NOLINT(readability-function-cognitive-complexity) +template , bool> = true> +constexpr auto fenv_round(T& val, bool is_neg = false, bool sticky = false) noexcept -> int { - using significand_type = std::conditional_t >= 128, int128::uint128_t, std::int64_t>; + return impl::fenv_round_impl(val, is_neg, sticky); +} +#else + +template , bool> = true> +constexpr auto fenv_round(T& val, bool is_neg = false, bool sticky = false) noexcept -> int // NOLINT(readability-function-cognitive-complexity) +{ if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(coeff)) { - const auto trailing_num {val % 10U}; - val /= 10U; - int exp_delta {1}; + return impl::fenv_round_impl(val, is_neg, sticky); + } + else + { + const auto round {fegetround()}; + return impl::fenv_round_impl(val, is_neg, sticky, round); + } +} - if (trailing_num >= 5U) - { - ++val; - } +#endif - // If the significand was e.g. 99'999'999 rounding up - // would put it out of range again +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif - if (static_cast(val) > static_cast(max_significand_v)) - { - val /= 10U; - ++exp_delta; - } +template +constexpr auto coefficient_rounding(T1& coeff, T2& exp, T3& biased_exp, const bool sign, int coeff_digits) noexcept +{ + // T1 will be a 128-bit or 256-bit + using sig_type = typename TargetDecimalType::significand_type; + using demoted_integer_type = std::conditional_t::digits10 < std::numeric_limits::digits10, T1, sig_type>; - return exp_delta; + // How many digits need to be shifted? + const auto shift_for_large_coeff {(coeff_digits - detail::precision_v) - 1}; + int shift {}; + BOOST_DECIMAL_IF_CONSTEXPR (is_fast_type_v) + { + // For fast types we never want to reduce past precision digits + // otherwise we could potentially end up incorrectly normalized + shift = shift_for_large_coeff; } else { - const auto round {fegetround()}; - int exp {1}; + const auto shift_for_small_exp {(-biased_exp) - 1}; + shift = std::max(shift_for_small_exp, shift_for_large_coeff); + } - const auto trailing_num {val % 10U}; - val /= 10U; + if (BOOST_DECIMAL_UNLIKELY(shift > std::numeric_limits::digits10)) + { + // Bounds check for our tables in pow10 + coeff = 0; + return 1; + } - // Default rounding mode - switch (round) + // Do shifting + BOOST_DECIMAL_ASSERT(shift >= 0); + const auto shift_pow_ten {detail::pow10(static_cast(shift))}; + + // In the synthetic integer cases it's inexpensive to see if we can demote the type + // relative to the cost of the division and modulo operation + demoted_integer_type shifted_coeff {}; + bool sticky {}; + BOOST_DECIMAL_IF_CONSTEXPR (sizeof(T1) < sizeof(int128::uint128_t)) + { + const auto div_res {impl::divmod(coeff, shift_pow_ten)}; + shifted_coeff = static_cast(div_res.quotient); + const auto trailing_digits {div_res.remainder}; + sticky = trailing_digits != 0U; + } + else + { + if (coeff < std::numeric_limits::max()) { - case rounding_mode::fe_dec_to_nearest_from_zero: - if (trailing_num >= 5U) - { - ++val; - } - break; - case rounding_mode::fe_dec_downward: - if (trailing_num >= 5U && is_neg) - { - ++val; - } - break; - case rounding_mode::fe_dec_to_nearest: - // Round to even - if (trailing_num == 5U) - { - if (val % 2U == 1U) - { - ++val; - } - } - // ... or nearest - else if (trailing_num > 5U) - { - ++val; - } - break; - case rounding_mode::fe_dec_toward_zero: - // Do nothing - break; - case rounding_mode::fe_dec_upward: - if (!is_neg && trailing_num != 0U) - { - ++val; - } - break; - // LCOV_EXCL_START - default: - BOOST_DECIMAL_UNREACHABLE; - // LCOV_EXCL_STOP + const auto smaller_coeff {static_cast(coeff)}; + const auto div_res {impl::divmod(smaller_coeff, static_cast(shift_pow_ten))}; + shifted_coeff = static_cast(div_res.quotient); + const auto trailing_digits {div_res.remainder}; + sticky = trailing_digits != 0U; } - - - // If the significand was e.g. 99'999'999 rounding up - // would put it out of range again - - if (static_cast(val) > max_significand_v) + else { - val /= 10U; - ++exp; + const auto div_res {impl::divmod(coeff, shift_pow_ten)}; + shifted_coeff = static_cast(div_res.quotient); + const auto trailing_digits {div_res.remainder}; + sticky = trailing_digits != 0U; } - - return exp; } + + // Do rounding + const auto removed_digits {detail::fenv_round(shifted_coeff, sign, sticky)}; + coeff = static_cast(shifted_coeff); + + const auto offset {removed_digits + shift}; + exp += offset; + biased_exp += offset; + coeff_digits -= offset; + + return coeff_digits; } +#ifdef _MSC_VER +# pragma warning(pop) +#elif defined(__GNUC__) +# pragma GCC diagnostic pop #endif } // namespace detail diff --git a/include/boost/decimal/detail/formatting_limits.hpp b/include/boost/decimal/detail/formatting_limits.hpp new file mode 100644 index 000000000..98d0b76c3 --- /dev/null +++ b/include/boost/decimal/detail/formatting_limits.hpp @@ -0,0 +1,77 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_FORMATTING_LIMITS_HPP +#define BOOST_DECIMAL_DETAIL_FORMATTING_LIMITS_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace decimal { + +template +class formatting_limits +{ +private: + + // Class invariant + static_assert(Precision > 0 || Precision == -1, "A specified precision must be greater than zero"); + + static constexpr std::size_t required_characters() noexcept + { + // Add an extra character for null terminator + const auto local_precision {detail::get_real_precision(Precision)}; + return detail::total_buffer_length(local_precision, detail::emax_v, true) + 1U; + } + + static constexpr std::size_t fixed_characters() noexcept + { + // Maximum would be + // sign + 0 + . + exponent number of zeros + precision + null terminator + // e.g. -0.00...01 + return static_cast(3U + detail::emax_v + 1U); + } + +public: + + static constexpr std::size_t scientific_format_max_chars {required_characters()}; + + static constexpr std::size_t fixed_format_max_chars { fixed_characters() }; + + static constexpr std::size_t hex_format_max_chars { scientific_format_max_chars }; + + static constexpr std::size_t cohort_preserving_scientific_max_chars { scientific_format_max_chars }; + + static constexpr std::size_t general_format_max_chars { scientific_format_max_chars }; + + static constexpr std::size_t max_chars { fixed_format_max_chars }; +}; + +#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) + +template +constexpr std::size_t formatting_limits::scientific_format_max_chars; + +template +constexpr std::size_t formatting_limits::fixed_format_max_chars; + +template +constexpr std::size_t formatting_limits::hex_format_max_chars; + +template +constexpr std::size_t formatting_limits::cohort_preserving_scientific_max_chars; + +template +constexpr std::size_t formatting_limits::general_format_max_chars; + +#endif + +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_FORMATTING_LIMITS_HPP diff --git a/include/boost/decimal/detail/from_chars_impl.hpp b/include/boost/decimal/detail/from_chars_impl.hpp new file mode 100644 index 000000000..cf00739d3 --- /dev/null +++ b/include/boost/decimal/detail/from_chars_impl.hpp @@ -0,0 +1,129 @@ +// Copyright 2024 - 2035 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_FROM_CHARS_IMPL_HPP +#define BOOST_DECIMAL_DETAIL_FROM_CHARS_IMPL_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_DECIMAL_BUILD_MODULE +#include +#include +#endif + +namespace boost { +namespace decimal { +namespace detail { + +#if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) +#endif + +template +constexpr auto from_chars_general_impl(const char* first, const char* last, TargetDecimalType& value, const chars_format fmt) noexcept -> from_chars_result +{ + using significand_type = std::conditional_t<(std::numeric_limits::digits > + std::numeric_limits::digits), + int128::uint128_t, std::uint64_t>; + + BOOST_DECIMAL_IF_CONSTEXPR (is_fast_type_v) + { + if (fmt == chars_format::cohort_preserving_scientific) + { + return {first, std::errc::invalid_argument}; + } + } + + if (BOOST_DECIMAL_UNLIKELY(first >= last)) + { + return {first, std::errc::invalid_argument}; + } + + bool sign {}; + significand_type significand {}; + std::int32_t expval {}; + + auto r {detail::parser(first, last, sign, significand, expval, fmt)}; + + if (!r) + { + if (r.ec == std::errc::not_supported) + { + using resultant_sig_type = typename TargetDecimalType::significand_type; + + resultant_sig_type payload_value {}; + if (significand < std::numeric_limits::max()) + { + payload_value = static_cast(significand); + } + + if (expval > 0) + { + value = write_payload(payload_value); + } + else + { + value = write_payload(payload_value); + } + + if (sign) + { + value = -value; + } + + r.ec = std::errc(); + } + else if (r.ec == std::errc::value_too_large) + { + value = sign ? -std::numeric_limits::infinity() : + std::numeric_limits::infinity(); + r.ec = std::errc(); + } + else + { + value = std::numeric_limits::signaling_NaN(); + errno = static_cast(r.ec); + } + } + else + { + BOOST_DECIMAL_IF_CONSTEXPR (!is_fast_type_v) + { + if (fmt == chars_format::cohort_preserving_scientific) + { + const auto sig_digs {detail::num_digits(significand)}; + if (sig_digs > precision_v) + { + // If we are parsing more digits than are representable there's no concept of cohorts + return {last, std::errc::value_too_large}; + } + } + } + + value = TargetDecimalType(significand, expval, sign); + } + + return r; +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // !defined(BOOST_DECIMAL_DISABLE_CLIB) + +} // namespace detail +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_FROM_CHARS_IMPL_HPP diff --git a/include/boost/decimal/detail/from_chars_integer_impl.hpp b/include/boost/decimal/detail/from_chars_integer_impl.hpp index 6a5642e29..4164db103 100644 --- a/include/boost/decimal/detail/from_chars_integer_impl.hpp +++ b/include/boost/decimal/detail/from_chars_integer_impl.hpp @@ -26,7 +26,7 @@ namespace boost { namespace decimal { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE unsigned char uchar_values[] = +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE unsigned char uchar_values[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, diff --git a/include/boost/decimal/detail/from_chars_result.hpp b/include/boost/decimal/detail/from_chars_result.hpp index 421710eb2..bdb8ac6e4 100644 --- a/include/boost/decimal/detail/from_chars_result.hpp +++ b/include/boost/decimal/detail/from_chars_result.hpp @@ -18,6 +18,12 @@ namespace decimal { // 22.13.3, Primitive numerical input conversion +// This is how the STL says to implement +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + BOOST_DECIMAL_EXPORT struct from_chars_result { const char* ptr; @@ -41,6 +47,10 @@ BOOST_DECIMAL_EXPORT struct from_chars_result constexpr explicit operator bool() const noexcept { return ec == std::errc{}; } }; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/i256.hpp b/include/boost/decimal/detail/i256.hpp new file mode 100644 index 000000000..d15e4cb6f --- /dev/null +++ b/include/boost/decimal/detail/i256.hpp @@ -0,0 +1,254 @@ +// Copyright 2023 - 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// This is not a fully featured implementation of a 256-bit integer like int128::uint128_t is +// i256 only contains the minimum amount that we need to perform operations like decimal128_t add/sub + +#ifndef BOOST_DECIMAL_DETAIL_I256_HPP +#define BOOST_DECIMAL_DETAIL_I256_HPP + +#include +#include +#include + +namespace boost { +namespace decimal { +namespace detail { + +namespace impl { + +// This impl works regardless of intrinsics or otherwise +constexpr u256 u256_add_impl(const int128::uint128_t& lhs, const int128::uint128_t& rhs) noexcept +{ + u256 result; + std::uint64_t carry {}; + + auto sum {lhs.low + rhs.low}; + result[0] = sum; + carry = (sum < lhs.low) ? 1 : 0; + + sum = lhs.high + rhs.high + carry; + result[1] = sum; + result[2] = static_cast(sum < lhs.high || (sum == lhs.high && carry)); + + return result; +} + +} // namespace impl + +#if !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) && defined(BOOST_DECIMAL_ADD_CARRY) + +constexpr u256 u256_add(const int128::uint128_t& lhs, const int128::uint128_t& rhs) noexcept +{ + if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + return impl::u256_add_impl(lhs, rhs); + } + else + { + unsigned long long result[3] {}; + unsigned char carry {}; + carry = BOOST_DECIMAL_ADD_CARRY(carry, lhs.low, rhs.low, &result[0]); + result[2] = static_cast(BOOST_DECIMAL_ADD_CARRY(carry, lhs.high, rhs.high, &result[1])); + + return {UINT64_C(0), result[2], result[1], result[0]}; + } +} + +#elif !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) && defined(__GNUC__) && !defined(BOOST_DECIMAL_ADD_CARRY) + +constexpr u256 u256_add(const int128::uint128_t& lhs, const int128::uint128_t& rhs) noexcept +{ + if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + return impl::u256_add_impl(lhs, rhs); + } + else + { + unsigned long long result[3] {}; + bool carry {}; + carry = impl::add_carry_u64(carry, lhs.low, rhs.low, &result[0]); + result[2] = static_cast(impl::add_carry_u64(carry, lhs.high, rhs.high, &result[1])); + + return {UINT64_C(0), result[2], result[1], result[0]}; + } +} + +#endif + +namespace impl { + +constexpr std::uint64_t sub_borrow_u64(const std::uint64_t borrow_in, const std::uint64_t a, const std::uint64_t b, std::uint64_t& result) noexcept +{ + const auto diff {a - b}; + const auto b1 {static_cast(a < b)}; + result = diff - borrow_in; + const auto borrow_out {b1 | (diff < borrow_in)}; + + return borrow_out; +} + +constexpr bool i256_sub_impl(const u256& a, const u256& b, u256& result) noexcept +{ + if (a >= b) + { + auto borrow {impl::sub_borrow_u64(0, a[0], b[0], result[0])}; + borrow = impl::sub_borrow_u64(borrow, a[1], b[1], result[1]); + borrow = impl::sub_borrow_u64(borrow, a[2], b[2], result[2]); + impl::sub_borrow_u64(borrow, a[3], b[3], result[3]); + return false; + } + else + { + // a < b: negative result, |a - b| = b - a + auto borrow {impl::sub_borrow_u64(0, b[0], a[0], result[0])}; + borrow = impl::sub_borrow_u64(borrow, b[1], a[1], result[1]); + borrow = impl::sub_borrow_u64(borrow, b[2], a[2], result[2]); + impl::sub_borrow_u64(borrow, b[3], a[3], result[3]); + return true; + } +} + +} // namespace impl + +#if !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) && defined(BOOST_DECIMAL_SUB_BORROW) + +constexpr bool i256_sub(const u256& a, const u256& b, u256& res) noexcept +{ + if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + return impl::i256_sub_impl(a, b, res); + } + else + { + if (a >= b) + { + unsigned long long result[4] {}; + unsigned char borrow {}; + + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, a[0], b[0], &result[0]); + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, a[1], b[1], &result[1]); + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, a[2], b[2], &result[2]); + BOOST_DECIMAL_SUB_BORROW(borrow, a[3], b[3], &result[3]); + + res = u256{result[3], result[2], result[1], result[0]}; + return false; + } + else + { + unsigned long long result[4] {}; + unsigned char borrow {}; + + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, b[0], a[0], &result[0]); + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, b[1], a[1], &result[1]); + borrow = BOOST_DECIMAL_SUB_BORROW(borrow, b[2], a[2], &result[2]); + BOOST_DECIMAL_SUB_BORROW(borrow, b[3], a[3], &result[3]); + + res = u256{result[3], result[2], result[1], result[0]}; + return true; + } + } +} + +#elif !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) && defined(__GNUC__) && !defined(BOOST_DECIMAL_SUB_BORROW) && BOOST_DECIMAL_HAS_BUILTIN(__builtin_subcll) + +constexpr bool i256_sub(const u256& a, const u256& b, u256& result) noexcept +{ + if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + return impl::i256_sub_impl(a, b, result); + } + else + { + if (a >= b) + { + unsigned long long borrow {}; + + result[0] = __builtin_subcll(a[0], b[0], borrow, &borrow); + result[1] = __builtin_subcll(a[1], b[1], borrow, &borrow); + result[2] = __builtin_subcll(a[2], b[2], borrow, &borrow); + result[3] = __builtin_subcll(a[3], b[3], borrow, &borrow); + + return false; + } + else + { + unsigned long long borrow {}; + + result[0] = __builtin_subcll(b[0], a[0], borrow, &borrow); + result[1] = __builtin_subcll(b[1], a[1], borrow, &borrow); + result[2] = __builtin_subcll(b[2], a[2], borrow, &borrow); + result[3] = __builtin_subcll(b[3], a[3], borrow, &borrow); + + return true; + } + } +} + +#elif !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) && defined(BOOST_DECIMAL_HAS_x86_INTRINSICS) + +namespace impl { + +// __builtin_subcll is missing from some platforms but __builtin_sub_overflow is present. +// Implement exactly as shown on the GCC page: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html + +inline std::uint64_t subcll(const std::uint64_t a, const std::uint64_t b, const std::uint64_t carry_in, std::uint64_t* carry_out) noexcept +{ + std::uint64_t s; + const auto c1 {__builtin_sub_overflow(a, b, &s)}; + const auto c2 {__builtin_sub_overflow(s, carry_in, &s)}; + *carry_out = static_cast(c1 | c2); + + return s; +} + +} // namespace impl + +constexpr bool i256_sub(const u256& a, const u256& b, u256& result) noexcept +{ + if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs)) + { + return impl::i256_sub_impl(a, b, result); + } + else + { + if (a >= b) + { + unsigned long long borrow {}; + + result[0] = impl::subcll(a[0], b[0], borrow, &borrow); + result[1] = impl::subcll(a[1], b[1], borrow, &borrow); + result[2] = impl::subcll(a[2], b[2], borrow, &borrow); + result[3] = impl::subcll(a[3], b[3], borrow, &borrow); + + return false; + } + else + { + unsigned long long borrow {}; + + result[0] = impl::subcll(b[0], a[0], borrow, &borrow); + result[1] = impl::subcll(b[1], a[1], borrow, &borrow); + result[2] = impl::subcll(b[2], a[2], borrow, &borrow); + result[3] = impl::subcll(b[3], a[3], borrow, &borrow); + + return true; + } + } +} + +#else + +constexpr bool i256_sub(const u256& a, const u256& b, u256& result) noexcept +{ + return impl::i256_sub_impl(a, b, result); +} + +#endif + +} // namespace detail +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_I256_HPP diff --git a/include/boost/decimal/detail/int128/cstdlib.hpp b/include/boost/decimal/detail/int128/cstdlib.hpp new file mode 100644 index 000000000..00de6f2f8 --- /dev/null +++ b/include/boost/decimal/detail/int128/cstdlib.hpp @@ -0,0 +1,103 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_INT128_CSTDLIB_HPP +#define BOOST_DECIMAL_DETAIL_INT128_CSTDLIB_HPP + +#include "int128.hpp" + +namespace boost { +namespace int128 { + +struct u128div_t +{ + uint128_t quot; + uint128_t rem; +}; + +struct i128div_t +{ + int128_t quot; + int128_t rem; +}; + +constexpr u128div_t div(const uint128_t x, const uint128_t y) noexcept +{ + if (BOOST_DECIMAL_DETAIL_INT128_UNLIKELY(x == 0U || y == 0U)) + { + return u128div_t{0U, 0U}; + } + + if (x < y) + { + return u128div_t{0U, x}; + } + else if (y.high != 0U) + { + u128div_t res {}; + res.quot = detail::knuth_div(x, y, res.rem); + return res; + } + else + { + if (x.high == 0U) + { + return u128div_t{x.low / y.low, x.low % y.low}; + } + else + { + u128div_t res {}; + detail::one_word_div(x, y.low, res.quot, res.rem); + return res; + } + } +} + +constexpr i128div_t div(const int128_t x, const int128_t y) noexcept +{ + if (BOOST_DECIMAL_DETAIL_INT128_UNLIKELY(x == 0 || y == 0)) + { + return i128div_t{0, 0}; + } + + #if defined(BOOST_DECIMAL_DETAIL_INT128_HAS_INT128) + + const auto builtin_x {static_cast(x)}; + const auto builtin_y {static_cast(y)}; + return i128div_t{static_cast(builtin_x / builtin_y), + static_cast(builtin_x % builtin_y)}; + + #else + + const auto abs_lhs {static_cast(abs(x))}; + const auto abs_rhs {static_cast(abs(y))}; + + if (abs_rhs > abs_lhs) + { + return {0, x}; + } + + const auto unsigned_res {div(abs_lhs, abs_rhs)}; + + const auto negative_quot {(x.high < 0) != (y.high < 0)}; + #if defined(_MSC_VER) && !defined(__GNUC__) + const auto negative_rem {x.high < 0}; + #else + const auto negative_rem {(x.high < 0) != (y.high < 0)}; + #endif + + i128div_t res {static_cast(unsigned_res.quot), static_cast(unsigned_res.rem)}; + + res.quot = negative_quot ? -res.quot : res.quot; + res.rem = negative_rem ? -res.rem : res.rem; + + return res; + + #endif +} + +} // namespace int128 +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_INT128_CSTDLIB_HPP diff --git a/include/boost/decimal/detail/int128/detail/clz.hpp b/include/boost/decimal/detail/int128/detail/clz.hpp index be9c9bbf6..61d609702 100644 --- a/include/boost/decimal/detail/int128/detail/clz.hpp +++ b/include/boost/decimal/detail/int128/detail/clz.hpp @@ -16,7 +16,7 @@ namespace detail { namespace impl { // See: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn -BOOST_DECIMAL_CONSTEXPR_VARIABLE int index64[64] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int index64[64] = { 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, @@ -43,7 +43,7 @@ constexpr int bit_scan_reverse(std::uint64_t bb) noexcept return index64[(bb * debruijn64) >> 58]; } -BOOST_DECIMAL_CONSTEXPR_VARIABLE int countl_mod37[37] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int countl_mod37[37] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, diff --git a/include/boost/decimal/detail/int128/detail/constants.hpp b/include/boost/decimal/detail/int128/detail/constants.hpp index a59b6b9d1..9e2024d4a 100644 --- a/include/boost/decimal/detail/int128/detail/constants.hpp +++ b/include/boost/decimal/detail/int128/detail/constants.hpp @@ -12,10 +12,10 @@ namespace boost { namespace int128 { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t low_word_mask {(std::numeric_limits::max)()}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t low_word_mask {(std::numeric_limits::max)()}; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE T offset_value_v = static_cast((std::numeric_limits::max)()); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE T offset_value_v = static_cast((std::numeric_limits::max)()); } // namespace detail } // namespace int128 diff --git a/include/boost/decimal/detail/int128/detail/conversions.hpp b/include/boost/decimal/detail/int128/detail/conversions.hpp index 27c65df82..c9d45528a 100644 --- a/include/boost/decimal/detail/int128/detail/conversions.hpp +++ b/include/boost/decimal/detail/int128/detail/conversions.hpp @@ -20,7 +20,7 @@ struct valid_overload }; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_valid_overload_v = valid_overload::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_valid_overload_v = valid_overload::value; } // namespace detail diff --git a/include/boost/decimal/detail/int128/detail/ctz.hpp b/include/boost/decimal/detail/int128/detail/ctz.hpp index f83be5dd3..84c74a160 100644 --- a/include/boost/decimal/detail/int128/detail/ctz.hpp +++ b/include/boost/decimal/detail/int128/detail/ctz.hpp @@ -34,7 +34,7 @@ constexpr int countr_impl(unsigned long long x) noexcept #endif -BOOST_DECIMAL_CONSTEXPR_VARIABLE int countr_mod37[37] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int countr_mod37[37] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, diff --git a/include/boost/decimal/detail/int128/detail/int128_imp.hpp b/include/boost/decimal/detail/int128/detail/int128_imp.hpp index 5da9980c3..3c1796fca 100644 --- a/include/boost/decimal/detail/int128/detail/int128_imp.hpp +++ b/include/boost/decimal/detail/int128/detail/int128_imp.hpp @@ -3071,9 +3071,9 @@ constexpr int128_t operator%(const int128_t lhs, const int128_t rhs) noexcept #else #if defined(_MSC_VER) && !defined(__GNUC__) - const auto is_neg{static_cast(lhs < 0)}; + const auto is_neg{lhs < 0}; #else - const auto is_neg {static_cast((lhs < 0) != (rhs < 0))}; + const auto is_neg {(lhs < 0) != (rhs < 0)}; #endif int128_t remainder {}; @@ -3215,17 +3215,14 @@ inline int128_t& int128_t::operator%=(const Integer rhs) noexcept #endif // BOOST_DECIMAL_DETAIL_INT128_HAS_MSVC_INT128 -} // namespace int128 -} // namespace boost - -namespace std { +namespace detail { -template <> -class numeric_limits +template +class numeric_limits_impl_i128 { public: - // Member constants + // Member constants static constexpr bool is_specialized = true; static constexpr bool is_signed = true; static constexpr bool is_integer = true; @@ -3279,6 +3276,59 @@ class numeric_limits static constexpr auto denorm_min () -> boost::int128::int128_t { return {0, 0}; } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl_i128::is_specialized; +template constexpr bool numeric_limits_impl_i128::is_signed; +template constexpr bool numeric_limits_impl_i128::is_integer; +template constexpr bool numeric_limits_impl_i128::is_exact; +template constexpr bool numeric_limits_impl_i128::has_infinity; +template constexpr bool numeric_limits_impl_i128::has_quiet_NaN; +template constexpr bool numeric_limits_impl_i128::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl_i128::has_denorm; +template constexpr bool numeric_limits_impl_i128::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl_i128::round_style; +template constexpr bool numeric_limits_impl_i128::is_iec559; +template constexpr bool numeric_limits_impl_i128::is_bounded; +template constexpr bool numeric_limits_impl_i128::is_modulo; +template constexpr int numeric_limits_impl_i128::digits; +template constexpr int numeric_limits_impl_i128::digits10; +template constexpr int numeric_limits_impl_i128::max_digits10; +template constexpr int numeric_limits_impl_i128::radix; +template constexpr int numeric_limits_impl_i128::min_exponent; +template constexpr int numeric_limits_impl_i128::min_exponent10; +template constexpr int numeric_limits_impl_i128::max_exponent; +template constexpr int numeric_limits_impl_i128::max_exponent10; +template constexpr bool numeric_limits_impl_i128::traps; +template constexpr bool numeric_limits_impl_i128::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace int128 +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::int128::detail::numeric_limits_impl_i128 {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // namespace std #endif // BOOST_DECIMAL_DETAIL_INT128_DETAIL_INT128_HPP diff --git a/include/boost/decimal/detail/int128/detail/mini_from_chars.hpp b/include/boost/decimal/detail/int128/detail/mini_from_chars.hpp index d12b2a1f0..ffb92a9a5 100644 --- a/include/boost/decimal/detail/int128/detail/mini_from_chars.hpp +++ b/include/boost/decimal/detail/int128/detail/mini_from_chars.hpp @@ -17,7 +17,7 @@ namespace int128 { namespace detail { namespace impl { -BOOST_DECIMAL_CONSTEXPR_VARIABLE unsigned char uchar_values[] = +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE unsigned char uchar_values[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, diff --git a/include/boost/decimal/detail/int128/detail/mini_to_chars.hpp b/include/boost/decimal/detail/int128/detail/mini_to_chars.hpp index d58e1d7e6..76659d8c2 100644 --- a/include/boost/decimal/detail/int128/detail/mini_to_chars.hpp +++ b/include/boost/decimal/detail/int128/detail/mini_to_chars.hpp @@ -13,14 +13,14 @@ namespace boost { namespace int128 { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE char lower_case_digit_table[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE char lower_case_digit_table[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; static_assert(sizeof(lower_case_digit_table) == sizeof(char) * 16, "10 numbers, and 6 letters"); -BOOST_DECIMAL_CONSTEXPR_VARIABLE char upper_case_digit_table[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE char upper_case_digit_table[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; diff --git a/include/boost/decimal/detail/int128/detail/traits.hpp b/include/boost/decimal/detail/int128/detail/traits.hpp index f0d72df1c..f7a35044a 100644 --- a/include/boost/decimal/detail/int128/detail/traits.hpp +++ b/include/boost/decimal/detail/int128/detail/traits.hpp @@ -25,7 +25,7 @@ struct signed_integer }; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_signed_integer_v = signed_integer::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_signed_integer_v = signed_integer::value; template struct unsigned_integer @@ -39,10 +39,10 @@ struct unsigned_integer }; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_unsigned_integer_v = unsigned_integer::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_unsigned_integer_v = unsigned_integer::value; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_any_integer_v = signed_integer::value || unsigned_integer::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_any_integer_v = signed_integer::value || unsigned_integer::value; // Decides if we can use a u32 or u64 implementation for some operations diff --git a/include/boost/decimal/detail/int128/detail/uint128_imp.hpp b/include/boost/decimal/detail/int128/detail/uint128_imp.hpp index f6df25194..c1c2a6469 100644 --- a/include/boost/decimal/detail/int128/detail/uint128_imp.hpp +++ b/include/boost/decimal/detail/int128/detail/uint128_imp.hpp @@ -674,8 +674,10 @@ constexpr bool operator<(const uint128_t lhs, const uint128_t rhs) noexcept } else { - const uint32_t* l = reinterpret_cast(&lhs); - const uint32_t* r = reinterpret_cast(&rhs); + std::uint32_t l[4] {}; + std::uint32_t r[4] {}; + std::memcpy(l, &lhs, sizeof(lhs)); + std::memcpy(r, &rhs, sizeof(rhs)); if (l[3] != r[3]) { @@ -827,8 +829,10 @@ constexpr bool operator<=(const uint128_t lhs, const uint128_t rhs) noexcept } else { - const uint32_t* l = reinterpret_cast(&lhs); - const uint32_t* r = reinterpret_cast(&rhs); + std::uint32_t l[4] {}; + std::uint32_t r[4] {}; + std::memcpy(l, &lhs, sizeof(lhs)); + std::memcpy(r, &rhs, sizeof(rhs)); if (l[3] != r[3]) { @@ -980,8 +984,10 @@ constexpr bool operator>(const uint128_t lhs, const uint128_t rhs) noexcept } else { - const uint32_t* l = reinterpret_cast(&lhs); - const uint32_t* r = reinterpret_cast(&rhs); + std::uint32_t l[4] {}; + std::uint32_t r[4] {}; + std::memcpy(l, &lhs, sizeof(lhs)); + std::memcpy(r, &rhs, sizeof(rhs)); if (l[3] != r[3]) { @@ -1133,8 +1139,10 @@ constexpr bool operator>=(const uint128_t lhs, const uint128_t rhs) noexcept } else { - const uint32_t* l = reinterpret_cast(&lhs); - const uint32_t* r = reinterpret_cast(&rhs); + std::uint32_t l[4] {}; + std::uint32_t r[4] {}; + std::memcpy(l, &lhs, sizeof(lhs)); + std::memcpy(r, &rhs, sizeof(rhs)); if (l[3] != r[3]) { @@ -3159,17 +3167,14 @@ inline uint128_t& uint128_t::operator%=(const Integer rhs) noexcept #endif // BOOST_DECIMAL_DETAIL_INT128_HAS_MSVC_INT128 -} // namespace int128 -} // namespace boost - -namespace std { +namespace detail { -template <> -class numeric_limits +template +class numeric_limits_impl_u128 { public: - // Member constants + // Member constants static constexpr bool is_specialized = true; static constexpr bool is_signed = false; static constexpr bool is_integer = true; @@ -3223,6 +3228,60 @@ class numeric_limits static constexpr auto denorm_min () -> boost::int128::uint128_t { return {0, 0}; } }; -}// namespace std +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +template constexpr bool numeric_limits_impl_u128::is_specialized; +template constexpr bool numeric_limits_impl_u128::is_signed; +template constexpr bool numeric_limits_impl_u128::is_integer; +template constexpr bool numeric_limits_impl_u128::is_exact; +template constexpr bool numeric_limits_impl_u128::has_infinity; +template constexpr bool numeric_limits_impl_u128::has_quiet_NaN; +template constexpr bool numeric_limits_impl_u128::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +template constexpr std::float_denorm_style numeric_limits_impl_u128::has_denorm; +template constexpr bool numeric_limits_impl_u128::has_denorm_loss; +#endif + +template constexpr std::float_round_style numeric_limits_impl_u128::round_style; +template constexpr bool numeric_limits_impl_u128::is_iec559; +template constexpr bool numeric_limits_impl_u128::is_bounded; +template constexpr bool numeric_limits_impl_u128::is_modulo; +template constexpr int numeric_limits_impl_u128::digits; +template constexpr int numeric_limits_impl_u128::digits10; +template constexpr int numeric_limits_impl_u128::max_digits10; +template constexpr int numeric_limits_impl_u128::radix; +template constexpr int numeric_limits_impl_u128::min_exponent; +template constexpr int numeric_limits_impl_u128::min_exponent10; +template constexpr int numeric_limits_impl_u128::max_exponent; +template constexpr int numeric_limits_impl_u128::max_exponent10; +template constexpr bool numeric_limits_impl_u128::traps; +template constexpr bool numeric_limits_impl_u128::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + + +} // namespace detail + +} // namespace int128 +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::int128::detail::numeric_limits_impl_u128 {}; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // namespace std #endif //BOOST_DECIMAL_DETAIL_INT128_DETAIL_UINT128_IMP_HPP diff --git a/include/boost/decimal/detail/int128/iostream.hpp b/include/boost/decimal/detail/int128/iostream.hpp index 157dfe171..8dc094a06 100644 --- a/include/boost/decimal/detail/int128/iostream.hpp +++ b/include/boost/decimal/detail/int128/iostream.hpp @@ -26,7 +26,7 @@ struct streamable_overload }; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_streamable_overload_v = streamable_overload::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_streamable_overload_v = streamable_overload::value; } // namespace detail diff --git a/include/boost/decimal/detail/int128/numeric.hpp b/include/boost/decimal/detail/int128/numeric.hpp index 36932b614..ceecb660c 100644 --- a/include/boost/decimal/detail/int128/numeric.hpp +++ b/include/boost/decimal/detail/int128/numeric.hpp @@ -35,14 +35,14 @@ struct reduced_integers #if defined(BOOST_DECIMAL_DETAIL_INT128_HAS_INT128) || defined(BOOST_DECIMAL_DETAIL_INT128_HAS_MSVC_INT128) template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_reduced_integer_v {reduced_integers::value || +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_reduced_integer_v {reduced_integers::value || std::is_same::value || std::is_same::value}; #else template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool is_reduced_integer_v {reduced_integers::value}; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool is_reduced_integer_v {reduced_integers::value}; #endif // 128-bit diff --git a/include/boost/decimal/detail/integer_search_trees.hpp b/include/boost/decimal/detail/integer_search_trees.hpp index e7f333356..df19e5e45 100644 --- a/include/boost/decimal/detail/integer_search_trees.hpp +++ b/include/boost/decimal/detail/integer_search_trees.hpp @@ -24,26 +24,14 @@ namespace decimal { namespace detail { // Generic solution -template -constexpr auto num_digits(T x) noexcept -> int -{ - int digits = 0; - - while (x) - { - x /= 10U; - ++digits; - } - - return digits; -} - -template <> -constexpr auto num_digits(std::uint32_t x) noexcept -> int +template ::digits10 <= std::numeric_limits::digits10, bool> = true> +constexpr auto num_digits(T init_x) noexcept -> int { // Use the most significant bit position to approximate log10 // log10(x) ~= log2(x) / log2(10) ~= log2(x) / 3.32 + const auto x {static_cast(init_x)}; + const auto msb {32 - int128::detail::impl::countl_impl(x)}; // Approximate log10 @@ -62,12 +50,15 @@ constexpr auto num_digits(std::uint32_t x) noexcept -> int return estimated_digits; } -template <> -constexpr auto num_digits(std::uint64_t x) noexcept -> int +template ::digits10 <= std::numeric_limits::digits10) && + (std::numeric_limits::digits10 > std::numeric_limits::digits10), bool> = true> +constexpr auto num_digits(T init_x) noexcept -> int { // Use the most significant bit position to approximate log10 // log10(x) ~= log2(x) / log2(10) ~= log2(x) / 3.32 + const auto x {static_cast(init_x)}; + const auto msb {63 - int128::detail::impl::countl_impl(x)}; // Approximate log10 @@ -91,7 +82,7 @@ constexpr auto num_digits(std::uint64_t x) noexcept -> int # pragma warning(disable: 4307) // MSVC 14.1 warns of intergral constant overflow #endif -constexpr int num_digits(const boost::int128::uint128_t& x) noexcept +constexpr int num_digits(const int128::uint128_t& x) noexcept { if (x.high == UINT64_C(0)) { @@ -111,7 +102,8 @@ constexpr int num_digits(const boost::int128::uint128_t& x) noexcept return estimated_digits + 1; } - if (estimated_digits > 1 && x < impl::BOOST_DECIMAL_DETAIL_INT128_pow10[estimated_digits - 1]) + // Estimated digits can't be less than 20 (65-bits) + if (x < impl::BOOST_DECIMAL_DETAIL_INT128_pow10[estimated_digits - 1]) { return estimated_digits - 1; } @@ -147,7 +139,8 @@ constexpr int num_digits(const u256& x) noexcept return estimated_digits + 1; } - if (estimated_digits > 1 && x < impl::u256_pow_10[estimated_digits - 1]) + // Estimated digits will never be less than 39 (129 bits) + if (x < impl::u256_pow_10[estimated_digits - 1]) { return estimated_digits - 1; } @@ -163,262 +156,11 @@ constexpr int num_digits(const u256& x) noexcept constexpr auto num_digits(const builtin_uint128_t& x) noexcept -> int { - if (static_cast(x >> 64) == UINT64_C(0)) - { - return num_digits(static_cast(x)); - } - - // We start left at 19 because we already eliminated the high word being 0 - std::uint32_t left = 19U; - std::uint32_t right = 38U; - - while (left < right) - { - std::uint32_t mid = (left + right + 1U) / 2U; - - if (x >= impl::builtin_128_pow10[mid]) - { - left = mid; - } - else - { - right = mid - 1; - } - } - - return static_cast(left + 1); + return num_digits(int128::uint128_t{x}); } #endif // Has int128 -// Specializations with pruned branches for constructors -// Since we already have partial information we can greatly speed things up in this case -template -constexpr auto d32_constructor_num_digits(T) noexcept -> std::enable_if_t::digits10 + 1 < 7, int> -{ - // Does not matter since it is guaranteed to fit - return 0; -} - -template -constexpr auto d32_constructor_num_digits(T x) noexcept -> std::enable_if_t<(std::numeric_limits::digits10 + 1 <= 10) && - (std::numeric_limits::digits10 + 1 > 7), int> -{ - BOOST_DECIMAL_ASSERT(x >= 10000000); - - if (x >= 100000000) - { - if (x >= 1000000000) - { - return 10; - } - return 9; - } - return 8; -} - -template -constexpr auto d32_constructor_num_digits(T x) noexcept -> std::enable_if_t<(std::numeric_limits::digits10 + 1 > 10) && - (std::numeric_limits::digits10 + 1 <= 20), int> -{ - // We already know that x >= 10000000 (7 digits) - BOOST_DECIMAL_ASSERT(x >= 10000000); - - if (x >= UINT64_C(10000000000)) - { - if (x >= UINT64_C(100000000000000)) - { - if (x >= UINT64_C(10000000000000000)) - { - if (x >= UINT64_C(100000000000000000)) - { - if (x >= UINT64_C(1000000000000000000)) - { - if (x >= UINT64_C(10000000000000000000)) - { - return 20; - } - return 19; - } - return 18; - } - return 17; - } - else if (x >= UINT64_C(1000000000000000)) - { - return 16; - } - return 15; - } - if (x >= UINT64_C(1000000000000)) - { - if (x >= UINT64_C(10000000000000)) - { - return 14; - } - return 13; - } - if (x >= UINT64_C(100000000000)) - { - return 12; - } - return 11; - } - else // 10000000 <= x < 10000000000 - { - if (x >= UINT64_C(100000000)) - { - if (x >= UINT64_C(1000000000)) - { - return 10; - } - return 9; - } - else // 10000000 <= x < 100000000 - { - return 8; - } - } -} - -template -constexpr auto d32_constructor_num_digits(T x) noexcept -> std::enable_if_t<(std::numeric_limits::digits10 + 1 > 20), int> -{ - // Anything bigger than uint64_t has no benefit so fall back to that - return num_digits(x); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 -constexpr auto d32_constructor_num_digits(builtin_uint128_t x) noexcept -> int -{ - return num_digits(x); -} -#endif - -template -constexpr auto d64_constructor_num_digits(T) noexcept -> std::enable_if_t<(std::numeric_limits::digits10 + 1 <= 16), int> -{ - return 0; -} - -template -constexpr auto d64_constructor_num_digits(T x) noexcept -> std::enable_if_t<(std::numeric_limits::digits10 + 1 > 16) && - (std::numeric_limits::digits10 <= 20), int> -{ - // Pre-condition: x >= 10^16 - BOOST_DECIMAL_ASSERT(x >= UINT64_C(10000000000000000)); - - if (x >= UINT64_C(100000000000000000)) - { - if (x >= UINT64_C(1000000000000000000)) - { - if (x >= UINT64_C(10000000000000000000)) - { - return 20; - } - return 19; - } - return 18; - } - return 17; -} - -template -constexpr auto d64_constructor_num_digits(T x) noexcept -> std::enable_if_t::digits10 >= 20, int> -{ - return num_digits(x); -} - -#ifdef BOOST_DECIMAL_HAS_INT128 -constexpr auto d64_constructor_num_digits(builtin_uint128_t x) noexcept -> int -{ - return num_digits(x); -} -#endif - -template -constexpr auto d128_constructor_num_digits(T) noexcept -> std::enable_if_t::digits10 + 1 <= 34, int> -{ - return 0; -} - -#ifdef BOOST_DECIMAL_HAS_INT128 -constexpr auto d128_constructor_num_digits(builtin_uint128_t x) noexcept -> int -{ - // Pre-condition: we know x has at least 34 digits - BOOST_DECIMAL_ASSERT(x >= detail::pow10(static_cast(33))); - - constexpr auto digits35 {detail::pow10(static_cast(34))}; - constexpr auto digits36 {detail::pow10(static_cast(35))}; - constexpr auto digits37 {detail::pow10(static_cast(36))}; - constexpr auto digits38 {detail::pow10(static_cast(37))}; - constexpr auto digits39 {detail::pow10(static_cast(38))}; - - if (x >= digits38) - { - if (x >= digits39) - { - return 39; - } - return 38; - } - if (x >= digits36) - { - if (x >= digits37) - { - return 37; - } - return 36; - } - if (x >= digits35) - { - return 35; - } - - return 34; // Since we know x has at least 34 digits -} -#endif - -constexpr auto d128_constructor_num_digits(const boost::int128::uint128_t x) noexcept -> int -{ - // Pre-condition: we know x has at least 34 digits - BOOST_DECIMAL_ASSERT(x >= detail::pow10(static_cast(33))); - - // Since we know that x has at least 34 digits we can get away with just comparing the high bits, - // which reduces these to uint64_t comps instead of synthesized 128-bit - - constexpr auto digits35 {detail::pow10(static_cast(34)).high}; - constexpr auto digits36 {detail::pow10(static_cast(35)).high}; - constexpr auto digits37 {detail::pow10(static_cast(36)).high}; - constexpr auto digits38 {detail::pow10(static_cast(37)).high}; - constexpr auto digits39 {detail::pow10(static_cast(38)).high}; - - const auto x_high {x.high}; - - if (x_high >= digits38) - { - if (x_high >= digits39) - { - return 39; - } - return 38; - } - if (x_high >= digits36) - { - if (x_high >= digits37) - { - return 37; - } - return 36; - } - if (x_high >= digits35) - { - return 35; - } - - return 34; // Since we know x has at least 34 digits -} - } // namespace detail } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/io.hpp b/include/boost/decimal/detail/io.hpp index 5d12d84ca..f8112f129 100644 --- a/include/boost/decimal/detail/io.hpp +++ b/include/boost/decimal/detail/io.hpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #endif namespace boost { @@ -36,16 +38,34 @@ BOOST_DECIMAL_EXPORT template >(std::basic_istream& is, DecimalType& d) -> std::enable_if_t, std::basic_istream&> { - charT t_buffer[1024] {}; // What should be an unreasonably high maximum - is >> std::setw(1023) >> t_buffer; + constexpr std::size_t static_buffer_size {1024U}; - char buffer[1024] {}; + std::basic_string t_buffer; + is >> std::ws >> t_buffer; + + const auto t_buffer_len {t_buffer.length()}; + + char static_buffer[static_buffer_size] {}; + std::unique_ptr longer_char_buffer {nullptr}; + char* buffer {static_buffer}; + + if (BOOST_DECIMAL_UNLIKELY(t_buffer_len > static_buffer_size)) + { + longer_char_buffer = std::unique_ptr(new(std::nothrow) char[t_buffer_len]); + if (longer_char_buffer.get() == nullptr) + { + errno = ENOMEM; + return is; + } + + buffer = longer_char_buffer.get(); + } BOOST_DECIMAL_IF_CONSTEXPR (!std::is_same::value) { - auto first = buffer; - auto t_first = t_buffer; - auto t_buffer_end = t_buffer + std::strlen(t_buffer); + auto first {buffer}; + auto t_first {t_buffer.begin()}; + auto t_buffer_end {t_buffer.end()}; while (t_first != t_buffer_end) { @@ -54,12 +74,12 @@ auto operator>>(std::basic_istream& is, DecimalType& d) } else { - std::memcpy(buffer, t_buffer, sizeof(t_buffer)); + std::memcpy(buffer, t_buffer.c_str(), t_buffer.size()); } - detail::convert_string_to_c_locale(buffer); + detail::convert_string_to_c_locale(buffer, is.getloc()); - chars_format fmt = chars_format::general; + auto fmt {chars_format::general}; const auto flags {is.flags()}; if (flags & std::ios_base::scientific) { @@ -74,17 +94,35 @@ auto operator>>(std::basic_istream& is, DecimalType& d) fmt = chars_format::fixed; } - auto r = from_chars(buffer, buffer + std::strlen(buffer), d, fmt); + auto first {buffer}; + if (*first == '+') + { + // Having a leading + sign is legal in iostream, but not allowed with charconv + // Pre-processing this case away helps support for both + ++first; + } + + auto r = from_chars(first, buffer + std::strlen(buffer), d, fmt); if (BOOST_DECIMAL_UNLIKELY(r.ec == std::errc::not_supported)) { - d = std::numeric_limits::signaling_NaN(); // LCOV_EXCL_LINE + d = std::numeric_limits::signaling_NaN(); } else if (static_cast(r.ec) == EINVAL) { errno = EINVAL; } + // Put back unconsumed characters + const auto consumed {static_cast(r.ptr - buffer)}; + BOOST_DECIMAL_ASSERT(t_buffer_len >= consumed); + const auto return_chars {static_cast(t_buffer_len - consumed)}; + + for (std::size_t i {}; i < return_chars; ++i) + { + is.putback(t_buffer[t_buffer_len - i - 1]); + } + return is; } @@ -126,12 +164,11 @@ auto operator<<(std::basic_ostream& os, const DecimalType& d) if (BOOST_DECIMAL_UNLIKELY(!r)) { - errno = static_cast(r.ec); // LCOV_EXCL_LINE + errno = static_cast(r.ec); } *r.ptr = '\0'; - - detail::convert_string_to_local_locale(buffer); + detail::convert_pointer_pair_to_local_locale(buffer, buffer + sizeof(buffer), os.getloc()); BOOST_DECIMAL_IF_CONSTEXPR (!std::is_same::value) { diff --git a/include/boost/decimal/detail/is_power_of_10.hpp b/include/boost/decimal/detail/is_power_of_10.hpp new file mode 100644 index 000000000..0feab0e50 --- /dev/null +++ b/include/boost/decimal/detail/is_power_of_10.hpp @@ -0,0 +1,28 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_IS_POWER_OF_10_HPP +#define BOOST_DECIMAL_DETAIL_IS_POWER_OF_10_HPP + +#include +#include +#include + +namespace boost { +namespace decimal { +namespace detail { + +template +constexpr auto is_power_of_10(const T x) noexcept + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_unsigned_v, T, bool) +{ + const auto removed_zeros {detail::remove_trailing_zeros(x)}; + return removed_zeros.trimmed_number == 1U; +} + +} // namespace detail +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_IS_POWER_OF_10_HPP diff --git a/include/boost/decimal/detail/locale_conversion.hpp b/include/boost/decimal/detail/locale_conversion.hpp index 490783d94..1c2d9c51e 100644 --- a/include/boost/decimal/detail/locale_conversion.hpp +++ b/include/boost/decimal/detail/locale_conversion.hpp @@ -15,12 +15,66 @@ namespace boost { namespace decimal { namespace detail { -inline void convert_string_to_c_locale(char* buffer) noexcept +// GCC-9 issues an erroneous warning for char == -30 being outside of type limits +#if defined(__GNUC__) && __GNUC__ >= 9 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wtype-limits" +#elif defined(__clang__) && __clang_major__ == 12 +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" +#endif + +inline void convert_string_to_c_locale(char* buffer, const std::locale& loc) noexcept { - const auto locale_decimal_point = *std::localeconv()->decimal_point; + const std::numpunct& np = std::use_facet>(loc); + + const auto locale_decimal_point {np.decimal_point()}; + auto locale_thousands_sep {np.thousands_sep()}; + if (locale_thousands_sep == -30) + { + locale_thousands_sep = ' '; + } + const bool has_grouping {!np.grouping().empty() && np.grouping()[0] > 0}; + + // Remove thousands separator if it exists and grouping is enabled + if (has_grouping && locale_thousands_sep != '\0') + { + // Find the decimal point first to know where the integer part ends + const auto decimal_pos {std::strchr(buffer, static_cast(locale_decimal_point))}; + const auto int_end {decimal_pos ? decimal_pos : (buffer + std::strlen(buffer))}; + + // Find the start of the number to include skipping sign + auto start {buffer}; + if (*start == '-' || *start == '+') + { + ++start; + } + + // Only remove thousands separators from the integer part + auto read {start}; + auto write {start}; + + while (read < int_end) + { + const auto ch = *read; + if (ch != locale_thousands_sep) + { + *write++ = *read; + } + ++read; + } + + // Copy the rest of the string (decimal point and fractional part) + while (*read != '\0') + { + *write++ = *read++; + } + *write = '\0'; + } + if (locale_decimal_point != '.') { - auto p = std::strchr(buffer, static_cast(locale_decimal_point)); + const auto p {std::strchr(buffer, static_cast(locale_decimal_point))}; if (p != nullptr) { *p = '.'; @@ -28,34 +82,131 @@ inline void convert_string_to_c_locale(char* buffer) noexcept } } -inline void convert_string_to_local_locale(char* buffer) noexcept +inline void convert_string_to_c_locale(char* buffer) noexcept { - const auto locale_decimal_point = *std::localeconv()->decimal_point; - if (locale_decimal_point != '.') + convert_string_to_c_locale(buffer, std::locale()); +} + +// Cast of return value avoids warning when sizeof(std::ptrdiff_t) > sizeof(int) e.g. when not in 32-bit +#if defined(__GNUC__) && defined(__i386__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wuseless-cast" +#endif + +inline int convert_pointer_pair_to_local_locale(char* first, const char* last, const std::locale& loc) noexcept +{ + const std::numpunct& np = std::use_facet>(loc); + + const auto locale_decimal_point {np.decimal_point()}; + auto locale_thousands_sep {np.thousands_sep()}; + if (locale_thousands_sep == -30) { - auto p = std::strchr(buffer, static_cast('.')); - if (p != nullptr) + locale_thousands_sep = ' '; + } + const bool has_grouping {!np.grouping().empty() && np.grouping()[0] > 0}; + const int grouping_size {has_grouping ? np.grouping()[0] : 0}; + + // Find the start of the number (skip sign if present) + char* start = first; + if (start < last && (*start == '-' || *start == '+')) + { + ++start; + } + + // Find the actual end of the string + auto string_end {start}; + while (string_end < last && *string_end != '\0') + { + ++string_end; + } + + // Find decimal point position + char* decimal_pos {nullptr}; + for (char* p = start; p < string_end; ++p) + { + if (*p == '.') { - *p = locale_decimal_point; + decimal_pos = p; + *decimal_pos = locale_decimal_point; + break; } } -} -inline void convert_pointer_pair_to_local_locale(char* first, const char* last) noexcept -{ - const auto locale_decimal_point = *std::localeconv()->decimal_point; - if (locale_decimal_point != '.') + // Determine the end of the integer part + const auto int_end {decimal_pos != nullptr ? decimal_pos : string_end}; + const auto int_digits {(int_end - start)}; + + // Calculate how many separators we need + int num_separators {}; + if (has_grouping && locale_thousands_sep != '\0' && int_digits > 0) + { + if (int_digits > grouping_size) + { + num_separators = static_cast((int_digits - 1) / grouping_size); + } + } + + // If we need to add separators, shift content and insert them + if (num_separators > 0) { - while (first != last) + const auto original_length {(string_end - first)}; + const auto new_length {original_length + num_separators}; + + // Check if we have enough space in the buffer + if (first + new_length >= last) + { + // Not enough space, return error indicator + return -1; + } + + // Shift everything after the integer part to make room + // Work backwards to avoid overwriting + auto old_pos {string_end}; + auto new_pos {first + new_length}; + + // Copy from end (including null terminator) back to the end of integer part + while (old_pos >= int_end) { - if (*first == '.') + *new_pos-- = *old_pos--; + } + + // Now insert the integer digits with separators + // Count digits from right to left (from decimal point backwards) + old_pos = int_end - 1; + int digits_from_right {1}; + + while (old_pos >= start) + { + *new_pos-- = *old_pos--; + + // Insert separator after every grouping_size digits from the right + // but not after the leftmost digit + if (old_pos >= start && digits_from_right % grouping_size == 0) { - *first = locale_decimal_point; + *new_pos-- = locale_thousands_sep; } - - ++first; + ++digits_from_right; } } + + return num_separators; +} + +// Cast of return value avoids warning when sizeof(std::ptrdiff_t) > sizeof(int) e.g. when not in 32-bit +#if defined(__GNUC__) && defined(__i386__) +# pragma GCC diagnostic pop +#endif + +#if defined(__GNUC__) && __GNUC__ == 9 +# pragma GCC diagnostic pop +#elif defined(__clang__) && __clang_major__ == 12 +# pragma clang diagnostic pop +#endif + +inline int convert_pointer_pair_to_local_locale(char* first, const char* last) +{ + const auto loc {std::locale()}; + return convert_pointer_pair_to_local_locale(first, last, loc); } } //namespace detail diff --git a/include/boost/decimal/detail/memcpy.hpp b/include/boost/decimal/detail/memcpy.hpp index 57fa36e3c..05f2e3113 100644 --- a/include/boost/decimal/detail/memcpy.hpp +++ b/include/boost/decimal/detail/memcpy.hpp @@ -33,8 +33,6 @@ namespace detail { namespace impl { -#define BOOST_DECIMAL_CONSTEXPR constexpr - constexpr char* memcpy_impl(char* dest, const char* src, std::size_t count) { for (std::size_t i = 0; i < count; ++i) @@ -81,11 +79,11 @@ constexpr char* memmove_impl(char* dest, const char* src, std::size_t count) #if !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION) -BOOST_DECIMAL_CONSTEXPR char* memcpy(char* dest, const char* src, std::size_t count) +constexpr char* memcpy(char* dest, const char* src, std::size_t count) { if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(count)) { - return static_cast(impl::memcpy_impl(dest, src, count)); + return impl::memcpy_impl(dest, src, count); } else { @@ -105,11 +103,11 @@ BOOST_DECIMAL_CONSTEXPR char* memcpy(char* dest, const char* src, std::size_t co } } -BOOST_DECIMAL_CONSTEXPR char* memset(char* dest, int ch, std::size_t count) +constexpr char* memset(char* dest, int ch, std::size_t count) { if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(count)) { - return static_cast(impl::memset_impl(dest, ch, count)); + return impl::memset_impl(dest, ch, count); } else { @@ -117,11 +115,11 @@ BOOST_DECIMAL_CONSTEXPR char* memset(char* dest, int ch, std::size_t count) } } -BOOST_DECIMAL_CONSTEXPR char* memmove(char* dest, const char* src, std::size_t count) +constexpr char* memmove(char* dest, const char* src, std::size_t count) { if (BOOST_DECIMAL_IS_CONSTANT_EVALUATED(count)) { - return static_cast(impl::memmove_impl(dest, src, count)); + return impl::memmove_impl(dest, src, count); } else { @@ -131,17 +129,17 @@ BOOST_DECIMAL_CONSTEXPR char* memmove(char* dest, const char* src, std::size_t c #else // No consteval detection -BOOST_DECIMAL_CONSTEXPR char* memcpy(char* dest, const char* src, std::size_t count) +constexpr char* memcpy(char* dest, const char* src, std::size_t count) { return impl::memcpy_impl(dest, src, count); } -BOOST_DECIMAL_CONSTEXPR char* memset(char* dest, int ch, std::size_t count) +constexpr char* memset(char* dest, int ch, std::size_t count) { return impl::memset_impl(dest, ch, count); } -BOOST_DECIMAL_CONSTEXPR char* memmove(char* dest, const char* src, std::size_t count) +constexpr char* memmove(char* dest, const char* src, std::size_t count) { return impl::memmove_impl(dest, src, count); } diff --git a/include/boost/decimal/detail/mul_impl.hpp b/include/boost/decimal/detail/mul_impl.hpp index e66bfa559..8d8b4d9be 100644 --- a/include/boost/decimal/detail/mul_impl.hpp +++ b/include/boost/decimal/detail/mul_impl.hpp @@ -29,7 +29,7 @@ namespace detail { template BOOST_DECIMAL_FORCE_INLINE constexpr auto mul_impl(const T& lhs, const T& rhs) noexcept -> ReturnType { - using mul_type = std::uint_fast64_t; + using mul_type = std::conditional_t < 64, std::uint_fast64_t, int128::uint128_t>; // The constructor needs to calculate the number of digits in the significand which for uint128 is slow // Since we know the value of res_sig is constrained to [1'000'000^2, 9'999'999^2] which equates to @@ -193,6 +193,13 @@ constexpr auto d128_fast_mul_impl(const T1& lhs_sig, const U1 lhs_exp, const boo return {int128::uint128_t{res_sig[1], res_sig[0]}, res_exp, sign}; } +template +BOOST_DECIMAL_FORCE_INLINE auto mul_impl(const decimal128_t_components& lhs, const decimal128_t_components& rhs) noexcept -> ReturnType +{ + return d128_mul_impl(lhs.sig, lhs.exp, lhs.sign, + rhs.sig, rhs.exp, rhs.sign); +} + } // namespace detail } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/normalize.hpp b/include/boost/decimal/detail/normalize.hpp index 0f73c091b..02c6ba9ba 100644 --- a/include/boost/decimal/detail/normalize.hpp +++ b/include/boost/decimal/detail/normalize.hpp @@ -15,6 +15,11 @@ namespace boost { namespace decimal { namespace detail { +#if defined(__GNUC__) && __GNUC__ == 7 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + // Converts the significand to full precision to remove the effects of cohorts template constexpr auto normalize(T1& significand, T2& exp, bool sign = false) noexcept -> void @@ -25,18 +30,34 @@ constexpr auto normalize(T1& significand, T2& exp, bool sign = false) noexcept - if (digits < target_precision) { const auto zeros_needed {target_precision - digits}; + BOOST_DECIMAL_ASSERT(zeros_needed >= 0); significand *= pow10(static_cast(zeros_needed)); exp -= zeros_needed; } else if (digits > target_precision) { - const auto excess_digits {digits - (target_precision + 1)}; - significand /= pow10(static_cast(excess_digits)); - // Perform final rounding according to the fenv rounding mode - exp += detail::fenv_round(significand, sign || significand < 0U) + excess_digits; + auto biased_exp {static_cast(exp) + detail::bias_v}; + detail::coefficient_rounding(significand, exp, biased_exp, sign, digits); } } +#if defined(__GNUC__) && __GNUC__ == 7 +# pragma GCC diagnostic pop +#endif + +// This is a branchless version of the above which is used for implementing basic operations, +// since we know that the values in the decimal type are never larger than target_precision +template +constexpr auto expand_significand(T1& significand, T2& exp) noexcept -> void +{ + constexpr auto target_precision {detail::precision_v}; + const auto digits {num_digits(significand)}; + + const auto zeros_needed {target_precision - digits}; + significand *= pow10(static_cast(zeros_needed)); + exp -= zeros_needed; +} + } //namespace detail } //namespace decimal } //namespace boost diff --git a/include/boost/decimal/detail/parser.hpp b/include/boost/decimal/detail/parser.hpp index cb4b0949e..bbeb4f8af 100644 --- a/include/boost/decimal/detail/parser.hpp +++ b/include/boost/decimal/detail/parser.hpp @@ -37,6 +37,11 @@ constexpr auto is_hex_char(char c) noexcept -> bool return is_integer_char(c) || (((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'))); } +constexpr auto is_payload_char(const char c) noexcept -> bool +{ + return is_integer_char(c) || (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))); +} + constexpr auto is_delimiter(char c, chars_format fmt) noexcept -> bool { if (fmt != chars_format::hex) @@ -68,7 +73,7 @@ constexpr auto from_chars_dispatch(const char* first, const char* last, builtin_ #if !defined(BOOST_DECIMAL_DISABLE_CLIB) template -constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_Integer& significand, Integer& exponent, chars_format fmt = chars_format::general) noexcept -> from_chars_result +constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_Integer& significand, Integer& exponent, const chars_format fmt = chars_format::general) noexcept -> from_chars_result { if (first >= last) { @@ -93,11 +98,15 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ sign = false; } + constexpr std::size_t significand_buffer_size = std::numeric_limits::digits10 ; + char significand_buffer[significand_buffer_size] {}; + // Handle non-finite values // Stl allows for string like "iNf" to return inf // // This is nested ifs rather than a big one-liner to ensure that once we hit an invalid character // or an end of buffer we return the correct value of next + bool signaling {}; if (next != last && (*next == 'i' || *next == 'I')) { ++next; @@ -106,14 +115,22 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ ++next; if (next != last && (*next == 'f' || *next == 'F')) { - significand = 0; + ++next; + exponent = 0; return {next, std::errc::value_too_large}; } } - return {next, std::errc::invalid_argument}; + return {first, std::errc::invalid_argument}; + } + + if (next != last && (*next == 's' || *next == 'S')) + { + ++next; + signaling = true; } - else if (next != last && (*next == 'n' || *next == 'N')) + + if (next != last && (*next == 'n' || *next == 'N')) { ++next; if (next != last && (*next == 'a' || *next == 'A')) @@ -122,29 +139,103 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ if (next != last && (*next == 'n' || *next == 'N')) { ++next; - if (next != last && (*next == '(')) + if (next != last) { - ++next; - if (next != last && (*next == 's' || *next == 'S')) + const auto current_pos {next}; + + bool any_valid_char {false}; + bool has_opening_brace {false}; + if (*next == '(') { - significand = 1; - return {next, std::errc::not_supported}; + ++next; + has_opening_brace = true; } - else if (next != last && (*next == 'i' || *next == 'I')) + + // Handle nan(SNAN) + if ((last - next) >= 4 && (*next == 's' || *next == 'S') && (*(next + 1) == 'n' || *(next + 1) == 'N') + && (*(next + 2) == 'a' || *(next + 2) == 'A') && (*(next + 3) == 'n' || *(next + 3) == 'N')) + { + next += 4; + signaling = true; + any_valid_char = true; + } + // Handle Nan(IND) + else if ((last - next) >= 3 && (*next == 'i' || *next == 'I') && (*(next + 1) == 'n' || *(next + 1) == 'N') + && (*(next + 2) == 'd' || *(next + 2) == 'D')) { - significand = 0; - return {next, std::errc::not_supported}; + next += 3; + sign = true; + any_valid_char = true; } + + // Arbitrary numerical payload + bool has_numerical_payload {false}; + auto significand_buffer_first {significand_buffer}; + std::size_t significand_characters {}; + while (next != last && (*next != ')')) + { + if (significand_characters < significand_buffer_size && is_integer_char(*next)) + { + ++significand_characters; + *significand_buffer_first++ = *next++; + any_valid_char = true; + has_numerical_payload = true; + } + else + { + // End of valid payload even if there are more characters + // e.g. SNAN42JUNK stops at J + break; + } + } + + // Non-numerical payload still needs to be parsed + // e.g. nan(PAYLOAD) + if (!has_numerical_payload && has_opening_brace) + { + while (next != last && (*next != ')')) + { + if (is_payload_char(*next)) + { + any_valid_char = true; + ++next; + } + else + { + break; + } + } + } + + if (next != last && any_valid_char) + { + // One past the end if we need to + ++next; + } + + if (significand_characters != 0) + { + from_chars_dispatch(significand_buffer, significand_buffer + significand_characters, significand, 10); + } + + if (!any_valid_char) + { + // If we have nan(..BAD..) we should point to ( + next = current_pos; + } + + exponent = static_cast(signaling); + return {next, std::errc::not_supported}; } else { - significand = 0; + exponent = static_cast(signaling); return {next, std::errc::not_supported}; } } } - return {next, std::errc::invalid_argument}; + return {first, std::errc::invalid_argument}; } // Ignore leading zeros (e.g. 00005 or -002.3e+5) @@ -165,8 +256,6 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ } // Next we get the significand - constexpr std::size_t significand_buffer_size = std::numeric_limits::digits10 ; - char significand_buffer[significand_buffer_size] {}; std::size_t i = 0; std::size_t dot_position = 0; Integer extra_zeros = 0; @@ -186,7 +275,7 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ if (next == last) { // if fmt is chars_format::scientific the e is required - if (fmt == chars_format::scientific) + if (fmt == chars_format::scientific || fmt == chars_format::cohort_preserving_scientific) { return {first, std::errc::invalid_argument}; } @@ -194,16 +283,13 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ exponent = 0; std::size_t offset = i; - from_chars_result r = from_chars_dispatch(significand_buffer, significand_buffer + offset, significand, base); + const from_chars_result r {from_chars_dispatch(significand_buffer, significand_buffer + offset, significand, base)}; switch (r.ec) { - // The two invalid cases are here for completeness, but I don't think we can actually hit them - // LCOV_EXCL_START case std::errc::invalid_argument: return {first, std::errc::invalid_argument}; case std::errc::result_out_of_range: return {next, std::errc::result_out_of_range}; - // LCOV_EXCL_STOP default: return {next, std::errc()}; } @@ -265,7 +351,7 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ if (next == last || is_delimiter(*next, fmt)) { - if (fmt == chars_format::scientific) + if (fmt == chars_format::scientific || fmt == chars_format::cohort_preserving_scientific) { return {first, std::errc::invalid_argument}; } @@ -280,14 +366,11 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ } std::size_t offset = i; - from_chars_result r = from_chars_dispatch(significand_buffer, significand_buffer + offset, significand, base); + const from_chars_result r {from_chars_dispatch(significand_buffer, significand_buffer + offset, significand, base)}; switch (r.ec) { - // Out of range included for completeness, but I don't think we can actually reach it - // LCOV_EXCL_START case std::errc::result_out_of_range: return {next, std::errc::result_out_of_range}; - // LCOV_EXCL_STOP case std::errc::invalid_argument: return {first, std::errc::invalid_argument}; default: @@ -329,12 +412,10 @@ constexpr auto parser(const char* first, const char* last, bool& sign, Unsigned_ from_chars_result r = from_chars_dispatch(significand_buffer, significand_buffer + offset, significand, base); switch (r.ec) { - // LCOV_EXCL_START case std::errc::invalid_argument: return {first, std::errc::invalid_argument}; case std::errc::result_out_of_range: return {next, std::errc::result_out_of_range}; - // LCOV_EXCL_STOP default: break; } diff --git a/include/boost/decimal/detail/power_tables.hpp b/include/boost/decimal/detail/power_tables.hpp index d496c642c..8317144fc 100644 --- a/include/boost/decimal/detail/power_tables.hpp +++ b/include/boost/decimal/detail/power_tables.hpp @@ -20,13 +20,13 @@ namespace detail { namespace impl { -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t powers_of_10_u32[10] = +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint32_t powers_of_10_u32[10] = { UINT32_C(1), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000), UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000), }; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t powers_of_10[20] = +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t powers_of_10[20] = { UINT64_C(1), UINT64_C(10), UINT64_C(100), UINT64_C(1000), UINT64_C(10000), UINT64_C(100000), UINT64_C(1000000), UINT64_C(10000000), UINT64_C(100000000), UINT64_C(1000000000), UINT64_C(10000000000), UINT64_C(100000000000), @@ -35,53 +35,52 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t powers_of_10[20] = UINT64_C(10000000000000000000) }; -BOOST_DECIMAL_CONSTEXPR_VARIABLE boost::int128::uint128_t BOOST_DECIMAL_DETAIL_INT128_pow10[] = +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE boost::int128::uint128_t BOOST_DECIMAL_DETAIL_INT128_pow10[39] = { - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(100000000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(1000000000000000000)}, - boost::int128::uint128_t {UINT64_C(0), UINT64_C(10000000000000000000)}, - boost::int128::uint128_t {UINT64_C(5), UINT64_C(7766279631452241920)}, - boost::int128::uint128_t {UINT64_C(54), UINT64_C(3875820019684212736)}, - boost::int128::uint128_t {UINT64_C(542), UINT64_C(1864712049423024128)}, - boost::int128::uint128_t {UINT64_C(5421), UINT64_C(200376420520689664)}, - boost::int128::uint128_t {UINT64_C(54210), UINT64_C(2003764205206896640)}, - boost::int128::uint128_t {UINT64_C(542101), UINT64_C(1590897978359414784)}, - boost::int128::uint128_t {UINT64_C(5421010), UINT64_C(15908979783594147840)}, - boost::int128::uint128_t {UINT64_C(54210108), UINT64_C(11515845246265065472)}, - boost::int128::uint128_t {UINT64_C(542101086), UINT64_C(4477988020393345024)}, - boost::int128::uint128_t {UINT64_C(5421010862), UINT64_C(7886392056514347008)}, - boost::int128::uint128_t {UINT64_C(54210108624), UINT64_C(5076944270305263616)}, - boost::int128::uint128_t {UINT64_C(542101086242), UINT64_C(13875954555633532928)}, - boost::int128::uint128_t {UINT64_C(5421010862427), UINT64_C(9632337040368467968)}, - boost::int128::uint128_t {UINT64_C(54210108624275), UINT64_C(4089650035136921600)}, - boost::int128::uint128_t {UINT64_C(542101086242752), UINT64_C(4003012203950112768)}, - boost::int128::uint128_t {UINT64_C(5421010862427522), UINT64_C(3136633892082024448)}, - boost::int128::uint128_t {UINT64_C(54210108624275221), UINT64_C(12919594847110692864)}, - boost::int128::uint128_t {UINT64_C(542101086242752217), UINT64_C(68739955140067328)}, - boost::int128::uint128_t {UINT64_C(5421010862427522170), UINT64_C(687399551400673280)}, - boost::int128::uint128_t {UINT64_C(17316620476856118468), UINT64_C(6873995514006732800)}, + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1000000000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(10000000000000000000000000000000000000), + BOOST_DECIMAL_DETAIL_INT128_UINT128_C(100000000000000000000000000000000000000) }; #ifdef BOOST_DECIMAL_HAS_INT128 -BOOST_DECIMAL_CONSTEXPR_VARIABLE detail::builtin_uint128_t builtin_128_pow10[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE detail::builtin_uint128_t builtin_128_pow10[39] = { detail::builtin_uint128_t(1), detail::builtin_uint128_t(10), detail::builtin_uint128_t(100), @@ -121,92 +120,90 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE detail::builtin_uint128_t builtin_128_pow10[] = detail::builtin_uint128_t(10000000000000000000ULL) * detail::builtin_uint128_t(100000000000000000), detail::builtin_uint128_t(10000000000000000000ULL) * detail::builtin_uint128_t(1000000000000000000), detail::builtin_uint128_t(10000000000000000000ULL) * detail::builtin_uint128_t(10000000000000000000ULL), - detail::builtin_uint128_t(10000000000000000000ULL) * detail::builtin_uint128_t(10000000000000000000ULL) * detail::builtin_uint128_t(10ULL), }; -static_assert(sizeof(builtin_128_pow10) == sizeof(boost::decimal::detail::builtin_uint128_t) * 40, "Should have 10^0 to 10^39"); - #endif -BOOST_DECIMAL_CONSTEXPR_VARIABLE u256 u256_pow_10[] = { - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(100000000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(1000000000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(0), UINT64_C(10000000000000000000)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5), UINT64_C(7766279631452241920)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54), UINT64_C(3875820019684212736)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542), UINT64_C(1864712049423024128)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421), UINT64_C(200376420520689664)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54210), UINT64_C(2003764205206896640)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542101), UINT64_C(1590897978359414784)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421010), UINT64_C(15908979783594147840)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54210108), UINT64_C(11515845246265065472)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542101086), UINT64_C(4477988020393345024)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421010862), UINT64_C(7886392056514347008)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54210108624), UINT64_C(5076944270305263616)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542101086242), UINT64_C(13875954555633532928)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421010862427), UINT64_C(9632337040368467968)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54210108624275), UINT64_C(4089650035136921600)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542101086242752), UINT64_C(4003012203950112768)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421010862427522), UINT64_C(3136633892082024448)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(54210108624275221), UINT64_C(12919594847110692864)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(542101086242752217), UINT64_C(68739955140067328)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(0)}, boost::int128::uint128_t{UINT64_C(5421010862427522170), UINT64_C(687399551400673280)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2)}, boost::int128::uint128_t{UINT64_C(17316620476856118468), UINT64_C(6873995514006732800)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29)}, boost::int128::uint128_t{UINT64_C(7145508105175220139), UINT64_C(13399722918938673152)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293)}, boost::int128::uint128_t{UINT64_C(16114848830623546549), UINT64_C(4870020673419870208)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938)}, boost::int128::uint128_t{UINT64_C(13574535716559052564), UINT64_C(11806718586779598848)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29387)}, boost::int128::uint128_t{UINT64_C(6618148649623664334), UINT64_C(7386721425538678784)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293873)}, boost::int128::uint128_t{UINT64_C(10841254275107988496), UINT64_C(80237960548581376)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938735)}, boost::int128::uint128_t{UINT64_C(16178822382532126880), UINT64_C(802379605485813760)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29387358)}, boost::int128::uint128_t{UINT64_C(14214271235644855872), UINT64_C(8023796054858137600)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293873587)}, boost::int128::uint128_t{UINT64_C(13015503840481697412), UINT64_C(6450984253743169536)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938735877)}, boost::int128::uint128_t{UINT64_C(1027829888850112811), UINT64_C(9169610316303040512)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29387358770)}, boost::int128::uint128_t{UINT64_C(10278298888501128114), UINT64_C(17909126868192198656)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293873587705)}, boost::int128::uint128_t{UINT64_C(10549268516463523069), UINT64_C(13070572018536022016)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938735877055)}, boost::int128::uint128_t{UINT64_C(13258964796087472617), UINT64_C(1578511669393358848)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29387358770557)}, boost::int128::uint128_t{UINT64_C(3462439444907864858), UINT64_C(15785116693933588480)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293873587705571)}, boost::int128::uint128_t{UINT64_C(16177650375369096972), UINT64_C(10277214349659471872)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938735877055718)}, boost::int128::uint128_t{UINT64_C(14202551164014556797), UINT64_C(10538423128046960640)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(29387358770557187)}, boost::int128::uint128_t{UINT64_C(12898303124178706663), UINT64_C(13150510911921848320)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(293873587705571876)}, boost::int128::uint128_t{UINT64_C(18302566799529756941), UINT64_C(2377900603251621888)}}, - u256{boost::int128::uint128_t{UINT64_C(0), UINT64_C(2938735877055718769)}, boost::int128::uint128_t{UINT64_C(17004971331911604867), UINT64_C(5332261958806667264)}}, - u256{boost::int128::uint128_t{UINT64_C(1), UINT64_C(10940614696847636083)}, boost::int128::uint128_t{UINT64_C(4029016655730084128), UINT64_C(16429131440647569408)}}, - u256{boost::int128::uint128_t{UINT64_C(15), UINT64_C(17172426599928602752)}, boost::int128::uint128_t{UINT64_C(3396678409881738056), UINT64_C(16717361816799281152)}}, - u256{boost::int128::uint128_t{UINT64_C(159), UINT64_C(5703569335900062977)}, boost::int128::uint128_t{UINT64_C(15520040025107828953), UINT64_C(1152921504606846976)}}, - u256{boost::int128::uint128_t{UINT64_C(1593), UINT64_C(1695461137871974930)}, boost::int128::uint128_t{UINT64_C(7626447661401876602), UINT64_C(11529215046068469760)}}, - u256{boost::int128::uint128_t{UINT64_C(15930), UINT64_C(16954611378719749304)}, boost::int128::uint128_t{UINT64_C(2477500319180559562), UINT64_C(4611686018427387904)}}, - u256{boost::int128::uint128_t{UINT64_C(159309), UINT64_C(3525417123811528497)}, boost::int128::uint128_t{UINT64_C(6328259118096044006), UINT64_C(9223372036854775808)}}, - u256{boost::int128::uint128_t{UINT64_C(1593091), UINT64_C(16807427164405733357)}, boost::int128::uint128_t{UINT64_C(7942358959831785217), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(15930919), UINT64_C(2053574980671369030)}, boost::int128::uint128_t{UINT64_C(5636613303479645706), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(159309191), UINT64_C(2089005733004138687)}, boost::int128::uint128_t{UINT64_C(1025900813667802212), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(1593091911), UINT64_C(2443313256331835254)}, boost::int128::uint128_t{UINT64_C(10259008136678022120), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(15930919111), UINT64_C(5986388489608800929)}, boost::int128::uint128_t{UINT64_C(10356360998232463120), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(159309191113), UINT64_C(4523652674959354447)}, boost::int128::uint128_t{UINT64_C(11329889613776873120), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(1593091911132), UINT64_C(8343038602174441244)}, boost::int128::uint128_t{UINT64_C(2618431695511421504), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(15930919111324), UINT64_C(9643409726906205977)}, boost::int128::uint128_t{UINT64_C(7737572881404663424), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(159309191113245), UINT64_C(4200376900514301694)}, boost::int128::uint128_t{UINT64_C(3588752519208427776), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(1593091911132452), UINT64_C(5110280857723913709)}, boost::int128::uint128_t{UINT64_C(17440781118374726144), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(15930919111324522), UINT64_C(14209320429820033867)}, boost::int128::uint128_t{UINT64_C(8387114520361296896), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(159309191113245227), UINT64_C(12965995782233477362)}, boost::int128::uint128_t{UINT64_C(10084168908774762496), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(1593091911132452277), UINT64_C(532749306367912313)}, boost::int128::uint128_t{UINT64_C(8607968719199866880), UINT64_C(0)}}, - u256{boost::int128::uint128_t{UINT64_C(15930919111324522770), UINT64_C(5327493063679123134)}, boost::int128::uint128_t{UINT64_C(12292710897160462336), UINT64_C(0)}}, +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE u256 u256_pow_10[79] = { + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(100000000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(1000000000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(0), UINT64_C(10000000000000000000)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5), UINT64_C(7766279631452241920)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54), UINT64_C(3875820019684212736)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542), UINT64_C(1864712049423024128)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421), UINT64_C(200376420520689664)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54210), UINT64_C(2003764205206896640)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542101), UINT64_C(1590897978359414784)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421010), UINT64_C(15908979783594147840)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54210108), UINT64_C(11515845246265065472)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542101086), UINT64_C(4477988020393345024)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421010862), UINT64_C(7886392056514347008)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54210108624), UINT64_C(5076944270305263616)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542101086242), UINT64_C(13875954555633532928)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421010862427), UINT64_C(9632337040368467968)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54210108624275), UINT64_C(4089650035136921600)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542101086242752), UINT64_C(4003012203950112768)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421010862427522), UINT64_C(3136633892082024448)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(54210108624275221), UINT64_C(12919594847110692864)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(542101086242752217), UINT64_C(68739955140067328)}, + u256{UINT64_C(0), UINT64_C(0), UINT64_C(5421010862427522170), UINT64_C(687399551400673280)}, + u256{UINT64_C(0), UINT64_C(2), UINT64_C(17316620476856118468), UINT64_C(6873995514006732800)}, + u256{UINT64_C(0), UINT64_C(29), UINT64_C(7145508105175220139), UINT64_C(13399722918938673152)}, + u256{UINT64_C(0), UINT64_C(293), UINT64_C(16114848830623546549), UINT64_C(4870020673419870208)}, + u256{UINT64_C(0), UINT64_C(2938), UINT64_C(13574535716559052564), UINT64_C(11806718586779598848)}, + u256{UINT64_C(0), UINT64_C(29387), UINT64_C(6618148649623664334), UINT64_C(7386721425538678784)}, + u256{UINT64_C(0), UINT64_C(293873), UINT64_C(10841254275107988496), UINT64_C(80237960548581376)}, + u256{UINT64_C(0), UINT64_C(2938735), UINT64_C(16178822382532126880), UINT64_C(802379605485813760)}, + u256{UINT64_C(0), UINT64_C(29387358), UINT64_C(14214271235644855872), UINT64_C(8023796054858137600)}, + u256{UINT64_C(0), UINT64_C(293873587), UINT64_C(13015503840481697412), UINT64_C(6450984253743169536)}, + u256{UINT64_C(0), UINT64_C(2938735877), UINT64_C(1027829888850112811), UINT64_C(9169610316303040512)}, + u256{UINT64_C(0), UINT64_C(29387358770), UINT64_C(10278298888501128114), UINT64_C(17909126868192198656)}, + u256{UINT64_C(0), UINT64_C(293873587705), UINT64_C(10549268516463523069), UINT64_C(13070572018536022016)}, + u256{UINT64_C(0), UINT64_C(2938735877055), UINT64_C(13258964796087472617), UINT64_C(1578511669393358848)}, + u256{UINT64_C(0), UINT64_C(29387358770557), UINT64_C(3462439444907864858), UINT64_C(15785116693933588480)}, + u256{UINT64_C(0), UINT64_C(293873587705571), UINT64_C(16177650375369096972), UINT64_C(10277214349659471872)}, + u256{UINT64_C(0), UINT64_C(2938735877055718), UINT64_C(14202551164014556797), UINT64_C(10538423128046960640)}, + u256{UINT64_C(0), UINT64_C(29387358770557187), UINT64_C(12898303124178706663), UINT64_C(13150510911921848320)}, + u256{UINT64_C(0), UINT64_C(293873587705571876), UINT64_C(18302566799529756941), UINT64_C(2377900603251621888)}, + u256{UINT64_C(0), UINT64_C(2938735877055718769), UINT64_C(17004971331911604867), UINT64_C(5332261958806667264)}, + u256{UINT64_C(1), UINT64_C(10940614696847636083), UINT64_C(4029016655730084128), UINT64_C(16429131440647569408)}, + u256{UINT64_C(15), UINT64_C(17172426599928602752), UINT64_C(3396678409881738056), UINT64_C(16717361816799281152)}, + u256{UINT64_C(159), UINT64_C(5703569335900062977), UINT64_C(15520040025107828953), UINT64_C(1152921504606846976)}, + u256{UINT64_C(1593), UINT64_C(1695461137871974930), UINT64_C(7626447661401876602), UINT64_C(11529215046068469760)}, + u256{UINT64_C(15930), UINT64_C(16954611378719749304), UINT64_C(2477500319180559562), UINT64_C(4611686018427387904)}, + u256{UINT64_C(159309), UINT64_C(3525417123811528497), UINT64_C(6328259118096044006), UINT64_C(9223372036854775808)}, + u256{UINT64_C(1593091), UINT64_C(16807427164405733357), UINT64_C(7942358959831785217), UINT64_C(0)}, + u256{UINT64_C(15930919), UINT64_C(2053574980671369030), UINT64_C(5636613303479645706), UINT64_C(0)}, + u256{UINT64_C(159309191), UINT64_C(2089005733004138687), UINT64_C(1025900813667802212), UINT64_C(0)}, + u256{UINT64_C(1593091911), UINT64_C(2443313256331835254), UINT64_C(10259008136678022120), UINT64_C(0)}, + u256{UINT64_C(15930919111), UINT64_C(5986388489608800929), UINT64_C(10356360998232463120), UINT64_C(0)}, + u256{UINT64_C(159309191113), UINT64_C(4523652674959354447), UINT64_C(11329889613776873120), UINT64_C(0)}, + u256{UINT64_C(1593091911132), UINT64_C(8343038602174441244), UINT64_C(2618431695511421504), UINT64_C(0)}, + u256{UINT64_C(15930919111324), UINT64_C(9643409726906205977), UINT64_C(7737572881404663424), UINT64_C(0)}, + u256{UINT64_C(159309191113245), UINT64_C(4200376900514301694), UINT64_C(3588752519208427776), UINT64_C(0)}, + u256{UINT64_C(1593091911132452), UINT64_C(5110280857723913709), UINT64_C(17440781118374726144), UINT64_C(0)}, + u256{UINT64_C(15930919111324522), UINT64_C(14209320429820033867), UINT64_C(8387114520361296896), UINT64_C(0)}, + u256{UINT64_C(159309191113245227), UINT64_C(12965995782233477362), UINT64_C(10084168908774762496), UINT64_C(0)}, + u256{UINT64_C(1593091911132452277), UINT64_C(532749306367912313), UINT64_C(8607968719199866880), UINT64_C(0)}, + u256{UINT64_C(15930919111324522770), UINT64_C(5327493063679123134), UINT64_C(12292710897160462336), UINT64_C(0)}, + u256{UINT64_C(11735238523568814774), UINT64_C(16381442489372128114), UINT64_C(12246644529347313664), UINT64_C(0)}, }; } // namespace impl @@ -240,7 +237,12 @@ constexpr auto pow10(detail::builtin_uint128_t n) noexcept -> detail::builtin_ui constexpr auto pow10(const u256& n) noexcept -> u256 { - return impl::u256_pow_10[n[3]]; + return impl::u256_pow_10[static_cast(n)]; +} + +constexpr auto pow10_256(const std::size_t n) noexcept -> u256 +{ + return impl::u256_pow_10[n]; } #if defined(__GNUC__) && __GNUC__ >= 7 diff --git a/include/boost/decimal/detail/promotion.hpp b/include/boost/decimal/detail/promotion.hpp index 4dfcbaf86..e9e658b3e 100644 --- a/include/boost/decimal/detail/promotion.hpp +++ b/include/boost/decimal/detail/promotion.hpp @@ -7,6 +7,7 @@ #include #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -33,6 +34,12 @@ struct decimal_val static constexpr int value = 32; }; +template <> +struct decimal_val +{ + static constexpr int value = 32; +}; + // Assign a higher value to the fast type for consistency of promotion // Side effect is the same calculation will be faster with the same precision template <> @@ -47,6 +54,12 @@ struct decimal_val static constexpr int value = 64; }; +template <> +struct decimal_val +{ + static constexpr int value = 64; +}; + template <> struct decimal_val { @@ -59,6 +72,12 @@ struct decimal_val static constexpr int value = 128; }; +template <> +struct decimal_val +{ + static constexpr int value = 128; +}; + template <> struct decimal_val { @@ -100,8 +119,6 @@ struct promote_2_args template using promote_2_args_t = typename promote_2_args::type; -} //namespace impl - // Promote N args using the rules of promote_2_args template struct promote_args; @@ -109,17 +126,36 @@ struct promote_args; template struct promote_args { - using type = impl::promote_arg_t; + using type = promote_arg_t; }; template struct promote_args { - using type = impl::promote_2_args_t, typename promote_args::type>; + using type = promote_2_args_t, typename promote_args::type>; }; +} //namespace impl + template -using promote_args_t = typename promote_args::type; +using promote_args_t = typename impl::promote_args::type; + +#if BOOST_DECIMAL_DEC_EVAL_METHOD == 0 + +template +using evaluation_type_t = T; + +#elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1 + +template +using evaluation_type_t = detail::promote_args_t; + +#else + +template +using evaluation_type_t = detail::promote_args_t; + +#endif } //namespace detail } //namespace decimal diff --git a/include/boost/decimal/detail/remove_trailing_zeros.hpp b/include/boost/decimal/detail/remove_trailing_zeros.hpp index a9df54b36..66e71d357 100644 --- a/include/boost/decimal/detail/remove_trailing_zeros.hpp +++ b/include/boost/decimal/detail/remove_trailing_zeros.hpp @@ -29,6 +29,12 @@ constexpr auto rotr(UInt n, unsigned int r) noexcept return (n >> r) | (n << ((bit_width - r) & (bit_width - 1))); } +// For internal use only and changes based on the type of T +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + template struct remove_trailing_zeros_return { @@ -36,6 +42,10 @@ struct remove_trailing_zeros_return std::size_t number_of_removed_zeros; }; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + constexpr auto remove_trailing_zeros(std::uint32_t n) noexcept -> remove_trailing_zeros_return { std::size_t s {}; @@ -132,6 +142,49 @@ constexpr auto remove_trailing_zeros(boost::int128::uint128_t n) noexcept -> rem return {n, s}; } +#ifdef BOOST_DECIMAL_DETAIL_INT128_HAS_INT128 + +constexpr auto remove_trailing_zeros(boost::int128::detail::builtin_u128 n) noexcept -> remove_trailing_zeros_return +{ + using u128 = boost::int128::detail::builtin_u128; + + std::size_t s {}; + + auto r = rotr<128>(n * static_cast(boost::int128::uint128_t(UINT64_C(0x62B42691AD836EB1), UINT64_C(0x16590F420A835081))), 32); + auto b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x0), UINT64_C(0x33EC48)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + r = rotr<128>(n * static_cast(boost::int128::uint128_t{UINT64_C(0x3275305C1066), UINT64_C(0xE4A4D1417CD9A041)}), 16); + b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x734), UINT64_C(0xACA5F6226F0ADA62)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + r = rotr<128>(n * static_cast(boost::int128::uint128_t {UINT64_C(0x6B7213EE9F5A78), UINT64_C(0xC767074B22E90E21)}), 8); + b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x2AF31DC461), UINT64_C(0x1873BF3F70834ACE)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + r = rotr<128>(n * static_cast(boost::int128::uint128_t {UINT64_C(0x95182A9930BE0DE), UINT64_C(0xD288CE703AFB7E91)}), 4); + b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x68DB8BAC710CB), UINT64_C(0x295E9E1B089A0276)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + r = rotr<128>(n * static_cast(boost::int128::uint128_t {UINT64_C(0x28F5C28F5C28F5C2), UINT64_C(0x8F5C28F5C28F5C29)}), 2); + b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x28F5C28F5C28F5C), UINT64_C(0x28F5C28F5C28F5C3)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + r = rotr<128>(n * static_cast(boost::int128::uint128_t {UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xCCCCCCCCCCCCCCCD)}), 1); + b = r < static_cast(boost::int128::uint128_t {UINT64_C(0x1999999999999999), UINT64_C(0x999999999999999A)}); + s = s * 2U + static_cast(b); + n = b ? r : n; + + return {n, s}; +} + +#endif + } // namespace detail } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/ryu/generic_128.hpp b/include/boost/decimal/detail/ryu/generic_128.hpp index 5e396f0d4..0253c83e0 100644 --- a/include/boost/decimal/detail/ryu/generic_128.hpp +++ b/include/boost/decimal/detail/ryu/generic_128.hpp @@ -30,7 +30,7 @@ using unsigned_128_type = boost::int128::uint128_t; // There's no way to define 128-bit constants in C, so we use little-endian // pairs of 64-bit constants. -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_TABLE[BOOST_DECIMAL_POW5_TABLE_SIZE][2] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_TABLE[BOOST_DECIMAL_POW5_TABLE_SIZE][2] = { { UINT64_C( 1), UINT64_C( 0) }, { UINT64_C( 5), UINT64_C( 0) }, { UINT64_C( 25), UINT64_C( 0) }, @@ -89,7 +89,7 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_TABLE[BOOST_DECIMAL_ { UINT64_C(18443565265187884909), UINT64_C(15046327690525280101) } }; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_SPLIT[89][4] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_SPLIT[89][4] = { { UINT64_C( 0), UINT64_C( 0), UINT64_C( 0), UINT64_C( 72057594037927936) }, { UINT64_C( 0), UINT64_C( 5206161169240293376), UINT64_C( 4575641699882439235), UINT64_C( 73468396926392969) }, { UINT64_C( 3360510775605221349), UINT64_C( 6983200512169538081), UINT64_C( 4325643253124434363), UINT64_C( 74906821675075173) }, @@ -183,7 +183,7 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_SPLIT[89][4] = { // Unfortunately, the results are sometimes off by one or two. We use an additional // lookup table to store those cases and adjust the result. -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t POW5_ERRORS[156] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t POW5_ERRORS[156] = { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), UINT64_C(0x9555596400000000), UINT64_C(0x65a6569525565555), UINT64_C(0x4415551445449655), UINT64_C(0x5105015504144541), UINT64_C(0x65a69969a6965964), UINT64_C(0x5054955969959656), UINT64_C(0x5105154515554145), UINT64_C(0x4055511051591555), UINT64_C(0x5500514455550115), @@ -225,7 +225,7 @@ UINT64_C(0x5554655255559545), UINT64_C(0x9555455441155556), UINT64_C(0x000000005 UINT64_C(0x5044044040000000), UINT64_C(0x1045040440010500), UINT64_C(0x0000400000040000), UINT64_C(0x0000000000000000) }; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_INV_SPLIT[89][4] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_INV_SPLIT[89][4] = { { UINT64_C( 0), UINT64_C( 0), UINT64_C( 0), UINT64_C(144115188075855872) }, { UINT64_C( 1573859546583440065), UINT64_C( 2691002611772552616), UINT64_C( 6763753280790178510), UINT64_C(141347765182270746) }, { UINT64_C(12960290449513840412), UINT64_C(12345512957918226762), UINT64_C(18057899791198622765), UINT64_C(138633484706040742) }, @@ -317,7 +317,7 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t GENERIC_POW5_INV_SPLIT[89][4] = { { UINT64_C( 7184427196661305643), UINT64_C(14332510582433188173), UINT64_C(14230167953789677901), UINT64_C(104649889046128358) } }; -BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint64_t POW5_INV_ERRORS[154] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE std::uint64_t POW5_INV_ERRORS[154] = { UINT64_C(0x1144155514145504), UINT64_C(0x0000541555401141), UINT64_C(0x0000000000000000), UINT64_C(0x0154454000000000), UINT64_C(0x4114105515544440), UINT64_C(0x0001001111500415), UINT64_C(0x4041411410011000), UINT64_C(0x5550114515155014), UINT64_C(0x1404100041554551), UINT64_C(0x0515000450404410), UINT64_C(0x5054544401140004), UINT64_C(0x5155501005555105), diff --git a/include/boost/decimal/detail/ryu/ryu_generic_128.hpp b/include/boost/decimal/detail/ryu/ryu_generic_128.hpp index b3a7a3b8a..1e1cefa93 100644 --- a/include/boost/decimal/detail/ryu/ryu_generic_128.hpp +++ b/include/boost/decimal/detail/ryu/ryu_generic_128.hpp @@ -28,8 +28,19 @@ namespace decimal { namespace detail { namespace ryu { -BOOST_DECIMAL_CONSTEXPR_VARIABLE int32_t fd128_exceptional_exponent = 0x7FFFFFFF; -BOOST_DECIMAL_CONSTEXPR_VARIABLE unsigned_128_type one = 1; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE int32_t fd128_exceptional_exponent = 0x7FFFFFFF; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE unsigned_128_type one = 1; + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) // Structure was padded due to alignment specifier +#endif + +// Internal use only +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif struct floating_decimal_128 { @@ -38,6 +49,14 @@ struct floating_decimal_128 bool sign; }; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + #ifdef BOOST_DECIMAL_DEBUG_RYU static char* s(unsigned_128_type v) { int len = num_digits(v); @@ -90,9 +109,9 @@ inline constexpr auto generic_binary_to_decimal( if (explicitLeadingBit) { // mantissaBits includes the explicit leading bit, so we need to correct for that here. - if (ieeeExponent == 0) + if (BOOST_DECIMAL_UNLIKELY(ieeeExponent == 0)) { - e2 = static_cast(1 - local_bias - mantissaBits + 1 - 2); + e2 = static_cast(1 - local_bias - mantissaBits + 1 - 2); // LCOV_EXCL_LINE } else { @@ -102,10 +121,10 @@ inline constexpr auto generic_binary_to_decimal( } else { - if (ieeeExponent == 0) + if (BOOST_DECIMAL_UNLIKELY(ieeeExponent == 0)) { - e2 = static_cast(1 - local_bias - mantissaBits - 2); - m2 = ieeeMantissa; + e2 = static_cast(1 - local_bias - mantissaBits - 2); // LCOV_EXCL_LINE + m2 = ieeeMantissa; // LCOV_EXCL_LINE } else { e2 = static_cast(ieeeExponent - local_bias - mantissaBits - 2U); @@ -346,6 +365,17 @@ BOOST_DECIMAL_CXX20_CONSTEXPR auto floating_point_to_fd128(long dou return generic_binary_to_decimal(bits, 112, 15, false); } +#elif BOOST_DECIMAL_LDBL_BITS == 0 + +template <> +BOOST_DECIMAL_CXX20_CONSTEXPR auto floating_point_to_fd128(long double val) noexcept -> floating_decimal_128 +{ + BOOST_DECIMAL_ASSERT_MSG(1==0, "Unsupported configuration"); + + auto bits = bit_cast(val); + return generic_binary_to_decimal(bits, 112, 15, false); +} + #endif #if defined(BOOST_DECIMAL_HAS_FLOAT128) && !defined(BOOST_DECIMAL_LDBL_IS_FLOAT128) diff --git a/include/boost/decimal/detail/sub_impl.hpp b/include/boost/decimal/detail/sub_impl.hpp deleted file mode 100644 index e3bc61ca6..000000000 --- a/include/boost/decimal/detail/sub_impl.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2023 - 2024 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_DETAIL_SUB_IMPL_HPP -#define BOOST_DECIMAL_DETAIL_SUB_IMPL_HPP - -#include -#include -#include -#include "int128.hpp" - -#ifndef BOOST_DECIMAL_BUILD_MODULE -#include -#endif - -namespace boost { -namespace decimal { -namespace detail { - -template -constexpr auto d128_sub_impl(T lhs_sig, U lhs_exp, bool lhs_sign, - T rhs_sig, U rhs_exp, bool rhs_sign, - bool abs_lhs_bigger) noexcept -> ReturnType -{ - auto delta_exp {lhs_exp > rhs_exp ? lhs_exp - rhs_exp : rhs_exp - lhs_exp}; - - if (delta_exp > detail::precision_v + 1) - { - // If the difference in exponents is more than the digits of accuracy - // we return the larger of the two - // - // e.g. 1e20 - 1e-20 = 1e20 - return abs_lhs_bigger ? ReturnType{lhs_sig, lhs_exp, lhs_sign} : - ReturnType{rhs_sig, rhs_exp, !rhs_sign}; - } - - // The two numbers can be subtracted together without special handling - - auto& sig_bigger {abs_lhs_bigger ? lhs_sig : rhs_sig}; - auto& exp_bigger {abs_lhs_bigger ? lhs_exp : rhs_exp}; - auto& sig_smaller {abs_lhs_bigger ? rhs_sig : lhs_sig}; - auto& smaller_sign {abs_lhs_bigger ? rhs_sign : lhs_sign}; - - if (delta_exp == 1) - { - sig_bigger *= 10U; - --delta_exp; - --exp_bigger; - } - else - { - if (delta_exp >= 2) - { - sig_bigger *= 100U; - delta_exp -= 2; - exp_bigger -= 2; - } - - if (delta_exp > 1) - { - sig_smaller /= pow10>(delta_exp - 1); - delta_exp = 1; - } - - if (delta_exp == 1) - { - detail::fenv_round(sig_smaller, smaller_sign); - } - } - - const auto signed_sig_lhs {detail::make_signed_value(lhs_sig, lhs_sign)}; - const auto signed_sig_rhs {detail::make_signed_value(rhs_sig, rhs_sign)}; - - const auto new_sig {signed_sig_lhs - signed_sig_rhs}; - - const auto new_exp {abs_lhs_bigger ? lhs_exp : rhs_exp}; - const auto new_sign {new_sig < 0}; - const auto res_sig {detail::make_positive_unsigned(new_sig)}; - - return {T{res_sig.high, res_sig.low}, new_exp, new_sign}; -} - -} // namespace detail -} // namespace decimal -} // namespace boost - -#endif //BOOST_DECIMAL_DETAIL_SUB_IMPL_HPP diff --git a/include/boost/decimal/detail/to_chars_integer_impl.hpp b/include/boost/decimal/detail/to_chars_integer_impl.hpp index 2feedf043..adc66550b 100644 --- a/include/boost/decimal/detail/to_chars_integer_impl.hpp +++ b/include/boost/decimal/detail/to_chars_integer_impl.hpp @@ -31,7 +31,7 @@ namespace boost { namespace decimal { namespace detail { -BOOST_DECIMAL_CONSTEXPR_VARIABLE char digit_table[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE char digit_table[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', @@ -45,22 +45,11 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE char digit_table[] = { // Use a simple lookup table to put together the Integer in character form template -BOOST_DECIMAL_CONSTEXPR auto to_chars_integer_impl(char* first, char* last, Integer value, int base) noexcept +constexpr auto to_chars_integer_impl(char* first, char* last, Integer value, int) noexcept BOOST_DECIMAL_REQUIRES_TWO_RETURN(detail::is_integral_v, Integer, detail::is_integral_v, Unsigned_Integer, to_chars_result) { const std::ptrdiff_t output_length = last - first; - if (!((first <= last) && (base >= 2 && base <= 36))) - { - return {last, std::errc::invalid_argument}; - } - - if (value == 0U) - { - *first++ = '0'; - return {first, std::errc()}; - } - Unsigned_Integer unsigned_value {}; BOOST_DECIMAL_IF_CONSTEXPR (std::is_signed::value) @@ -106,7 +95,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_integer_impl(char* first, char* last, Inte // Specialization for base-10 -BOOST_DECIMAL_CONSTEXPR_VARIABLE char radix_table[] = { +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE char radix_table[] = { '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', @@ -138,7 +127,7 @@ constexpr char* decompose32(std::uint32_t value, char* buffer) noexcept for (std::size_t i {}; i < 10; i += 2) { - boost::decimal::detail::memcpy(buffer + i, radix_table + static_cast(y >> 57) * 2, 2); + boost::decimal::detail::memcpy(buffer + i, radix_table + (y >> 57) * 2, 2); y &= mask; y *= 100U; } @@ -161,11 +150,6 @@ constexpr to_chars_result to_chars_integer_impl(char* first, char* last, Integer int converted_value_digits {}; bool is_negative = false; - if (first > last) - { - return {last, std::errc::invalid_argument}; - } - // Strip the sign from the value and apply at the end after parsing if the type is signed BOOST_DECIMAL_IF_CONSTEXPR (is_signed_v) { @@ -289,11 +273,6 @@ constexpr to_chars_result to_chars_integer_impl(char* first, char* last, Integer const std::ptrdiff_t user_buffer_size = last - first; BOOST_DECIMAL_ATTRIBUTE_UNUSED bool is_negative = false; - if (first > last) - { - return {last, std::errc::invalid_argument}; - } - // Strip the sign from the value and apply at the end after parsing if the type is signed BOOST_DECIMAL_IF_CONSTEXPR (std::numeric_limits::is_signed #ifdef BOOST_DECIMAL_HAS_INT128 @@ -316,7 +295,7 @@ constexpr to_chars_result to_chars_integer_impl(char* first, char* last, Integer unsigned_value = static_cast(value); } - auto converted_value = static_cast(unsigned_value); + auto converted_value = unsigned_value; const int converted_value_digits = num_digits(converted_value); @@ -343,7 +322,7 @@ constexpr to_chars_result to_chars_integer_impl(char* first, char* last, Integer while (converted_value != 0U) { - auto digits = static_cast(converted_value % ten_9); + const auto digits = static_cast(converted_value % ten_9); num_chars[i] = num_digits(digits); decompose32(digits, buffer[i]); // Always returns 10 digits (to include leading 0s) which we want converted_value = (converted_value - digits) / ten_9; @@ -372,8 +351,8 @@ constexpr to_chars_result to_chars_integer_impl(char* first, char* last, Integer #pragma GCC diagnostic pop #endif -} -} -} +} // namespace detail +} // namespace decimal +} // namespace boost #endif //BOOST_TO_CHARS_INTEGER_IMPL_HPP diff --git a/include/boost/decimal/detail/to_chars_result.hpp b/include/boost/decimal/detail/to_chars_result.hpp index 955a9dfed..7c43a0e73 100644 --- a/include/boost/decimal/detail/to_chars_result.hpp +++ b/include/boost/decimal/detail/to_chars_result.hpp @@ -16,6 +16,12 @@ namespace boost { namespace decimal { +// This is how the STL says to implement +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif + BOOST_DECIMAL_EXPORT struct to_chars_result { char *ptr; @@ -34,6 +40,10 @@ BOOST_DECIMAL_EXPORT struct to_chars_result constexpr explicit operator bool() const noexcept { return ec == std::errc{}; } }; +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/detail/to_float.hpp b/include/boost/decimal/detail/to_float.hpp index a73412623..7a2bff654 100644 --- a/include/boost/decimal/detail/to_float.hpp +++ b/include/boost/decimal/detail/to_float.hpp @@ -94,10 +94,8 @@ BOOST_DECIMAL_CXX20_CONSTEXPR auto to_float(Decimal val) noexcept if (BOOST_DECIMAL_UNLIKELY(!success)) { - // LCOV_EXCL_START errno = EINVAL; return 0; - // LCOV_EXCL_STOP } return result; diff --git a/include/boost/decimal/detail/type_traits.hpp b/include/boost/decimal/detail/type_traits.hpp index 025016f48..8d5d920b8 100644 --- a/include/boost/decimal/detail/type_traits.hpp +++ b/include/boost/decimal/detail/type_traits.hpp @@ -8,6 +8,7 @@ // Extends the current type traits to include our types and __int128s #include #include +#include #include "int128.hpp" #ifndef BOOST_DECIMAL_BUILD_MODULE @@ -37,6 +38,9 @@ struct is_signed { static constexpr bool value = false;}; #endif +template <> +struct is_signed { static constexpr bool value = false; }; + template constexpr bool is_signed::value; @@ -112,6 +116,9 @@ struct is_integral { static constexpr bool value = true; }; #endif +template <> +struct is_integral { static constexpr bool value = true; }; + template constexpr bool is_integral::value; @@ -197,7 +204,7 @@ struct conjunction : std::conditional_t(B1::value), conjunction, B1> {}; template -BOOST_DECIMAL_CONSTEXPR_VARIABLE bool conjunction_v = conjunction::value; +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE bool conjunction_v = conjunction::value; } // namespace detail } // namespace decimal diff --git a/include/boost/decimal/detail/u256.hpp b/include/boost/decimal/detail/u256.hpp index 291d19dcf..0dac46b42 100644 --- a/include/boost/decimal/detail/u256.hpp +++ b/include/boost/decimal/detail/u256.hpp @@ -33,7 +33,8 @@ u256 constexpr u256& operator=(u256&& other) noexcept = default; constexpr u256(std::uint64_t byte3, std::uint64_t byte2, std::uint64_t byte1, std::uint64_t byte0) noexcept; - constexpr u256(std::uint64_t x) { bytes[0] = x; } + constexpr u256(const int128::uint128_t x) noexcept { bytes[0] = x.low; bytes[1] = x.high; } + constexpr u256(const std::uint64_t x) noexcept { bytes[0] = x; } explicit constexpr operator std::uint64_t() const noexcept { return bytes[0]; } @@ -56,12 +57,17 @@ u256 constexpr u256& operator>>=(int amount) noexcept; constexpr u256& operator|=(const u256& rhs) noexcept; + constexpr u256& operator*=(const u256& rhs) noexcept; + constexpr u256& operator/=(const u256& rhs) noexcept; constexpr u256& operator/=(const int128::uint128_t& rhs) noexcept; constexpr u256& operator/=(std::uint64_t rhs) noexcept; constexpr u256& operator%=(const u256& rhs) noexcept; constexpr u256& operator%=(std::uint64_t rhs) noexcept; + + constexpr u256& operator++() noexcept; + constexpr u256& operator++(int) noexcept; }; } // namespace detail @@ -260,6 +266,16 @@ constexpr bool operator<(const u256& lhs, const u256& rhs) noexcept #endif +constexpr bool operator<(const u256& lhs, const int128::uint128_t& rhs) noexcept +{ + return lhs[3] == 0U && lhs[2] == 0U && int128::uint128_t{lhs[1], lhs[0]} < rhs; +} + +constexpr bool operator<(const int128::uint128_t& lhs, const u256& rhs) noexcept +{ + return rhs[3] == 0U && rhs[2] == 0U && lhs < int128::uint128_t{rhs[1], rhs[0]}; +} + constexpr bool operator<(const u256& lhs, const std::uint64_t rhs) noexcept { return lhs[3] == 0 && lhs[2] == 0 && lhs[1] == 0 && lhs[0] < rhs; @@ -352,6 +368,16 @@ constexpr bool operator>(const u256& lhs, const u256& rhs) noexcept return rhs < lhs; } +constexpr bool operator>(const u256& lhs, const int128::uint128_t& rhs) noexcept +{ + return lhs[3] > 0U || lhs[2] > 0U || int128::uint128_t{lhs[1], lhs[0]} > rhs; +} + +constexpr bool operator>(const u256& lhs, const std::uint64_t rhs) noexcept +{ + return lhs[3] != 0U || lhs[2] != 0U || lhs[1] != 0U || lhs[0] > rhs; +} + //===================================== // Greater Equal Operator //===================================== @@ -727,6 +753,19 @@ constexpr u256 operator+(const u256& lhs, const u256& rhs) noexcept #endif +constexpr u256& u256::operator++() noexcept +{ + *this = *this + static_cast(1); + return *this; +} + +constexpr u256& u256::operator++(int) noexcept +{ + *this = *this + static_cast(1); + return *this; +} + + //===================================== // Multiplication Operators //===================================== @@ -884,6 +923,12 @@ constexpr u256 umul256(const int128::uint128_t& a, const int128::uint128_t& b) n return result; } +constexpr u256& u256::operator*=(const u256& rhs) noexcept +{ + *this = *this * rhs; + return *this; +} + //===================================== // Division Operators //===================================== @@ -935,7 +980,7 @@ constexpr std::size_t div_to_words(const boost::int128::uint128_t& x, std::uint3 words[3] = static_cast(static_cast(x.high) >> 32); // LCOV_EXCL_LINE } - BOOST_DECIMAL_DETAIL_INT128_ASSERT_MSG(x != 0U, "Division by 0"); + BOOST_DECIMAL_DETAIL_INT128_ASSERT_MSG(x != 0U, "Division by 0"); // LCOV_EXCL_LINE : False Negative std::size_t word_count {4}; while (words[word_count - 1U] == 0U) @@ -1019,6 +1064,47 @@ BOOST_DECIMAL_FORCE_INLINE constexpr u256 default_div(const u256& lhs, const Uns return from_words(q); } +struct u256_divmod_result +{ + u256 quotient; + u256 remainder; +}; + +template +BOOST_DECIMAL_FORCE_INLINE constexpr auto div_mod(const u256& lhs, const UnsignedInteger& rhs) noexcept -> u256_divmod_result +{ + std::uint32_t u[8] {}; + std::uint32_t v[8] {}; + std::uint32_t q[8] {}; + + const auto m {div_to_words(lhs, u)}; + const auto n {div_to_words(rhs, v)}; + + BOOST_DECIMAL_DETAIL_INT128_ASSERT(m >= n); + + // Simplify handling of single word division + // We run into this case with dividing by powers of 10 while rounding u256 + if (n == 1U) + { + std::uint64_t remainder {}; + + for (std::size_t j = m; j-- > 0;) + { + const auto dividend {(remainder << 32) | u[j]}; + q[j] = static_cast(dividend / v[0]); + remainder = dividend % v[0]; + } + + u[0] = static_cast(remainder); + } + else + { + int128::detail::impl::knuth_divide(u, m, v, n, q); + } + + return {from_words(q), from_words(u)}; +} + } // namespace impl constexpr u256 operator/(const u256& lhs, const u256& rhs) noexcept diff --git a/include/boost/decimal/detail/utilities.hpp b/include/boost/decimal/detail/utilities.hpp index 9a362e38f..154d1d77c 100644 --- a/include/boost/decimal/detail/utilities.hpp +++ b/include/boost/decimal/detail/utilities.hpp @@ -27,6 +27,12 @@ template constexpr auto strlen(const T* str) noexcept -> std::size_t { std::size_t i {}; + + if (str == nullptr) + { + return i; + } + while (*str != '\0') { ++str; diff --git a/include/boost/decimal/detail/write_payload.hpp b/include/boost/decimal/detail/write_payload.hpp new file mode 100644 index 000000000..e71f6b439 --- /dev/null +++ b/include/boost/decimal/detail/write_payload.hpp @@ -0,0 +1,71 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_DETAIL_WRITE_PAYLOAD_HPP +#define BOOST_DECIMAL_DETAIL_WRITE_PAYLOAD_HPP + +#include +#include +#include + +namespace boost { +namespace decimal { + +constexpr auto from_bits(const std::uint32_t rhs) noexcept -> decimal32_t; +constexpr auto from_bits(const std::uint64_t rhs) noexcept -> decimal64_t; +constexpr auto from_bits(const int128::uint128_t rhs) noexcept -> decimal128_t; + +namespace detail { + +template +constexpr auto write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_fast_type_v, TargetDecimalType) +{ + using sig_type = typename TargetDecimalType::significand_type; + + constexpr TargetDecimalType nan_type {is_snan ? std::numeric_limits::signaling_NaN() : + std::numeric_limits::quiet_NaN()}; + + constexpr std::uint32_t significand_field_bits {decimal_val_v < 64 ? 23U : + decimal_val_v < 128 ? 53U : 110U}; + + constexpr sig_type max_payload_value {(static_cast(1) << significand_field_bits) - 1U}; + + TargetDecimalType return_value {nan_type}; + if (payload_value < max_payload_value) + { + return_value.significand_ |= payload_value; + } + + return return_value; +} + +template +constexpr auto write_payload(typename TargetDecimalType::significand_type payload_value) + BOOST_DECIMAL_REQUIRES(detail::is_ieee_type_v, TargetDecimalType) +{ + using sig_type = typename TargetDecimalType::significand_type; + + constexpr TargetDecimalType nan_type {is_snan ? std::numeric_limits::signaling_NaN() : + std::numeric_limits::quiet_NaN()}; + + constexpr std::uint32_t significand_field_bits {decimal_val_v < 64 ? 23U : + decimal_val_v < 128 ? 53U : 110U}; + + constexpr sig_type max_payload_value {(static_cast(1) << significand_field_bits) - 1U}; + + auto return_value {nan_type.bits_}; + if (payload_value < max_payload_value) + { + return_value = payload_value | return_value; + } + + return from_bits(return_value); +} + +} // namespace detail +} // namespace decimal +} // namespace boost + +#endif // BOOST_DECIMAL_DETAIL_WRITE_PAYLOAD_HPP diff --git a/include/boost/decimal/dpd_conversion.hpp b/include/boost/decimal/dpd_conversion.hpp index 94b3d6011..6a4c58761 100644 --- a/include/boost/decimal/dpd_conversion.hpp +++ b/include/boost/decimal/dpd_conversion.hpp @@ -14,7 +14,7 @@ #include #include #include -#include "detail/int128.hpp" +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -435,30 +435,34 @@ constexpr auto from_dpd_d32(const std::uint32_t dpd) noexcept static_assert(std::is_same::value || std::is_same::value, "Target decimal type must be 32-bits"); + const auto sign {(dpd & detail::d32_sign_mask) != 0}; + // First we check for non-finite values // Since they are in the same initial format as BID it's easy to check with our existing masks if ((dpd & detail::d32_inf_mask) == detail::d32_inf_mask) { if ((dpd & detail::d32_snan_mask) == detail::d32_snan_mask) { - return std::numeric_limits::signaling_NaN(); + return sign ? -std::numeric_limits::signaling_NaN() : + std::numeric_limits::signaling_NaN(); } else if ((dpd & detail::d32_nan_mask) == detail::d32_nan_mask) { - return std::numeric_limits::quiet_NaN(); + return sign ? -std::numeric_limits::quiet_NaN() : + std::numeric_limits::quiet_NaN(); } else { - return std::numeric_limits::infinity(); + return sign ? -std::numeric_limits::infinity() : + std::numeric_limits::infinity(); } } - constexpr std::uint32_t dpd_d32_exponent_mask {UINT32_C(0b0'00000'111111'0000000000'0000000000)}; - constexpr std::uint32_t dpd_d32_significand_mask {UINT32_C(0b0'00000'000000'1111111111'1111111111)}; - constexpr std::uint32_t dpd_d32_combination_mask {UINT32_C(0b0'11111'000000'0000000000'0000000000)}; + constexpr std::uint32_t dpd_d32_exponent_mask {UINT32_C(0x3F00000)}; + constexpr std::uint32_t dpd_d32_significand_mask {UINT32_C(0xFFFFF)}; + constexpr std::uint32_t dpd_d32_combination_mask {UINT32_C(0x7C000000)}; // The bit lengths are the same as used in the standard bid format - const auto sign {(dpd & detail::d32_sign_mask) != 0}; const auto combination_field_bits {(dpd & dpd_d32_combination_mask) >> 26U}; const auto exponent_field_bits {(dpd & dpd_d32_exponent_mask) >> 20U}; const auto significand_bits {(dpd & dpd_d32_significand_mask)}; @@ -501,10 +505,11 @@ constexpr auto from_dpd_d32(const std::uint32_t dpd) noexcept // We can now decode the remainder of the significand to recover the value std::uint8_t digits[7] {}; digits[0] = static_cast(d0); - const auto significand_low {significand_bits & 0b1111111111}; + constexpr std::uint32_t seven_digits_mask {UINT32_C(0x3FF)}; + const auto significand_low {significand_bits & seven_digits_mask}; detail::decode_dpd(significand_low, digits[6], digits[5], digits[4]); - const auto significand_high {(significand_bits & 0b11111111110000000000) >> 10U}; - BOOST_DECIMAL_ASSERT(significand_high <= 0b1111111111); + const auto significand_high {(significand_bits & UINT32_C(0xFFC00)) >> 10U}; + BOOST_DECIMAL_ASSERT(significand_high <= seven_digits_mask); detail::decode_dpd(significand_high, digits[3], digits[2], digits[1]); // Now we can assemble the significand @@ -635,31 +640,35 @@ constexpr auto from_dpd_d64(const std::uint64_t dpd) noexcept static_assert(std::is_same::value || std::is_same::value, "Target decimal type must be 64-bits"); + const auto sign {(dpd & detail::d64_sign_mask) != 0}; + // First we check for non-finite values // Since they are in the same initial format as BID it's easy to check with our existing masks if ((dpd & detail::d64_inf_mask) == detail::d64_inf_mask) { if ((dpd & detail::d64_snan_mask) == detail::d64_snan_mask) { - return std::numeric_limits::signaling_NaN(); + return sign ? -std::numeric_limits::signaling_NaN() : + std::numeric_limits::signaling_NaN(); } else if ((dpd & detail::d64_nan_mask) == detail::d64_nan_mask) { - return std::numeric_limits::quiet_NaN(); + return sign ? -std::numeric_limits::quiet_NaN() : + std::numeric_limits::quiet_NaN(); } else { - return std::numeric_limits::infinity(); + return sign ? -std::numeric_limits::infinity() : + std::numeric_limits::infinity(); } } // The bit lengths are the same as used in the standard bid format - constexpr std::uint64_t dpd_d64_combination_field_mask {UINT64_C(0b0'11111'00000000'0000000000'0000000000'0000000000'0000000000'0000000000)}; - constexpr std::uint64_t dpd_d64_exponent_field_mask {UINT64_C(0b0'00000'11111111'0000000000'0000000000'0000000000'0000000000'0000000000)}; - constexpr std::uint64_t dpd_d64_significand_field_mask {UINT64_C(0b0'00000'00000000'1111111111'1111111111'1111111111'1111111111'1111111111)}; + constexpr std::uint64_t dpd_d64_combination_field_mask {UINT64_C(0x7C00000000000000)}; + constexpr std::uint64_t dpd_d64_exponent_field_mask {UINT64_C(0x3FC000000000000)}; + constexpr std::uint64_t dpd_d64_significand_field_mask {UINT64_C(0x3FFFFFFFFFFFF)}; - const auto sign {(dpd & detail::d64_sign_mask) != 0}; const auto combination_field_bits {(dpd & dpd_d64_combination_field_mask) >> 58U}; const auto exponent_field_bits {(dpd & dpd_d64_exponent_field_mask) >> 50U}; auto significand_bits {(dpd & dpd_d64_significand_field_mask)}; @@ -704,7 +713,8 @@ constexpr auto from_dpd_d64(const std::uint64_t dpd) noexcept digits[0] = static_cast(d0); for (int i = 15; i > 0; i -= 3) { - const auto declet_bits {static_cast(significand_bits & 0b1111111111)}; + constexpr std::uint32_t declet_mask {UINT32_C(0x3FF)}; + const auto declet_bits {static_cast(significand_bits & declet_mask)}; significand_bits >>= 10U; detail::decode_dpd(declet_bits, digits[i], digits[i - 1], digits[i - 2]); } @@ -770,6 +780,9 @@ constexpr auto to_dpd_d128(const DecimalType val) noexcept const auto d0_is_nine {d[0] == 9}; switch (leading_two_bits) { + // The decimal128_t case never uses the combination field like the other types, + // since the significand always fits inside the allotted number of bits. + // I don't believe this path will ever be taken, but it's correct case 0U: combination_field_bits = d0_is_nine ? 0b11001 : 0b11000; break; @@ -836,28 +849,32 @@ constexpr auto from_dpd_d128(const int128::uint128_t dpd) noexcept static_assert(std::is_same::value || std::is_same::value, "Target decimal type must be 128-bits"); + const auto sign {(dpd.high & detail::d128_sign_mask) != 0}; + if ((dpd & detail::d128_inf_mask) == detail::d128_inf_mask) { if ((dpd & detail::d128_snan_mask) == detail::d128_snan_mask) { - return std::numeric_limits::signaling_NaN(); + return sign ? -std::numeric_limits::signaling_NaN() : + std::numeric_limits::signaling_NaN(); } else if ((dpd & detail::d128_nan_mask) == detail::d128_nan_mask) { - return std::numeric_limits::quiet_NaN(); + return sign ? -std::numeric_limits::quiet_NaN() : + std::numeric_limits::quiet_NaN(); } else { - return std::numeric_limits::infinity(); + return sign ? -std::numeric_limits::infinity() : + std::numeric_limits::infinity(); } } - constexpr std::uint64_t d128_dpd_combination_field_mask_high_bits {UINT64_C(0b0'11111'00000000'0000000000'0000000000'0000000000'0000000000'0000000000)}; - constexpr std::uint64_t d128_dpd_exponent_mask_high_bits {UINT64_C(0b0'00000'111111111111'0000000000'0000000000'0000000000'0000000000'000000)}; - constexpr int128::uint128_t d128_dpd_significand_mask {UINT64_C(0b1111111111'1111111111'1111111111'1111111111'111111), UINT64_MAX}; + constexpr std::uint64_t d128_dpd_combination_field_mask_high_bits {UINT64_C(0x7C00000000000000)}; + constexpr std::uint64_t d128_dpd_exponent_mask_high_bits {UINT64_C(0x3FFC00000000000)}; + constexpr int128::uint128_t d128_dpd_significand_mask {UINT64_C(0x3FFFFFFFFFFF), UINT64_MAX}; // The bit lengths are the same as used in the standard bid format - const auto sign {(dpd.high & detail::d128_sign_mask) != 0}; const auto combination_field_bits {(dpd.high & d128_dpd_combination_field_mask_high_bits) >> 58U}; const auto exponent_field_bits {(dpd.high & d128_dpd_exponent_mask_high_bits) >> 46U}; auto significand_bits {(dpd & d128_dpd_significand_mask)}; @@ -903,7 +920,8 @@ constexpr auto from_dpd_d128(const int128::uint128_t dpd) noexcept digits[0] = static_cast(d0); for (int i = num_digits - 1; i > 0; i -= 3) { - const auto declet_bits {static_cast(significand_bits & 0b1111111111U)}; + constexpr std::uint32_t declet_mask {UINT32_C(0x3FF)}; + const auto declet_bits {static_cast(significand_bits & declet_mask)}; significand_bits >>= 10U; detail::decode_dpd(declet_bits, digits[i], digits[i - 1], digits[i - 2]); } diff --git a/include/boost/decimal/fenv.hpp b/include/boost/decimal/fenv.hpp deleted file mode 100644 index c7e0d8661..000000000 --- a/include/boost/decimal/fenv.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2025 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#ifndef BOOST_DECIMAL_FENV_HPP -#define BOOST_DECIMAL_FENV_HPP - -#ifdef _MSC_VER -// Expands to "This header is deprecated; use expr instead." -# define BOOST_DECIMAL_HEADER_DEPRECATED(expr) __pragma("This header is deprecated; use " expr " instead.") -#else // GNU, Clang, Intel, IBM, etc. -// Expands to "This header is deprecated use expr instead" -# define BOOST_DECIMAL_HEADER_DEPRECATED_MESSAGE(expr) _Pragma(#expr) -# define BOOST_DECIMAL_HEADER_DEPRECATED(expr) BOOST_DECIMAL_HEADER_DEPRECATED_MESSAGE(message "This header is deprecated use " expr " instead") -#endif - -BOOST_DECIMAL_HEADER_DEPRECATED(""); - -#include - -#endif //BOOST_DECIMAL_FENV_HPP diff --git a/include/boost/decimal/fmt_format.hpp b/include/boost/decimal/fmt_format.hpp index 0b4e71fbe..dfb3ea9e3 100644 --- a/include/boost/decimal/fmt_format.hpp +++ b/include/boost/decimal/fmt_format.hpp @@ -9,10 +9,26 @@ #define BOOST_DECIMAL_HAS_FMTLIB_SUPPORT +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wconversion" +#endif + #include #include +#include + +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + #include +#include #include + +#ifndef BOOST_DECIMAL_BUILD_MODULE + #include #include #include @@ -20,6 +36,8 @@ #include #include +#endif // BOOST_DECIMAL_BUILD_MODULE + namespace boost { namespace decimal { namespace detail { @@ -35,16 +53,19 @@ enum class sign_option template constexpr auto parse_impl(ParseContext &ctx) { + using CharType = typename ParseContext::char_type; + auto sign_character = sign_option::minus; - int ctx_precision = 6; + int ctx_precision = -1; boost::decimal::chars_format fmt = boost::decimal::chars_format::general; bool is_upper = false; int padding_digits = 0; + bool use_locale = false; auto it {ctx.begin()}; if (it == nullptr) { - return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, it); + return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, use_locale, it); } // Check for a sign character @@ -52,15 +73,15 @@ constexpr auto parse_impl(ParseContext &ctx) { switch (*it) { - case '-': + case static_cast('-'): sign_character = sign_option::minus; ++it; break; - case '+': + case static_cast('+'): sign_character = sign_option::plus; ++it; break; - case ' ': + case static_cast(' '): sign_character = sign_option::space; ++it; break; @@ -70,20 +91,20 @@ constexpr auto parse_impl(ParseContext &ctx) } // Check for a padding character - while (it != ctx.end() && *it >= '0' && *it <= '9') + while (it != ctx.end() && *it >= static_cast('0') && *it <= static_cast('9')) { - padding_digits = padding_digits * 10 + (*it - '0'); + padding_digits = padding_digits * 10 + (*it - static_cast('0')); ++it; } // If there is a . then we need to capture the precision argument - if (it != ctx.end() && *it == '.') + if (it != ctx.end() && *it == static_cast('.')) { ++it; ctx_precision = 0; - while (it != ctx.end() && *it >= '0' && *it <= '9') + while (it != ctx.end() && *it >= static_cast('0') && *it <= static_cast('9')) { - ctx_precision = ctx_precision * 10 + (*it - '0'); + ctx_precision = ctx_precision * 10 + (*it - static_cast('0')); ++it; } } @@ -93,37 +114,55 @@ constexpr auto parse_impl(ParseContext &ctx) { switch (*it) { - case 'G': + case static_cast('G'): is_upper = true; fmt = chars_format::general; break; - case 'g': + case static_cast('g'): fmt = chars_format::general; break; - case 'F': + case static_cast('F'): is_upper = true; fmt = chars_format::fixed; break; - case 'f': + case static_cast('f'): fmt = chars_format::fixed; break; - case 'E': + case static_cast('E'): is_upper = true; fmt = chars_format::scientific; break; - case 'e': + case static_cast('e'): fmt = chars_format::scientific; break; - case 'A': + case static_cast('X'): is_upper = true; fmt = chars_format::hex; break; - case 'a': + case static_cast('x'): fmt = chars_format::hex; break; + + case static_cast('A'): + if (ctx_precision != -1) + { + BOOST_DECIMAL_THROW_EXCEPTION(std::logic_error("Cohort preservation is mutually exclusive with precision")); + } + + is_upper = true; + fmt = chars_format::cohort_preserving_scientific; + break; + case static_cast('a'): + if (ctx_precision != -1) + { + BOOST_DECIMAL_THROW_EXCEPTION(std::logic_error("Cohort preservation is mutually exclusive with precision")); + } + + fmt = chars_format::cohort_preserving_scientific; + break; // LCOV_EXCL_START default: BOOST_DECIMAL_THROW_EXCEPTION(std::logic_error("Invalid format specifier")); @@ -132,13 +171,20 @@ constexpr auto parse_impl(ParseContext &ctx) ++it; } + // Check for the locale character + if (it != ctx.end() && *it == static_cast('L')) + { + use_locale = true; + ++it; + } + // Verify we're at the closing brace - if (it != ctx.end() && *it != '}') + if (it != ctx.end() && *it != static_cast('}')) { BOOST_DECIMAL_THROW_EXCEPTION(std::logic_error("Expected '}' in format string")); // LCOV_EXCL_LINE } - return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, it); + return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, use_locale, it); } template @@ -149,14 +195,17 @@ struct formatter int padding_digits; int ctx_precision; bool is_upper; + bool use_locale; constexpr formatter() : sign{sign_option::minus}, fmt{chars_format::general}, padding_digits{0}, ctx_precision{6}, - is_upper{false} {} + is_upper{false}, + use_locale{false} {} - constexpr auto parse(fmt::format_parse_context &ctx) + template + constexpr auto parse(fmt::parse_context &ctx) { const auto res {boost::decimal::detail::fmt_detail::parse_impl(ctx)}; @@ -165,8 +214,9 @@ struct formatter is_upper = std::get<2>(res); padding_digits = std::get<3>(res); sign = std::get<4>(res); + use_locale = std::get<5>(res); - return std::get<5>(res); + return std::get<6>(res); } template @@ -203,7 +253,15 @@ struct formatter // LCOV_EXCL_STOP } - const auto r = boost::decimal::to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt, ctx_precision); + boost::decimal::to_chars_result r {}; + if (ctx_precision != -1) + { + r = boost::decimal::to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt, ctx_precision); + } + else + { + r = boost::decimal::to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt); + } std::string s(buffer.data(), static_cast(r.ptr - buffer.data())); @@ -228,7 +286,74 @@ struct formatter s.insert(s.begin() + static_cast(has_sign), static_cast(padding_digits) - s.size(), '0'); } + if (use_locale) + { + // We need approximately 1/3 more space in order to insert the thousands separators, + // but after we have done our processing we need to shrink the string back down + const auto initial_length {s.length()}; + s.resize(s.length() * 4 / 3 + 1); + const auto offset {static_cast(convert_pointer_pair_to_local_locale(const_cast(s.data()), s.data() + s.length()))}; + s.resize(initial_length + offset); + } + + #ifdef BOOST_DECIMAL_NO_CXX17_IF_CONSTEXPR + return fmt::format_to(ctx.out(), "{}", s); + + #else + + using CharType = typename FormatContext::char_type; + + if constexpr (std::is_same_v) + { + return fmt::format_to(ctx.out(), "{}", s); + } + else if constexpr (std::is_same_v) + { + std::wstring result; + result.reserve(s.size()); + for (const char c : s) + { + result.push_back(static_cast(static_cast(c))); + } + + return fmt::format_to(ctx.out(), L"{}", result); + } + else + { + // For other character types (char16_t, char32_t, etc.) + + std::basic_string result; + result.reserve(s.size()); + for (const char c : s) + { + result.push_back(static_cast(static_cast(c))); + } + + if constexpr (std::is_same_v) + { + return fmt::format_to(ctx.out(), u"{}", result); + } + else if constexpr (std::is_same_v) + { + return fmt::format_to(ctx.out(), U"{}", result); + } + #ifdef BOOST_DECIMAL_HAS_CHAR8_T + else + { + static_assert(std::is_same_v, "Unsupported wide character type"); + return fmt::format_to(ctx.out(), u8"{}", result); + } + #else + else + { + static_assert(std::is_same_v, "Unsupported wide character type"); + return fmt::format_to(ctx.out(), u8"{}", result); + } + #endif + } + + #endif // BOOST_DECIMAL_NO_CXX17_IF_CONSTEXPR } }; @@ -239,6 +364,8 @@ struct formatter namespace fmt { +#ifdef BOOST_DECIMAL_NO_CXX17_IF_CONSTEXPR + template <> struct formatter : public boost::decimal::detail::fmt_detail::formatter {}; @@ -263,6 +390,134 @@ template <> struct formatter : public boost::decimal::detail::fmt_detail::formatter {}; +#else + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +#ifdef BOOST_DECIMAL_HAS_CHAR8_T + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +template <> +struct formatter + : public boost::decimal::detail::fmt_detail::formatter {}; + +#endif // BOOST_DECIMAL_HAS_CHAR8_T + +#endif + } // namespace fmt #endif // __has_include() diff --git a/include/boost/decimal/format.hpp b/include/boost/decimal/format.hpp index 4dae38a9c..7f66d5176 100644 --- a/include/boost/decimal/format.hpp +++ b/include/boost/decimal/format.hpp @@ -5,13 +5,12 @@ #ifndef BOOST_DECIMAL_FORMAT_HPP #define BOOST_DECIMAL_FORMAT_HPP -// Many compilers seem to have with completely broken support so narrow down our support range -#if (__cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) && !defined(BOOST_DECIMAL_DISABLE_CLIB) && \ - ((defined(__GNUC__) && __GNUC__ >= 13) || (defined(__clang__) && __clang_major__ >= 18) || (defined(_MSC_VER) && _MSC_VER >= 1940)) +#if __has_include() && defined(__cpp_lib_format) && __cpp_lib_format >= 201907L && !defined(BOOST_DECIMAL_DISABLE_CLIB) #define BOOST_DECIMAL_HAS_FORMAT_SUPPORT #include +#include #include #include #include @@ -24,7 +23,8 @@ // Default :g // Fixed :f // Scientific :e -// Hex :a +// Hex :x +// Cohort Preserving :a // // Capital letter for any of the above leads to all characters being uppercase @@ -40,27 +40,30 @@ enum class format_sign_option template constexpr auto parse_impl(ParseContext &ctx) { + using CharType = typename ParseContext::char_type; + auto sign_character = format_sign_option::minus; auto it {ctx.begin()}; - int ctx_precision = 6; + int ctx_precision = -1; boost::decimal::chars_format fmt = boost::decimal::chars_format::general; bool is_upper = false; int padding_digits = 0; + bool use_locale = false; // Check for a sign character if (it != ctx.end()) { switch (*it) { - case '-': + case static_cast('-'): sign_character = format_sign_option::minus; ++it; break; - case '+': + case static_cast('+'): sign_character = format_sign_option::plus; ++it; break; - case ' ': + case static_cast(' '): sign_character = format_sign_option::space; ++it; break; @@ -70,26 +73,26 @@ constexpr auto parse_impl(ParseContext &ctx) } // Check for a padding character - while (it != ctx.end() && *it >= '0' && *it <= '9') + while (it != ctx.end() && *it >= static_cast('0') && *it <= static_cast('9')) { - padding_digits = padding_digits * 10 + (*it - '0'); + padding_digits = padding_digits * 10 + (*it - static_cast('0')); ++it; } // If there is a . then we need to capture the precision argument - if (it != ctx.end() && *it == '.') + if (it != ctx.end() && *it == static_cast('.')) { ++it; ctx_precision = 0; - while (it != ctx.end() && *it >= '0' && *it <= '9') + while (it != ctx.end() && *it >= static_cast('0') && *it <= static_cast('9')) { - ctx_precision = ctx_precision * 10 + (*it - '0'); + ctx_precision = ctx_precision * 10 + (*it - static_cast('0')); ++it; } } // Lastly we capture the format to include if it's upper case - if (it != ctx.end() && *it != '}') + if (it != ctx.end() && *it != static_cast('}')) { switch (*it) { @@ -114,12 +117,25 @@ constexpr auto parse_impl(ParseContext &ctx) fmt = chars_format::scientific; break; + case 'X': + is_upper = true; + [[fallthrough]]; + case 'x': + fmt = chars_format::hex; + break; + case 'A': is_upper = true; [[fallthrough]]; case 'a': - fmt = chars_format::hex; + if (ctx_precision != -1) + { + BOOST_DECIMAL_THROW_EXCEPTION(std::format_error("Cohort preservation is mutually exclusive with precision")); + } + + fmt = chars_format::cohort_preserving_scientific; break; + // LCOV_EXCL_START default: BOOST_DECIMAL_THROW_EXCEPTION(std::format_error("Invalid format specifier")); @@ -128,36 +144,58 @@ constexpr auto parse_impl(ParseContext &ctx) ++it; } + // Check for the locale character + if (it != ctx.end() && *it == static_cast('L')) + { + use_locale = true; + ++it; + } + // Verify we're at the closing brace - if (it != ctx.end() && *it != '}') + if (it != ctx.end() && *it != static_cast('}')) { BOOST_DECIMAL_THROW_EXCEPTION(std::format_error("Expected '}' in format string")); // LCOV_EXCL_LINE } - return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, it); + return std::make_tuple(ctx_precision, fmt, is_upper, padding_digits, sign_character, use_locale, it); } +template +struct formattable_character_type : std::false_type {}; + +template <> +struct formattable_character_type : std::true_type {}; + +template <> +struct formattable_character_type : std::true_type {}; + +template +inline constexpr bool is_formattable_character_type_v = formattable_character_type::value; + } // Namespace boost::decimal::detail namespace std { -template -struct formatter +template + requires boost::decimal::detail::is_formattable_character_type_v +struct formatter { boost::decimal::chars_format fmt; boost::decimal::detail::format_sign_option sign; int ctx_precision; int padding_digits; bool is_upper; + bool use_locale; constexpr formatter() : fmt(boost::decimal::chars_format::general), sign(boost::decimal::detail::format_sign_option::minus), ctx_precision(6), padding_digits(0), - is_upper(false) + is_upper(false), + use_locale(false) {} - constexpr auto parse(format_parse_context &ctx) + constexpr auto parse(basic_format_parse_context& ctx) { const auto res {boost::decimal::detail::parse_impl(ctx)}; @@ -166,8 +204,9 @@ struct formatter is_upper = std::get<2>(res); padding_digits = std::get<3>(res); sign = std::get<4>(res); + use_locale = std::get<5>(res); - return std::get<5>(res); + return std::get<6>(res); } template @@ -176,6 +215,9 @@ struct formatter using namespace boost::decimal; using namespace boost::decimal::detail; + using CharType = FormatContext::char_type; + static_assert(is_formattable_character_type_v, "This is an unsupported character type. Only char and wchar_t can be used with std::format"); + std::array buffer {}; auto buffer_front = buffer.data(); bool has_sign {false}; @@ -207,7 +249,15 @@ struct formatter // LCOV_EXCL_STOP } - const auto r = to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt, ctx_precision); + boost::decimal::to_chars_result r {}; + if (ctx_precision != -1) + { + r = to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt, ctx_precision); + } + else + { + r = to_chars(buffer_front, buffer.data() + buffer.size(), v, fmt); + } std::string s(buffer.data(), static_cast(r.ptr - buffer.data())); @@ -232,12 +282,37 @@ struct formatter s.insert(s.begin() + static_cast(has_sign), static_cast(padding_digits) - s.size(), '0'); } - return std::format_to(ctx.out(), "{}", s); + if (use_locale) + { + // We need approximately 1/3 more space in order to insert the thousands separators, + // but after we have done our processing we need to shrink the string back down + const auto initial_length {s.length()}; + s.resize(s.length() * 4 / 3 + 1); + const auto offset {static_cast(convert_pointer_pair_to_local_locale(const_cast(s.data()), s.data() + s.length()))}; + s.resize(initial_length + offset); + } + + // std only supports char and wchar_t + if constexpr (std::is_same_v) + { + return std::format_to(ctx.out(), "{}", s); + } + else + { + std::wstring result; + result.reserve(s.size()); + for (const char c : s) + { + result.push_back(static_cast(static_cast(c))); + } + + return std::format_to(ctx.out(), L"{}", result); + } } }; } // Namespace std -#endif +#endif // compatibility #endif //BOOST_DECIMAL_FORMAT_HPP diff --git a/include/boost/decimal/fwd.hpp b/include/boost/decimal/fwd.hpp index 3a519b1c2..3f7649bba 100644 --- a/include/boost/decimal/fwd.hpp +++ b/include/boost/decimal/fwd.hpp @@ -25,46 +25,31 @@ class decimal_fast128_t; namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; + +#ifdef __clang__ +# pragma clang diagnostic pop #endif } // Namespace std diff --git a/include/boost/decimal/hash.hpp b/include/boost/decimal/hash.hpp index 718d145ed..15a8cf50f 100644 --- a/include/boost/decimal/hash.hpp +++ b/include/boost/decimal/hash.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #ifndef BOOST_DECIMAL_BUILD_MODULE #include @@ -26,8 +27,10 @@ struct hash // Since the underlying type is a std::uint32_t, we will rely on its hash function from the STL auto operator()(const boost::decimal::decimal32_t& v) const noexcept -> std::size_t { + const auto normalized_v {boost::decimal::normalize(v)}; + std::uint32_t bits; - std::memcpy(&bits, &v, sizeof(std::uint32_t)); + std::memcpy(&bits, &normalized_v, sizeof(std::uint32_t)); return std::hash{}(bits); } @@ -39,8 +42,10 @@ struct hash // Since the underlying type is a std::uint64_t, we will rely on its hash function from the STL auto operator()(const boost::decimal::decimal64_t& v) const noexcept -> std::size_t { + const auto normalized_v {boost::decimal::normalize(v)}; + std::uint64_t bits; - std::memcpy(&bits, &v, sizeof(std::uint64_t)); + std::memcpy(&bits, &normalized_v, sizeof(std::uint64_t)); return std::hash{}(bits); } @@ -57,8 +62,10 @@ struct hash // Take the xor of the two words and hash that auto operator()(const boost::decimal::decimal128_t& v) const noexcept -> std::size_t { + const auto normalized_v {boost::decimal::normalize(v)}; + boost::int128::uint128_t bits; - std::memcpy(&bits, &v, sizeof(boost::int128::uint128_t)); + std::memcpy(&bits, &normalized_v, sizeof(boost::int128::uint128_t)); return std::hash{}(bits.high ^ bits.low); } diff --git a/include/boost/decimal/literals.hpp b/include/boost/decimal/literals.hpp index e0709f76b..e6d84d350 100644 --- a/include/boost/decimal/literals.hpp +++ b/include/boost/decimal/literals.hpp @@ -55,16 +55,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_df(const char *str, const std::s return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DF(const unsigned long long v) -> decimal32_t -{ - return decimal32_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_df(const unsigned long long v) -> decimal32_t -{ - return decimal32_t {v}; -} - BOOST_DECIMAL_EXPORT constexpr auto operator ""_DFF(const char *str) -> decimal_fast32_t { decimal_fast32_t d; @@ -93,16 +83,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_dff(const char *str, const std:: return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DFF(const unsigned long long v) -> decimal_fast32_t -{ - return decimal_fast32_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_dff(const unsigned long long v) -> decimal_fast32_t -{ - return decimal_fast32_t {v}; -} - BOOST_DECIMAL_EXPORT constexpr auto operator ""_DD(const char *str) -> decimal64_t { decimal64_t d; @@ -131,16 +111,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_dd(const char *str, std::size_t) return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DD(const unsigned long long v) -> decimal64_t -{ - return decimal64_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_dd(const unsigned long long v) -> decimal64_t -{ - return decimal64_t {v}; -} - BOOST_DECIMAL_EXPORT constexpr auto operator ""_DDF(const char *str) -> decimal_fast64_t { decimal_fast64_t d; @@ -169,16 +139,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_ddf(const char *str, const std:: return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DDF(const unsigned long long v) -> decimal_fast64_t -{ - return decimal_fast64_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_ddf(const unsigned long long v) -> decimal_fast64_t -{ - return decimal_fast64_t {v}; -} - BOOST_DECIMAL_EXPORT constexpr auto operator ""_DL(const char *str) -> decimal128_t { decimal128_t d; @@ -207,16 +167,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_dl(const char *str, std::size_t) return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DL(const unsigned long long v) -> decimal128_t -{ - return decimal128_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_dl(const unsigned long long v) -> decimal128_t -{ - return decimal128_t {v}; -} - BOOST_DECIMAL_EXPORT constexpr auto operator ""_DLF(const char *str) -> decimal_fast128_t { decimal_fast128_t d; @@ -245,16 +195,6 @@ BOOST_DECIMAL_EXPORT constexpr auto operator ""_dlf(const char *str, const std:: return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator ""_DLF(const unsigned long long v) -> decimal_fast128_t -{ - return decimal_fast128_t {v}; -} - -BOOST_DECIMAL_EXPORT constexpr auto operator ""_dlf(const unsigned long long v) -> decimal_fast128_t -{ - return decimal_fast128_t {v}; -} - } // namespace literals } // namespace decimal } // namespace boost diff --git a/include/boost/decimal/numbers.hpp b/include/boost/decimal/numbers.hpp index 554f6813e..f61fc0d6c 100644 --- a/include/boost/decimal/numbers.hpp +++ b/include/boost/decimal/numbers.hpp @@ -43,7 +43,7 @@ constexpr auto log2e_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto log2e_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(78208654878293), UINT64_C(16395798456599530402)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(78208654878293), UINT64_C(16395798456599530404)}, -33}; } template < 128, bool> = true> @@ -55,7 +55,7 @@ constexpr auto log10e_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto log10e_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(235431510388986), UINT64_C(2047877485384264674)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(235431510388986), UINT64_C(2047877485384264675)}, -34}; } template < 128, bool> = true> @@ -79,7 +79,7 @@ constexpr auto pi_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto pi_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(170306079004327), UINT64_C(13456286628489437068)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(170306079004327), UINT64_C(13456286628489437071)}, -33}; } template < 128, bool> = true> @@ -91,7 +91,7 @@ constexpr auto pi_over_four_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto pi_over_four_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(42576519751081932), UINT64_C(6764235707220873609)}, -38}; + return DecimalType{boost::int128::uint128_t{UINT64_C(42576519751081932), UINT64_C(5970600460659265253)}, -38}; } template < 128, bool> = true> @@ -103,7 +103,7 @@ constexpr auto inv_pi_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto inv_pi_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(172556135062039), UINT64_C(13820348844234745256)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(172556135062039), UINT64_C(13820348844234745263)}, -34}; } template < 128, bool> = true> @@ -115,7 +115,7 @@ constexpr auto inv_sqrtpi_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto inv_sqrtpi_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(305847786088084), UINT64_C(12695685840195063976)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(305847786088084), UINT64_C(12695685840195063982)}, -34}; } template < 128, bool> = true> @@ -127,7 +127,7 @@ constexpr auto ln2_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto ln2_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(375755839507647), UINT64_C(8395602002641374208)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(375755839507647), UINT64_C(8395602002641374214)}, -34}; } template < 128, bool> = true> @@ -139,7 +139,7 @@ constexpr auto ln10_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto ln10_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(124823388007844), UINT64_C(1462833818723808456)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(124823388007844), UINT64_C(1462833818723808460)}, -33}; } template < 128, bool> = true> @@ -151,7 +151,7 @@ constexpr auto sqrt2_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto sqrt2_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(76664670834168), UINT64_C(12987834932751794202)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(76664670834168), UINT64_C(12987834932751794210)}, -33}; } template < 128, bool> = true> @@ -163,7 +163,7 @@ constexpr auto sqrt3_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto sqrt3_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(93894662421072), UINT64_C(8437766544231453518)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(93894662421072), UINT64_C(8437766544231453520)}, -33}; } template < 128, bool> = true> @@ -175,7 +175,7 @@ constexpr auto sqrt10_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto sqrt10_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(171427415457846), UINT64_C(13450487317535253574)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(171427415457846), UINT64_C(13450487317535253583)}, -33}; } template < 128, bool> = true> @@ -223,7 +223,7 @@ constexpr auto inv_sqrt3_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto inv_sqrt3_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(312982208070241), UINT64_C(9679144407061960114)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(312982208070241), UINT64_C(9679144407061960119)}, -34}; } template < 128, bool> = true> @@ -235,7 +235,7 @@ constexpr auto egamma_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto egamma_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(312909238939453), UINT64_C(7916302232898517972)}, -34}; + return DecimalType{boost::int128::uint128_t{UINT64_C(312909238939453), UINT64_C(7916302232898517976)}, -34}; } template < 128, bool> = true> @@ -247,88 +247,88 @@ constexpr auto phi_v() noexcept -> DecimalType template >= 128, bool> = true> constexpr auto phi_v() noexcept -> DecimalType { - return DecimalType{boost::int128::uint128_t{UINT64_C(87713798287901), UINT64_C(2061523135646567614)}, -33}; + return DecimalType{boost::int128::uint128_t{UINT64_C(87713798287901), UINT64_C(2061523135646567622)}, -33}; } } // Namespace detail BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec e_v = detail::e_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec e_v = detail::e_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec log2e_v = detail::log2e_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec log2e_v = detail::log2e_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec log10e_v = detail::log10e_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec log10e_v = detail::log10e_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec log10_2_v = detail::log10_2_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec log10_2_v = detail::log10_2_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec pi_v = detail::pi_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec pi_v = detail::pi_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec pi_over_four_v = detail::pi_over_four_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec pi_over_four_v = detail::pi_over_four_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec inv_pi_v = detail::inv_pi_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec inv_pi_v = detail::inv_pi_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec inv_sqrtpi_v = detail::inv_sqrtpi_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec inv_sqrtpi_v = detail::inv_sqrtpi_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec ln2_v = detail::ln2_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec ln2_v = detail::ln2_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec ln10_v = detail::ln10_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec ln10_v = detail::ln10_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec sqrt2_v = detail::sqrt2_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec sqrt2_v = detail::sqrt2_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec sqrt3_v = detail::sqrt3_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec sqrt3_v = detail::sqrt3_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec sqrt10_v = detail::sqrt10_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec sqrt10_v = detail::sqrt10_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec cbrt2_v = detail::cbrt2_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec cbrt2_v = detail::cbrt2_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec cbrt10_v = detail::cbrt10_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec cbrt10_v = detail::cbrt10_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec inv_sqrt2_v = detail::inv_sqrt2_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec inv_sqrt2_v = detail::inv_sqrt2_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec inv_sqrt3_v = detail::inv_sqrt3_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec inv_sqrt3_v = detail::inv_sqrt3_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec egamma_v = detail::egamma_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec egamma_v = detail::egamma_v(); BOOST_DECIMAL_EXPORT template , bool> = true> -BOOST_DECIMAL_CONSTEXPR_VARIABLE Dec phi_v = detail::phi_v(); +BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE Dec phi_v = detail::phi_v(); // Explicitly defaulted variables like the STL provides -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto e {e_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto log10_2 {log10_2_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto log10e {log10e_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto log2e {log2e_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto pi {pi_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto inv_pi {inv_pi_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto inv_sqrtpi {inv_sqrtpi_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto ln2 {ln2_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto ln10 {ln10_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto sqrt2 {sqrt2_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto sqrt3 {sqrt3_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto sqrt10 {sqrt10_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto cbrt2 {cbrt2_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto cbrt10 {cbrt10_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto inv_sqrt2 {inv_sqrt2_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto inv_sqrt3 {inv_sqrt3_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto egamma {egamma_v}; -BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR_VARIABLE auto phi {phi_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto e {e_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto log10_2 {log10_2_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto log10e {log10e_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto log2e {log2e_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto pi {pi_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto inv_pi {inv_pi_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto inv_sqrtpi {inv_sqrtpi_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto ln2 {ln2_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto ln10 {ln10_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto sqrt2 {sqrt2_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto sqrt3 {sqrt3_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto sqrt10 {sqrt10_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto cbrt2 {cbrt2_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto cbrt10 {cbrt10_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto inv_sqrt2 {inv_sqrt2_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto inv_sqrt3 {inv_sqrt3_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto egamma {egamma_v}; +BOOST_DECIMAL_EXPORT BOOST_DECIMAL_INLINE_CONSTEXPR_VARIABLE auto phi {phi_v}; } // namespace numbers } // namespace decimal diff --git a/include/boost/decimal/string.hpp b/include/boost/decimal/string.hpp index f5846cf6e..0248586f5 100644 --- a/include/boost/decimal/string.hpp +++ b/include/boost/decimal/string.hpp @@ -13,12 +13,74 @@ namespace boost { namespace decimal { +namespace detail { + +template +auto from_string_impl(const std::string& str, std::size_t* idx) + BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, DecimalType) +{ + DecimalType val; + const auto r {from_chars(str, val)}; + + if (r.ec == std::errc::result_out_of_range || val == std::numeric_limits::infinity()) + { + val = std::numeric_limits::signaling_NaN(); + BOOST_DECIMAL_THROW_EXCEPTION(std::out_of_range("Conversion is outside the range of the type")); + } + else if (r.ec != std::errc{}) + { + val = std::numeric_limits::signaling_NaN(); + BOOST_DECIMAL_THROW_EXCEPTION(std::invalid_argument("Conversion could not be performed")); + } + else + { + if (idx != nullptr) + { + *idx = static_cast(r.ptr - str.data()); + } + } + + return val; +} + +} // namespace detail + +BOOST_DECIMAL_EXPORT inline auto stod32(const std::string& str, std::size_t* idx = nullptr) -> decimal32_t +{ + return detail::from_string_impl(str, idx); +} + +BOOST_DECIMAL_EXPORT inline auto stod32f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast32_t +{ + return detail::from_string_impl(str, idx); +} + +BOOST_DECIMAL_EXPORT inline auto stod64(const std::string& str, std::size_t* idx = nullptr) -> decimal64_t +{ + return detail::from_string_impl(str, idx); +} + +BOOST_DECIMAL_EXPORT inline auto stod64f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast64_t +{ + return detail::from_string_impl(str, idx); +} + +BOOST_DECIMAL_EXPORT inline auto stod128(const std::string& str, std::size_t* idx = nullptr) -> decimal128_t +{ + return detail::from_string_impl(str, idx); +} + +BOOST_DECIMAL_EXPORT inline auto stod128f(const std::string& str, std::size_t* idx = nullptr) -> decimal_fast128_t +{ + return detail::from_string_impl(str, idx); +} + BOOST_DECIMAL_EXPORT template auto to_string(const DecimalType value) BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::string) { char buffer[64]; - auto r = to_chars(buffer, buffer + sizeof(buffer), value, chars_format::fixed, 6); + auto r = to_chars(buffer, buffer + sizeof(buffer), value); *r.ptr = '\0'; return std::string(buffer); } diff --git a/include/boost/decimal/uint128_t.hpp b/include/boost/decimal/uint128_t.hpp new file mode 100644 index 000000000..683c2ac4b --- /dev/null +++ b/include/boost/decimal/uint128_t.hpp @@ -0,0 +1,18 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_UINT128_T_HPP +#define BOOST_DECIMAL_UINT128_T_HPP + +#include "detail/int128.hpp" + +namespace boost { +namespace decimal { + +using uint128_t = int128::uint128_t; + +} +} + +#endif // BOOST_DECIMAL_UINT128_T_HPP diff --git a/modules/Jamfile b/modules/Jamfile index 307799288..a8dc5cd51 100644 --- a/modules/Jamfile +++ b/modules/Jamfile @@ -22,8 +22,27 @@ project gcc:23 clang:23 + BOOST_DECIMAL_USE_MODULE ; obj decimal : decimal.cxx : msvc:-interface ; run quick_test.cpp decimal : : : decimal ; + +run ../test/github_issue_448.cpp decimal : : : decimal ; +run ../test/github_issue_798.cpp decimal : : : decimal ; +run ../test/github_issue_802.cpp decimal : : : decimal ; +run ../test/github_issue_805.cpp decimal : : : decimal ; +run ../test/github_issue_808.cpp decimal : : : decimal ; +run ../test/github_issue_890.cpp decimal : : : decimal ; +run ../test/github_issue_900.cpp decimal : : : decimal ; +run ../test/github_issue_988.cpp decimal : : : decimal ; +run ../test/github_issue_1026.cpp decimal : : : decimal ; +run ../test/github_issue_1035.cpp decimal : : : decimal ; +run ../test/github_issue_1054.cpp decimal : : : decimal ; +run ../test/github_issue_1055.cpp decimal : : : decimal ; +run ../test/github_issue_1057.cpp decimal : : : decimal ; + +run ../test/random_decimal32_comp.cpp decimal : : : decimal ; +run ../test/random_decimal32_fast_comp.cpp decimal : : : decimal ; +run ../test/random_decimal32_fast_math.cpp decimal : : : decimal ; diff --git a/modules/decimal.cxx b/modules/decimal.cxx index 5f5c1b203..f6657812a 100644 --- a/modules/decimal.cxx +++ b/modules/decimal.cxx @@ -31,6 +31,7 @@ module; #include #include #include +#include // is a C++23 feature that is not everywhere yet #if __has_include() @@ -80,46 +81,22 @@ class decimal_fast128_t; export namespace std { template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif } // Namespace std diff --git a/ports/decimal/portfile.cmake b/ports/decimal/portfile.cmake index fa33a0eb8..48028e3b3 100644 --- a/ports/decimal/portfile.cmake +++ b/ports/decimal/portfile.cmake @@ -7,8 +7,8 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO cppalliance/decimal - REF v5.1.2 - SHA512 e3c0a2542f30407c1a9f24679182f2ee2e826c9e65c58e208af7a7a11194709dbd473e0eea68b59bb398afd1c0ab5a8ac420a4c1c4d69198cc541773f0372dd6 + REF v5.2.0 + SHA512 631d438c906cb567c30629aad3daf97a336c0b532a16908249b09383e868ad51e8cca538680893a03d2a5c4fbcd153e52585dc5c1293e2db71579afb4cc94525 HEAD_REF master ) diff --git a/ports/decimal/vcpkg.json b/ports/decimal/vcpkg.json index 6f0fabd90..aaee3a375 100644 --- a/ports/decimal/vcpkg.json +++ b/ports/decimal/vcpkg.json @@ -1,6 +1,6 @@ { "name": "decimal", - "version": "5.1.2", + "version": "5.2.0", "description": "A C++14 implementation of IEEE 754 decimal floating point numbers", "homepage": "https://github.com/cppalliance/decimal", "license": "BSL-1.0", diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b1fa1998d..eebf64ac1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,17 +7,25 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) if(HAVE_BOOST_TEST) - find_package(fmt) - find_package(bson 2.0.2 CONFIG) - if(fmt_FOUND AND bson_FOUND) - message(STATUS "Boost.Decimal: Test with fmtlib and bson") - boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random fmt::fmt bson::bson COMPILE_DEFINITIONS BOOST_DECIMAL_TEST_FMT BOOST_DECIMAL_TEST_BSON) - elseif(fmt_FOUND) - message(STATUS "Boost.Decimal: Test with fmtlib") - boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random fmt::fmt COMPILE_DEFINITIONS BOOST_DECIMAL_TEST_FMT) + if(BUILD_DECTEST_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/decimal-dectest/CMakeLists.txt") + + add_subdirectory(decimal-dectest) + else() - message(STATUS "Boost.Decimal: Test without fmtlib and bson") - boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random) + + find_package(fmt CONFIG) + find_package(bson 2.0.2 CONFIG) + if(fmt_FOUND AND bson_FOUND) + message(STATUS "Boost.Decimal: Test with fmtlib and bson") + boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random fmt::fmt bson::bson COMPILE_DEFINITIONS BOOST_DECIMAL_TEST_FMT BOOST_DECIMAL_TEST_BSON) + elseif(fmt_FOUND) + message(STATUS "Boost.Decimal: Test with fmtlib") + boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random fmt::fmt COMPILE_DEFINITIONS BOOST_DECIMAL_TEST_FMT) + else() + message(STATUS "Boost.Decimal: Test without fmtlib and bson") + boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::decimal Boost::core Boost::math Boost::multiprecision Boost::charconv Boost::random) + endif() + endif() endif() diff --git a/test/Jamfile b/test/Jamfile index 43b3fa67b..b51a99beb 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -29,6 +29,11 @@ project : requirements #gcc:-Wduplicated-branches gcc:-Wfloat-equal gcc:-Wshadow + # https://github.com/cppalliance/decimal/issues/1291 + # GCC-7 does not support extra-semi, just pick one to try + gcc-13:-Wextra-semi + gcc:-Wuseless-cast + # gcc:-Wpadded clang:-Wsign-conversion clang:-Wconversion @@ -48,6 +53,7 @@ run-fail benchmark_uint256.cpp ; run compare_dec128_and_fast.cpp ; compile-fail concepts_test.cpp ; + run crash_report_1.cpp ; run github_issue_426.cpp ; run github_issue_448.cpp ; @@ -58,10 +64,27 @@ run github_issue_802.cpp ; run github_issue_805.cpp ; run github_issue_808.cpp ; run github_issue_890.cpp ; -run github_issue_893.cpp ; run github_issue_900.cpp ; run github_issue_911.cpp ; run github_issue_988.cpp ; +run github_issue_1026.cpp ; +run github_issue_1035.cpp ; +run github_issue_1054.cpp ; +run github_issue_1055.cpp ; +run github_issue_1057.cpp ; +compile-fail github_issue_1087.cpp ; +run github_issue_1091.cpp ; +run github_issue_1094.cpp ; +run github_issue_1105.cpp ; +run github_issue_1106.cpp ; +run github_issue_1107.cpp ; +run github_issue_1110.cpp ; +run github_issue_1112.cpp ; +run github_issue_1174.cpp ; +run github_issue_1260.cpp ; +run github_issue_1294.cpp ; +run github_issue_1299.cpp ; + run link_1.cpp link_2.cpp link_3.cpp ; run quick.cpp ; run random_decimal32_comp.cpp ; @@ -98,8 +121,10 @@ run test_bid_conversions.cpp ; run test_big_uints.cpp ; run test_boost_math_univariate_stats.cpp ; run test_cbrt.cpp ; +run test_charconv_preservation.cpp ; run test_cmath.cpp ; run test_constants.cpp ; +run test_constexpr_rounding_mode.cpp ; run test_cosh.cpp ; #run test_decimal32.cpp ; run test_decimal32_fast_basis.cpp ; @@ -111,6 +136,7 @@ run test_decimal64_fast_stream.cpp ; run test_decimal64_stream.cpp ; #run test_decimal128_basis.cpp ; run test_decimal_quantum.cpp ; +run test_downward_rounding.cpp ; run test_dpd_conversions.cpp ; run test_edges_and_behave.cpp ; run test_edit_members.cpp ; @@ -130,6 +156,8 @@ run test_format_fmtlib.cpp ; run-fail test_fprintf.cpp ; run test_frexp_ldexp.cpp ; run test_from_chars.cpp /boost/charconv//boost_charconv ; +run test_from_chars_nan_payloads.cpp ; +run test_from_string.cpp ; run test_git_issue_266.cpp ; run test_git_issue_271.cpp ; run test_hash.cpp ; @@ -149,6 +177,7 @@ run test_lgamma.cpp ; run test_log.cpp ; run test_log1p.cpp ; run test_log10.cpp ; +run test_nan_conversions.cpp ; run test_normalize.cpp ; run test_parser.cpp ; run test_pow.cpp ; @@ -159,33 +188,49 @@ run test_sin_cos.cpp ; run test_sinh.cpp ; run test_snprintf.cpp ; run test_sqrt.cpp ; +run test_string_construction.cpp ; +run test_string_locale_conversion.cpp ; run test_strtod.cpp ; run test_tan.cpp ; run test_tanh.cpp ; run test_tgamma.cpp ; run test_to_chars.cpp ; run test_to_string.cpp ; +run test_total_ordering.cpp ; +run test_upward_rounding.cpp ; run test_zeta.cpp ; +run limits_link_1.cpp limits_link_2.cpp limits_link_3.cpp ; + # Run the examples too run ../examples/adl.cpp ; run ../examples/basic_construction.cpp ; run ../examples/bit_conversions.cpp ; run ../examples/charconv.cpp ; +run ../examples/charconv_cohort_preservation.cpp ; run ../examples/literals.cpp ; run ../examples/rounding_mode.cpp ; -run ../examples/moving_average.cpp ; -run ../examples/currency_conversion.cpp ; +run ../examples/rounding_mode_compile_time.cpp ; run ../examples/statistics.cpp ; run ../examples/format.cpp ; run ../examples/fmt_format.cpp ; run ../examples/print.cpp ; +run ../examples/promotion.cpp ; +run ../examples/numerical_parsing.cpp ; +run ../examples/first_example.cpp ; +run ../examples/basic_arithmetic.cpp ; +run ../examples/to_from_file.cpp ; +run ../examples/addition.cpp ; +run ../examples/debugger.cpp ; +run ../examples/binary_float_conversions.cpp ; +run ../examples/integral_conversions.cpp ; # Test compilation of separate headers compile compile_tests/bid_conversion.cpp ; compile compile_tests/dpd_conversion.cpp ; compile compile_tests/cfloat.cpp ; compile compile_tests/charconv_compile.cpp ; +compile compile_tests/charconv_before_types_compile.cpp ; compile compile_tests/cmath_compile.cpp ; compile compile_tests/cstdio_compile.cpp ; compile compile_tests/cstdlib_compile.cpp ; diff --git a/test/benchmark_libbid.c b/test/benchmark_libbid.c index 725a24e3c..d3464284a 100644 --- a/test/benchmark_libbid.c +++ b/test/benchmark_libbid.c @@ -2,25 +2,71 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#define _POSIX_C_SOURCE 199309L +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#else +# define _POSIX_C_SOURCE 199309L +#endif #include #include #include -#include #include #include #include -typedef uint32_t Decimal32; -typedef uint64_t Decimal64; -#include "../LIBRARY/src/bid_conf.h" -#include "../LIBRARY/src/bid_functions.h" +#include "..\LIBRARY\src\bid_conf.h" +#include "..\LIBRARY\src\bid_functions.h" + +typedef BID_UINT32 Decimal32; +typedef BID_UINT64 Decimal64; typedef BID_UINT128 Decimal128; #define K 20000000 #define N 5 +#ifdef _MSC_VER +# define BOOST_DECIMAL_NOINLINE __declspec(noinline) +#else +# define BOOST_DECIMAL_NOINLINE __attribute__ ((noinline)) +#endif + +#ifdef _WIN32 +#include + +#define CLOCK_MONOTONIC 1 + +struct timespec +{ + long tv_sec; + long tv_nsec; +}; + +int clock_gettime(int clock_id, struct timespec* tp) +{ + (void)clock_id; // Ignore clock_id, always use QPC + + static LARGE_INTEGER frequency = { 0 }; + LARGE_INTEGER counter; + + if (frequency.QuadPart == 0) + { + QueryPerformanceFrequency(&frequency); + } + + QueryPerformanceCounter(&counter); + + tp->tv_sec = (long)(counter.QuadPart / frequency.QuadPart); + tp->tv_nsec = (long)(((counter.QuadPart % frequency.QuadPart) * 1000000000LL) / frequency.QuadPart); + + return 0; +} + +#else +#include +#endif + uint32_t flag = 0; uint32_t random_uint32(void) @@ -45,15 +91,15 @@ uint64_t random_uint64(void) return r; } -__attribute__ ((noinline)) void generate_vector_32(Decimal32* buffer, size_t buffer_len) +BOOST_DECIMAL_NOINLINE void generate_vector_32(Decimal32* buffer, size_t buffer_len) { for (size_t i = 0; i < buffer_len; ++i) { - buffer[i] = bid32_from_uint32(random_uint32(), BID_ROUNDING_DOWN, &flag); + buffer[i] = bid32_from_uint32(random_uint32(), BID_ROUNDING_TO_NEAREST, &flag); } } -__attribute__ ((noinline)) void test_comparisons_32(Decimal32* data, const char* label) +BOOST_DECIMAL_NOINLINE void test_comparisons_32(Decimal32* data, const char* label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -82,15 +128,15 @@ __attribute__ ((noinline)) void test_comparisons_32(Decimal32* data, const char* printf("Comparisons <%-10s >: %-10" PRIu64 " us (s=%zu)\n", label, elapsed_time_us, s); } -__attribute__ ((noinline)) void generate_vector_64(Decimal64* buffer, size_t buffer_len) +BOOST_DECIMAL_NOINLINE void generate_vector_64(Decimal64* buffer, size_t buffer_len) { for (size_t i = 0; i < buffer_len; ++i) { - buffer[i] = bid64_from_uint64(random_uint64(), BID_ROUNDING_DOWN, &flag); + buffer[i] = bid64_from_uint64(random_uint64(), BID_ROUNDING_TO_NEAREST, &flag); } } -__attribute__ ((noinline)) void test_comparisons_64(Decimal64* data, const char* label) +BOOST_DECIMAL_NOINLINE void test_comparisons_64(Decimal64* data, const char* label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -119,18 +165,56 @@ __attribute__ ((noinline)) void test_comparisons_64(Decimal64* data, const char* printf("Comparisons <%-10s >: %-10" PRIu64 " us (s=%zu)\n", label, elapsed_time_us, s); } +Decimal128 random_decimal128(void) +{ + char str[64]; // Plenty of room for: -d.dddddddddddddddddddddddddddddddddE±eeee -__attribute__ ((__noinline__)) void generate_vector_128(Decimal128* buffer, size_t buffer_len) + // 1. Random sign (50/50) + char sign = (random_uint64() & 1) ? '-' : '+'; + + // 2. Random 34-digit significand + char digits[35]; + for (int i = 0; i < 34; i++) + { + digits[i] = '0' + (random_uint64() % 10); + } + + // Ensure first digit is non-zero (avoid leading zeros affecting value) + if (digits[0] == '0') + { + digits[0] = '1' + (random_uint64() % 9); + } + digits[34] = '\0'; + + // 3. Random exponent: -6143 to +6144 + int exp_range = 6144 - (-6143) + 1; // 12288 possible values + int exponent = (int)(random_uint64() % exp_range) - 6143; + + // 4. Build string: "±D.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE±EEEE" + snprintf(str, sizeof(str), "%c%c.%sE%+d", + sign, + digits[0], // integer part (1 digit) + &digits[1], // fractional part (33 digits) + exponent); + + // 5. Parse to decimal128 + _IDEC_flags flags = 0; + Decimal128 result = bid128_from_string(str, BID_ROUNDING_TO_NEAREST, &flags); + + return result; +} + +BOOST_DECIMAL_NOINLINE void generate_vector_128(Decimal128* buffer, size_t buffer_len) { size_t i = 0; while (i < buffer_len) { - buffer[i] = bid128_from_uint64(random_uint64()); + buffer[i] = random_decimal128(); ++i; } } -__attribute__ ((__noinline__)) void test_comparisons_128(Decimal128* data, const char* label) +BOOST_DECIMAL_NOINLINE void test_comparisons_128(Decimal128* data, const char* label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -162,26 +246,26 @@ __attribute__ ((__noinline__)) void test_comparisons_128(Decimal128* data, const typedef Decimal32 (*operation_32)(Decimal32, Decimal32); -__attribute__ ((noinline)) Decimal32 add_32(Decimal32 a, Decimal32 b) +BOOST_DECIMAL_NOINLINE Decimal32 add_32(Decimal32 a, Decimal32 b) { - return bid32_add(a, b, BID_ROUNDING_DOWN, &flag); + return bid32_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal32 sub_32(Decimal32 a, Decimal32 b) +BOOST_DECIMAL_NOINLINE Decimal32 sub_32(Decimal32 a, Decimal32 b) { - return bid32_sub(a, b, BID_ROUNDING_DOWN, &flag); + return bid32_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal32 mul_32(Decimal32 a, Decimal32 b) +BOOST_DECIMAL_NOINLINE Decimal32 mul_32(Decimal32 a, Decimal32 b) { - return bid32_mul(a, b, BID_ROUNDING_DOWN, &flag); + return bid32_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal32 div_32(Decimal32 a, Decimal32 b) +BOOST_DECIMAL_NOINLINE Decimal32 div_32(Decimal32 a, Decimal32 b) { - return bid32_div(a, b, BID_ROUNDING_DOWN, &flag); + return bid32_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) void test_two_element_operation_32(Decimal32* data, operation_32 op, const char* label, const char* op_label) +BOOST_DECIMAL_NOINLINE void test_two_element_operation_32(Decimal32* data, operation_32 op, const char* label, const char* op_label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -207,27 +291,27 @@ __attribute__ ((noinline)) void test_two_element_operation_32(Decimal32* data, o typedef Decimal64 (*operation_64)(Decimal64, Decimal64); -__attribute__ ((noinline)) Decimal64 add_64(Decimal64 a, Decimal64 b) +BOOST_DECIMAL_NOINLINE Decimal64 add_64(Decimal64 a, Decimal64 b) { - return bid64_add(a, b, BID_ROUNDING_DOWN, &flag); + return bid64_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal64 sub_64(Decimal64 a, Decimal64 b) +BOOST_DECIMAL_NOINLINE Decimal64 sub_64(Decimal64 a, Decimal64 b) { - return bid64_sub(a, b, BID_ROUNDING_DOWN, &flag); + return bid64_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal64 mul_64(Decimal64 a, Decimal64 b) +BOOST_DECIMAL_NOINLINE Decimal64 mul_64(Decimal64 a, Decimal64 b) { - return bid64_mul(a, b, BID_ROUNDING_DOWN, &flag); + return bid64_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) Decimal64 div_64(Decimal64 a, Decimal64 b) +BOOST_DECIMAL_NOINLINE Decimal64 div_64(Decimal64 a, Decimal64 b) { - return bid64_div(a, b, BID_ROUNDING_DOWN, &flag); + return bid64_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((noinline)) void test_two_element_operation_64(Decimal64* data, operation_64 op, const char* label, const char* op_label) +BOOST_DECIMAL_NOINLINE void test_two_element_operation_64(Decimal64* data, operation_64 op, const char* label, const char* op_label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -254,27 +338,27 @@ __attribute__ ((noinline)) void test_two_element_operation_64(Decimal64* data, o typedef Decimal128 (*operation_128)(Decimal128, Decimal128); -__attribute__ ((__noinline__)) Decimal128 add_128(Decimal128 a, Decimal128 b) +BOOST_DECIMAL_NOINLINE Decimal128 add_128(Decimal128 a, Decimal128 b) { - return bid128_add(a, b, BID_ROUNDING_DOWN, &flag); + return bid128_add(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((__noinline__)) Decimal128 sub_128(Decimal128 a, Decimal128 b) +BOOST_DECIMAL_NOINLINE Decimal128 sub_128(Decimal128 a, Decimal128 b) { - return bid128_sub(a, b, BID_ROUNDING_DOWN, &flag); + return bid128_sub(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((__noinline__)) Decimal128 mul_128(Decimal128 a, Decimal128 b) +BOOST_DECIMAL_NOINLINE Decimal128 mul_128(Decimal128 a, Decimal128 b) { - return bid128_mul(a, b, BID_ROUNDING_DOWN, &flag); + return bid128_mul(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((__noinline__)) Decimal128 div_128(Decimal128 a, Decimal128 b) +BOOST_DECIMAL_NOINLINE Decimal128 div_128(Decimal128 a, Decimal128 b) { - return bid128_div(a, b, BID_ROUNDING_DOWN, &flag); + return bid128_div(a, b, BID_ROUNDING_TO_NEAREST, &flag); } -__attribute__ ((__noinline__)) void test_two_element_operation_128(Decimal128* data, operation_128 op, const char* label, const char* op_label) +BOOST_DECIMAL_NOINLINE void test_two_element_operation_128(Decimal128* data, operation_128 op, const char* label, const char* op_label) { struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); @@ -304,8 +388,10 @@ int main() // One time init of random number generator srand(time(NULL)); + #ifndef _WIN32 fedisableexcept(FE_ALL_EXCEPT); - + #endif + Decimal32* d32_array = malloc(K * sizeof(Decimal32)); Decimal64* d64_array = malloc(K * sizeof(Decimal64)); Decimal128* d128_array = malloc(K * sizeof(Decimal128)); diff --git a/test/compare_dec128_and_fast.cpp b/test/compare_dec128_and_fast.cpp index e1fb15b3f..7f74c9358 100644 --- a/test/compare_dec128_and_fast.cpp +++ b/test/compare_dec128_and_fast.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -23,9 +24,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(8U); // Number of trials +static constexpr auto N = static_cast(8); // Number of trials #endif static std::mt19937_64 rng(42); @@ -130,6 +131,13 @@ void test_sub() const decimal_fast128_t dec128_fast_2 {val2}; const decimal_fast128_t dec128_fast_res {dec128_fast_1 + dec128_fast_2}; + if (isinf(dec128_1) && isinf(dec128_2) && isinf(dec128_fast_1) && isinf(dec128_fast_2)) + { + BOOST_TEST(isinf(dec128_res) || isnan(dec128_res)); + BOOST_TEST(isinf(dec128_fast_res) || isnan(dec128_fast_res)); + continue; + } + if (!BOOST_TEST_EQ(static_cast(dec128_res), static_cast(dec128_fast_res))) { // LCOV_EXCL_START @@ -272,6 +280,12 @@ void test_div() const decimal_fast128_t dec128_fast_2 {val2}; const decimal_fast128_t dec128_fast_res {dec128_fast_1 / dec128_fast_2}; + if (isinf(dec128_1) && isinf(dec128_2) && isinf(dec128_fast_1) && isinf(dec128_fast_2)) + { + BOOST_TEST(isnan(dec128_res) && isnan(dec128_fast_res)); + continue; + } + if (!BOOST_TEST_EQ(static_cast(dec128_res), static_cast(dec128_fast_res))) { // LCOV_EXCL_START diff --git a/test/compile_tests/charconv_before_types_compile.cpp b/test/compile_tests/charconv_before_types_compile.cpp new file mode 100644 index 000000000..e4295b003 --- /dev/null +++ b/test/compile_tests/charconv_before_types_compile.cpp @@ -0,0 +1,16 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + return 0; +} diff --git a/test/cover/make_gcov_02_files.gmk b/test/cover/make_gcov_02_files.gmk index 711161a85..bc1638d18 100644 --- a/test/cover/make_gcov_02_files.gmk +++ b/test/cover/make_gcov_02_files.gmk @@ -12,6 +12,9 @@ FILES_EXCLUDE := $(PATH_SRC)/concepts_test.cpp $(PATH_SRC)/link_1.cpp \ $(PATH_SRC)/link_2.cpp \ $(PATH_SRC)/link_3.cpp \ + $(PATH_SRC)/limits_link_1.cpp \ + $(PATH_SRC)/limits_link_2.cpp \ + $(PATH_SRC)/limits_link_3.cpp \ $(PATH_SRC)/test_bad_evaluation_method.cpp \ $(PATH_SRC)/test_explicit_floats.cpp \ $(PATH_SRC)/test_from_chars.cpp \ diff --git a/test/github_issue_1026.cpp b/test/github_issue_1026.cpp new file mode 100644 index 000000000..5a75afc42 --- /dev/null +++ b/test/github_issue_1026.cpp @@ -0,0 +1,79 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1026 + +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + +using namespace boost::decimal; +using namespace boost::decimal::literals; + +int main() +{ + // Round ties to even + + BOOST_TEST_EQ("1234567.49"_DF, "1234567"_DF); + BOOST_TEST_EQ("1234567.50"_DF, "1234568"_DF); + BOOST_TEST_EQ("1234567.51"_DF, "1234568"_DF); + + BOOST_TEST_EQ("9999999991234567.49"_DD, "9999999991234567"_DD); + BOOST_TEST_EQ("9999999991234567.50"_DD, "9999999991234568"_DD); + BOOST_TEST_EQ("9999999991234567.51"_DD, "9999999991234568"_DD); + + BOOST_TEST_EQ("9999999999999999999999999991234567.49"_DL, "9999999999999999999999999991234567"_DL); + BOOST_TEST_EQ("9999999999999999999999999991234567.50"_DL, "9999999999999999999999999991234568"_DL); + BOOST_TEST_EQ("9999999999999999999999999991234567.51"_DL, "9999999999999999999999999991234568"_DL); + + BOOST_TEST_EQ("2345678.49"_DF, "2345678"_DF); + BOOST_TEST_EQ("2345678.50"_DF, "2345678"_DF); + BOOST_TEST_EQ("2345678.51"_DF, "2345679"_DF); + + BOOST_TEST_EQ("9999999992345678.49"_DD, "9999999992345678"_DD); + BOOST_TEST_EQ("9999999992345678.50"_DD, "9999999992345678"_DD); + BOOST_TEST_EQ("9999999992345678.51"_DD, "9999999992345679"_DD); + + BOOST_TEST_EQ("9999999999999999999999999992345678.49"_DL, "9999999999999999999999999992345678"_DL); + BOOST_TEST_EQ("9999999999999999999999999992345678.50"_DL, "9999999999999999999999999992345678"_DL); + BOOST_TEST_EQ("9999999999999999999999999992345678.51"_DL, "9999999999999999999999999992345679"_DL); + + BOOST_TEST_EQ(("0"_DF + "8.4e-96"_DF), "8.4e-96"_DF); + BOOST_TEST_EQ(("0"_DF + std::numeric_limits::denorm_min()), std::numeric_limits::denorm_min()); + BOOST_TEST_EQ((std::numeric_limits::denorm_min() + std::numeric_limits::denorm_min()), 2*std::numeric_limits::denorm_min()); + + BOOST_TEST_EQ(("0"_DD + "8.4e-96"_DD), "8.4e-96"_DD); + BOOST_TEST_EQ(("0"_DD + std::numeric_limits::denorm_min()), std::numeric_limits::denorm_min()); + BOOST_TEST_EQ((std::numeric_limits::denorm_min() + std::numeric_limits::denorm_min()), 2*std::numeric_limits::denorm_min()); + + BOOST_TEST_EQ("0"_DF + "8.4e-100"_DF, "8.4e-100"_DF); + BOOST_TEST_EQ("1"_DF * "1e-101"_DF, "1e-101"_DF); + BOOST_TEST_EQ("1e-101"_DF / "1"_DF, "1e-101"_DF); + + BOOST_TEST_EQ("0"_DD + "8.4e-100"_DD, "8.4e-100"_DD); + BOOST_TEST_EQ("1"_DD * "1e-101"_DD, "1e-101"_DD); + BOOST_TEST_EQ("1e-101"_DD / "1"_DD, "1e-101"_DD); + + BOOST_TEST_EQ("5.24289e-96"_DF / "1"_DF, "5.24289e-96"_DF); + + BOOST_TEST_EQ("1"_DF / "5.24289e-96"_DF, "1.907345e+95"_DF); + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + const auto new_rounding_mode = fesetround(rounding_mode::fe_dec_to_nearest_from_zero); + BOOST_TEST(new_rounding_mode == rounding_mode::fe_dec_to_nearest_from_zero); + BOOST_TEST_EQ(decimal32_t(100000, -105), "1e-100"_df); + + #endif // BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + return boost::report_errors(); +} + diff --git a/test/github_issue_1035.cpp b/test/github_issue_1035.cpp new file mode 100644 index 000000000..7bde48d2e --- /dev/null +++ b/test/github_issue_1035.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1035 + +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include +#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + +using namespace boost::decimal; +using namespace boost::decimal::literals; + +int main() +{ + std::mt19937_64 rng(42); + std::uniform_int_distribution dist(1, 1); + + const auto previously_inf {"5e+95"_DF * dist(rng)}; + BOOST_TEST_EQ(previously_inf, "500000e+90"_DF); + + #ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + return boost::report_errors(); + #else + + fesetround(rounding_mode::fe_dec_downward); + BOOST_TEST_EQ("5e+50"_DF * dist(rng) - "4e+40"_DF, "4.999999e+50"_DF); + BOOST_TEST_EQ("5e+95"_DF * dist(rng) - "4e-100"_DF, "4.999999e+95"_DF); + BOOST_TEST_EQ("-5e+95"_DF * dist(rng) + "4e-100"_DF, "-4.999999e+95"_DF); + BOOST_TEST_EQ("-5e+95"_DL * dist(rng) + "4e-100"_DL, "-4.999999999999999999999999999999999e+95"_DL); + + fesetround(rounding_mode::fe_dec_upward); + BOOST_TEST_EQ("5e+50"_DF * dist(rng) + "4e+40"_DF, "5.000001e+50"_DF); + BOOST_TEST_EQ("5e+95"_DF * dist(rng) + "4e-100"_DF, "5.000001e+95"_DF); + BOOST_TEST_EQ("-5e+95"_DF * dist(rng) - "4e-100"_DF, "-5.000001e+95"_DF); + BOOST_TEST_EQ("-5e+95"_DL * dist(rng) - "4e-100"_DL, "-5.000000000000000000000000000000001e+95"_DL); + + return boost::report_errors(); + + #endif +} diff --git a/test/github_issue_1054.cpp b/test/github_issue_1054.cpp new file mode 100644 index 000000000..b16222a88 --- /dev/null +++ b/test/github_issue_1054.cpp @@ -0,0 +1,128 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1054 + +#if defined(__GNUC__) && (__GNUC__ >= 7) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + +using namespace boost::decimal; + +// https://en.cppreference.com/w/cpp/compiler_support/17 +#if (defined(__GNUC__) && __GNUC__ >= 11) || \ +((defined(__clang__) && __clang_major__ >= 14 && !defined(__APPLE__)) || (defined(__clang__) && defined(__APPLE__) && __clang_major__ >= 16)) || \ +(defined(_MSC_VER) && _MSC_VER >= 1924) + +# if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# include +# define BOOST_DECIMAL_TEST_CHARCONV +# endif + +#endif + +#ifdef BOOST_DECIMAL_TEST_CHARCONV + +template +void endptr_using_from_chars(const std::string& str) +{ + auto get_endptr_1 = [](const auto& s) { + DecimalType x; + return boost::decimal::from_chars(s.data(), s.data() + s.size(), x).ptr; + }; + auto get_endptr_2 = [](const auto& s) { + double x; + return std::from_chars(s.data(), s.data() + s.size(), x).ptr; + }; + BOOST_TEST_CSTR_EQ(get_endptr_1(str), get_endptr_2(str)); +} + +#else + +template +void endptr_using_from_chars(const std::string&) {} + +#endif + +template +void endptr_using_strtod(const std::string& str) +{ + auto get_endptr_1 = [](const auto& s) { + char* ptr; + boost::decimal::strtod(s.data(), &ptr); + return ptr; + }; + auto get_endptr_2 = [](const auto& s) { + char* ptr; + std::strtod(s.data(), &ptr); + return ptr; + }; + + BOOST_TEST_CSTR_EQ(get_endptr_1(str), get_endptr_2(str)); +} + +template +void check_endptr() +{ + // endptr should point to the character after "inf" + endptr_using_from_chars("info"); + endptr_using_strtod("info"); + + // endptr should points to the beginning of the string + endptr_using_from_chars("inch"); + endptr_using_strtod("inch"); + + // endptr should point to the character after "nan" + endptr_using_from_chars("nano"); + endptr_using_strtod("nano"); + + // endptr should point to the beginning of the string + endptr_using_from_chars("name"); + endptr_using_strtod("name"); + + #ifdef __APPLE__ + // Darwin's strtod works incorrectly for nan with payload, so skip the test. + #else + // endptr should point to the character after "nan(PAYLOAD)" + endptr_using_from_chars("nan(PAYLOAD)"); + endptr_using_strtod("nan(PAYLOAD)"); + + // endptr should point to the character after "nan(123)" + endptr_using_from_chars("nan(123)"); + endptr_using_strtod("nan(123)"); + + // endptr should point to the character after "nan" + endptr_using_from_chars("nan(..BAD..)"); + endptr_using_strtod("nan(..BAD..)"); + #endif +} + +int main() +{ + // Restrict testing to a small cohort of compilers that we know generate correct results + #if defined(__GNUC__) && __GNUC__ >= 10 && !defined(__MINGW32__) + + check_endptr(); + check_endptr(); + check_endptr(); + check_endptr(); + check_endptr(); + check_endptr(); + + #endif + + return boost::report_errors(); +} diff --git a/test/github_issue_1055.cpp b/test/github_issue_1055.cpp new file mode 100644 index 000000000..6300a6b7f --- /dev/null +++ b/test/github_issue_1055.cpp @@ -0,0 +1,71 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1055 + +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + +using namespace boost::decimal; + +template +void endpos_using_istream(const std::string& str, const int expected_endpos) +{ + std::istringstream is(str); + DecimalType x; + + is >> x; + is.clear(); + const auto endpos = is.tellg(); + + if (!BOOST_TEST_EQ(endpos, expected_endpos)) + { + // LCOV_EXCL_START + std::cerr << "String: " << str << '\n' + << "Expected: " << expected_endpos << '\n' + << "Got: " << is.tellg() << std::endl; + // LCOV_EXCL_STOP + } +} + +template +void check_endpos() +{ + // Expected end positions match double handling with GCC 15.2 on x64 + endpos_using_istream("Decimal!", 0); + endpos_using_istream("127.0.0.1", 5); + endpos_using_istream("nullptr", 0); + + // Handling of nan and infinity is already an exception to what is supposed to happen + // We'll claim that it's like the IP address case where everything past INF or NAN is considered junk + endpos_using_istream("INF", 3); + endpos_using_istream("INFinity", 3); + endpos_using_istream("INFinite", 3); + + endpos_using_istream("nan", 3); + endpos_using_istream("nanfinity", 3); + endpos_using_istream("nan(snan)", 9); + endpos_using_istream("nan(snan)JUNK", 9); +} + +int main() +{ + check_endpos(); + check_endpos(); + check_endpos(); + + check_endpos(); + check_endpos(); + check_endpos(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1057.cpp b/test/github_issue_1057.cpp new file mode 100644 index 000000000..9a7cb3dfd --- /dev/null +++ b/test/github_issue_1057.cpp @@ -0,0 +1,85 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1057 + +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + +template +void convert_leading_plus_by_strtod() +{ + DecimalType x = boost::decimal::strtod("+0.1", nullptr); + BOOST_TEST_EQ(x, DecimalType(1, -1)); +} + +template +void convert_leading_space_by_strtod() +{ + DecimalType x = boost::decimal::strtod(" \t 0.1", nullptr); + BOOST_TEST_EQ(x, DecimalType(1, -1)); +} + +template +void test_both() +{ + DecimalType x = boost::decimal::strtod(" \n \t +0.1", nullptr); + BOOST_TEST_EQ(x, DecimalType(1, -1)); + + x = boost::decimal::strtod(" \n \t -0.2", nullptr); + BOOST_TEST_EQ(x, -DecimalType(2, -1)); +} + +template +void test_segfault() +{ + DecimalType x = boost::decimal::strtod(" \n \t +", nullptr); + BOOST_TEST(boost::decimal::isnan(x)); + + x = boost::decimal::strtod(" \n \t", nullptr); + BOOST_TEST(boost::decimal::isnan(x)); +} + +int main() +{ + using namespace boost::decimal; + + convert_leading_plus_by_strtod(); + convert_leading_plus_by_strtod(); + convert_leading_plus_by_strtod(); + convert_leading_plus_by_strtod(); + convert_leading_plus_by_strtod(); + convert_leading_plus_by_strtod(); + + convert_leading_space_by_strtod(); + convert_leading_space_by_strtod(); + convert_leading_space_by_strtod(); + convert_leading_space_by_strtod(); + convert_leading_space_by_strtod(); + convert_leading_space_by_strtod(); + + test_both(); + test_both(); + test_both(); + test_both(); + test_both(); + test_both(); + + test_segfault(); + test_segfault(); + test_segfault(); + test_segfault(); + test_segfault(); + test_segfault(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1087.cpp b/test/github_issue_1087.cpp new file mode 100644 index 000000000..a22c614e7 --- /dev/null +++ b/test/github_issue_1087.cpp @@ -0,0 +1,30 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1087 + +#include +#include + +using namespace boost::decimal; + +template +void test() +{ + T val {-3, 3, true}; + BOOST_TEST_EQ(val, T(UINT32_C(3), 3, true)); +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return 0; +} diff --git a/test/github_issue_1091.cpp b/test/github_issue_1091.cpp new file mode 100644 index 000000000..0c5b80162 --- /dev/null +++ b/test/github_issue_1091.cpp @@ -0,0 +1,51 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1091 + +#include +#include + +using namespace boost::decimal; + +template +void test() +{ + constexpr T one {1u, 0}; + T low {std::numeric_limits::lowest()}; + BOOST_TEST(!isinf(low)); + + low *= 2; + + BOOST_TEST(low < one); + BOOST_TEST(one > low); + BOOST_TEST(isinf(low)); + + T high {std::numeric_limits::max()}; + BOOST_TEST(!isinf(high)); + + high *= 2; + + BOOST_TEST(high > one); + BOOST_TEST(one < high); + BOOST_TEST(isinf(high)); + + T min {-std::numeric_limits::denorm_min()}; + + min /= 2; + + BOOST_TEST(min < one); + BOOST_TEST(min == (one - one)); + BOOST_TEST(signbit(min)); +} + +int main() +{ + test(); + test(); + test(); + + return boost::report_errors(); +} + diff --git a/test/github_issue_1094.cpp b/test/github_issue_1094.cpp new file mode 100644 index 000000000..33e7eaf91 --- /dev/null +++ b/test/github_issue_1094.cpp @@ -0,0 +1,34 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1094 + +#include +#include + +using namespace boost::decimal; + +int main() +{ + BOOST_TEST(boost::decimal::fegetround() == _boost_decimal_global_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == _boost_decimal_global_runtime_rounding_mode); + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + BOOST_TEST(fesetround(rounding_mode::fe_dec_upward) == rounding_mode::fe_dec_upward); + BOOST_TEST(boost::decimal::fegetround() != _boost_decimal_global_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == _boost_decimal_global_runtime_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == rounding_mode::fe_dec_upward); + + #else + + BOOST_TEST(fesetround(rounding_mode::fe_dec_upward) == _boost_decimal_global_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == _boost_decimal_global_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == _boost_decimal_global_runtime_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == rounding_mode::fe_dec_default); + + #endif + + return boost::report_errors(); +} diff --git a/test/github_issue_1105.cpp b/test/github_issue_1105.cpp new file mode 100644 index 000000000..2baf85f64 --- /dev/null +++ b/test/github_issue_1105.cpp @@ -0,0 +1,82 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1105 + +#include +#include +#include + +static std::mt19937_64 rng(42); + +using namespace boost::decimal; + +template +void test() +{ + std::uniform_int_distribution dist(1, 1); + + const T one {dist(rng), 0}; + const T zero {0, 0}; + + const T val {dist(rng), -5}; + int val_exp {}; + const auto val_sig {frexp10(val, &val_exp)}; + + const auto next {nextafter(val, one)}; + int next_exp {}; + const auto next_sig {frexp10(next, &next_exp)}; + BOOST_TEST_EQ(next_exp, val_exp); + BOOST_TEST_EQ(next_sig, val_sig + 1U); + + const auto prev {nextafter(val, zero)}; + int prev_exp {}; + const auto prev_sig {frexp10(prev, &prev_exp)}; + BOOST_TEST_EQ(prev_exp, val_exp - 1); + BOOST_TEST_EQ(prev_sig, detail::max_significand_v); + + // Max significand + 1 should be reduced + const auto original_val {nextafter(prev, one)}; + int original_exp {}; + const auto original_sig {frexp10(original_val, &original_exp)}; + BOOST_TEST_EQ(original_exp, val_exp); + BOOST_TEST_EQ(original_sig, val_sig); + + const auto zero_next {nextafter(zero, one)}; + BOOST_TEST_EQ(zero_next, std::numeric_limits::denorm_min()); +} + +// Per IEEE 754 nextafter is allowed to break cohort +void test_non_preserving() +{ + const auto val = decimal32_t{"1e-100"}; + const auto two_val = decimal32_t{2, boost::decimal::detail::etiny_v}; + const auto one = decimal32_t{"1e0"}; + const auto next = nextafter(val,one); + const auto between = decimal32_t{"11e-101"}; + + BOOST_TEST_LE(val, between); + BOOST_TEST_EQ(next, between); + BOOST_TEST_LE(two_val, next); + + const auto nines_value = decimal32_t{"99e-101"}; + const auto next_nines_res = decimal32_t{"991e-102"}; + const auto res = nextafter(nines_value, one); + BOOST_TEST_EQ(res, next_nines_res); + + const auto wrap_value = decimal32_t{"9999999e-107"}; + const auto next_after_wrap = nextafter(wrap_value, one); + BOOST_TEST_GT(next_after_wrap, wrap_value); +} + +int main() +{ + test(); + test(); + test(); + + test_non_preserving(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1106.cpp b/test/github_issue_1106.cpp new file mode 100644 index 000000000..505169ad3 --- /dev/null +++ b/test/github_issue_1106.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1106 + +#include +#include +#include +#include + +using namespace boost::decimal; + +template +void test() +{ + using std::isinf; + using std::signbit; + + const auto a {std::numeric_limits::lowest() / 99}; + const T b {100}; + const auto c {a * b}; + + BOOST_TEST(isinf(c)); + BOOST_TEST(signbit(c)); + + // The same as above in principle + const auto d {a / (1/b)}; + BOOST_TEST(isinf(d)); + BOOST_TEST(signbit(d)); +} + +int main() +{ + #ifndef _MSC_VER + test(); + test(); + #endif + + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1107.cpp b/test/github_issue_1107.cpp new file mode 100644 index 000000000..b0af7290f --- /dev/null +++ b/test/github_issue_1107.cpp @@ -0,0 +1,120 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1107 + +#include +#include +#include +#include + +using namespace boost::decimal; + +static std::mt19937_64 rng(42); +static std::uniform_int_distribution dist(1, 10); + +// 7.2.b +template +void test_mul() +{ + const T a {dist(rng) * 0}; + const T b {dist(rng) * std::numeric_limits::infinity()}; + + BOOST_TEST(a == 0); + BOOST_TEST(isinf(b)); + + BOOST_TEST(isnan(a * b)); + BOOST_TEST(isnan(b * a)); +} + +// 7.2.d +template +void test_add_sub() +{ + const T a {dist(rng) * std::numeric_limits::infinity()}; + const T b {dist(rng) * -std::numeric_limits::infinity()}; + + BOOST_TEST(!signbit(a)); + BOOST_TEST(signbit(b)); + + BOOST_TEST(isnan(b + a)); // -inf + inf + BOOST_TEST(isnan(a + b)); // inf - inf + BOOST_TEST(isnan(b - b)); // -inf + inf + BOOST_TEST(isnan(a - a)); // inf - inf +} + +// 7.2.e +template +void test_div() +{ + const T a {dist(rng) * 0}; + const T b {dist(rng) * std::numeric_limits::infinity()}; + + BOOST_TEST(a == 0); + BOOST_TEST(isinf(b)); + + BOOST_TEST(isnan(a / a)); + BOOST_TEST(isnan(b / b)); +} + +// 7.2.f +template +void test_remainder() +{ + const T a {dist(rng) * 0}; + const T b {dist(rng) * std::numeric_limits::infinity()}; + const T c {dist(rng)}; + + BOOST_TEST(isnan(remainder(b, c))); + BOOST_TEST(isnan(remainder(c, a))); +} + +// 7.2.g +template +void test_sqrt() +{ + const T val {-dist(rng)}; + const auto sqrt_val {sqrt(val)}; + BOOST_TEST(isnan(sqrt_val)); +} + +int main() +{ + test_add_sub(); + test_add_sub(); + test_add_sub(); + test_add_sub(); + test_add_sub(); + test_add_sub(); + + test_mul(); + test_mul(); + test_mul(); + test_mul(); + test_mul(); + test_mul(); + + test_div(); + test_div(); + test_div(); + test_div(); + test_div(); + test_div(); + + test_remainder(); + test_remainder(); + test_remainder(); + test_remainder(); + test_remainder(); + test_remainder(); + + test_sqrt(); + test_sqrt(); + test_sqrt(); + test_sqrt(); + test_sqrt(); + test_sqrt(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1110.cpp b/test/github_issue_1110.cpp new file mode 100644 index 000000000..db571f011 --- /dev/null +++ b/test/github_issue_1110.cpp @@ -0,0 +1,67 @@ +// Copyright 2025 Christopher Kormanyos +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1110 + +#include +#include +#include + +#include + +#include +#include +#include + +using namespace boost::decimal; + +namespace local { + +auto test() -> void; + +auto test() -> void +{ + const boost::decimal::decimal128_t one { 1 }; + const boost::decimal::decimal128_t del { 1, -32 }; + const boost::decimal::decimal128_t sum { one + del }; + + const boost::decimal::decimal128_t sqr { sqrt(sum) }; + + { + std::stringstream strm { }; + + strm << std::setprecision(std::numeric_limits::digits10) << sqr; + + BOOST_TEST_CSTR_EQ(strm.str().c_str(), "1.000000000000000000000000000000005"); + } + + const boost::decimal::decimal128_t cbr { cbrt(sum) }; + + { + std::stringstream strm { }; + + strm << std::setprecision(std::numeric_limits::digits10)<< cbr; + + BOOST_TEST_CSTR_EQ(strm.str().c_str(), "1.000000000000000000000000000000003"); + } + + const boost::decimal::decimal128_t lgt { log10(sum) }; + + { + std::stringstream strm { }; + + strm << std::setprecision(std::numeric_limits::digits10)<< lgt; + + BOOST_TEST_CSTR_EQ(strm.str().c_str(), "4.4e-33"); + } +} + +} // namespace local + +auto main() -> int +{ + local::test(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1112.cpp b/test/github_issue_1112.cpp new file mode 100644 index 000000000..253bda161 --- /dev/null +++ b/test/github_issue_1112.cpp @@ -0,0 +1,63 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1112 + +#include +#include +#include + +static std::mt19937_64 rng(42); +std::uniform_int_distribution<> dist(-1, -1); + +using namespace boost::decimal; + +template +void reproducer() +{ + const auto dec_res {static_cast(nearbyint(T{2325, -1}))}; + const auto dbl_res {static_cast(std::nearbyint(232.5))}; + BOOST_TEST_EQ(dec_res, dbl_res); +} + +template +void test_rounding_up() +{ + const auto mode {boost::decimal::fesetround(rounding_mode::fe_dec_upward)}; + if (mode != rounding_mode::fe_dec_default) + { + const T value {2325, dist(rng)}; // The result will be wrong if computed at compile time + const auto dec_res {static_cast(nearbyint(value))}; + BOOST_TEST_EQ(dec_res, 233); + } +} + +template +void test_rounding_down() +{ + const auto mode {boost::decimal::fesetround(rounding_mode::fe_dec_downward)}; + if (mode != rounding_mode::fe_dec_default) + { + const T value {2325, dist(rng)}; // The result will be wrong if computed at compile time + const auto dec_res {static_cast(nearbyint(value))}; + BOOST_TEST_EQ(dec_res, 232); + } +} + +int main() +{ + reproducer(); + reproducer(); + reproducer(); + + test_rounding_up(); + test_rounding_up(); + test_rounding_up(); + + test_rounding_down(); + test_rounding_down(); + test_rounding_down(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1174.cpp b/test/github_issue_1174.cpp new file mode 100644 index 000000000..113c197f8 --- /dev/null +++ b/test/github_issue_1174.cpp @@ -0,0 +1,53 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1174 +// +// The decTest tests only apply to decimal64_t so we need to cover the other two as well + +#include +#include +#include + +static std::mt19937_64 rng(42); +static std::uniform_int_distribution dist(1, 1); + +using namespace boost::decimal; + +// These values are all from clamp.decTest +// The tests for decimal32_t and decimal128_t are derived from the values used here +template +void test() +{ + constexpr T zero {0}; + constexpr auto sub_min {std::numeric_limits::denorm_min()}; + const T a {dist(rng) * 7, detail::etiny_v}; + + BOOST_TEST_GT(a, zero); + + const T b {dist(rng) * 7, detail::etiny_v - 1}; + + BOOST_TEST_EQ(b, sub_min); + + const T c {dist(rng) * 7, detail::etiny_v - 2}; + + BOOST_TEST_EQ(c, zero); + + const T d {dist(rng) * 70, detail::etiny_v - 1}; + + BOOST_TEST_EQ(a, d); + + const T e {dist(rng) * 700, detail::etiny_v - 2}; + + BOOST_TEST_EQ(a, e); +} + +int main() +{ + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1260.cpp b/test/github_issue_1260.cpp new file mode 100644 index 000000000..63ce8cdb3 --- /dev/null +++ b/test/github_issue_1260.cpp @@ -0,0 +1,114 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1260 + +#include +#include +#include +#include + +template +void test() +{ + const T lhs {"1E34"}; + const T rhs {"-0.51"}; + const T res {"9999999999999999999999999999999999"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); + + const T sub_val {lhs - boost::decimal::abs(rhs)}; + BOOST_TEST_EQ(sub_val, res); +} + +template +void test2() +{ + const T lhs {"1E34"}; + const T rhs {"-0.501"}; + const T res {"9999999999999999999999999999999999"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); + + const T sub_val {lhs - boost::decimal::abs(rhs)}; + BOOST_TEST_EQ(sub_val, res); +} + +template +void test3() +{ + const T lhs {"1E34"}; + const T rhs {"-0.5001"}; + const T res {"9999999999999999999999999999999999"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); + + const T sub_val {lhs - boost::decimal::abs(rhs)}; + BOOST_TEST_EQ(sub_val, res); +} + +template +void test4() +{ + const T lhs {"1E34"}; + const T rhs {"-0.50001"}; + const T res {"9999999999999999999999999999999999"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); + + const T sub_val {lhs - boost::decimal::abs(rhs)}; + BOOST_TEST_EQ(sub_val, res); +} + +template +void test5() +{ + const T lhs {"5"}; + const T rhs {"-3"}; + const T res {"2"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); +} + +template +void test6() +{ + // Only an issue on 32-bit platforms + const T lhs {"10000e+9"}; + const T rhs {"7000"}; + const T res {"10000000007000"}; + + const T add_val {lhs + rhs}; + BOOST_TEST_EQ(add_val, res); +} + +int main() +{ + std::cerr << std::setprecision(std::numeric_limits::max_digits10); + + test(); + test(); + + test2(); + test2(); + + test3(); + test3(); + + test4(); + test4(); + + test5(); + test5(); + + test6(); + test6(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1294.cpp b/test/github_issue_1294.cpp new file mode 100644 index 000000000..f1b872d27 --- /dev/null +++ b/test/github_issue_1294.cpp @@ -0,0 +1,59 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1294 + +#include +#include + +using namespace boost::decimal; + +template +void test_round_down() +{ + const T val {"0.499"}; + constexpr T ref_1 {1}; + constexpr T ref_0 {0}; + + BOOST_TEST_EQ(ceil(val), ref_1); + BOOST_TEST_EQ(floor(val), ref_0); + BOOST_TEST_EQ(trunc(val), ref_0); + BOOST_TEST_EQ(round(val), ref_0); + BOOST_TEST_EQ(lround(val), 0L); + BOOST_TEST_EQ(nearbyint(val), 0); + BOOST_TEST_EQ(lrint(val), 0L); + BOOST_TEST_EQ(llrint(val), 0LL); +} + +template +void test() +{ + const T val {"0.999"}; + constexpr T ref_1 {1}; + constexpr T ref_0 {0}; + + BOOST_TEST_EQ(ceil(val), ref_1); + BOOST_TEST_EQ(floor(val), ref_0); + BOOST_TEST_EQ(trunc(val), ref_0); + BOOST_TEST_EQ(round(val), ref_1); + BOOST_TEST_EQ(lround(val), 1L); + BOOST_TEST_EQ(nearbyint(val), 1); + BOOST_TEST_EQ(lrint(val), 1L); + BOOST_TEST_EQ(llrint(val), 1LL); + + test_round_down(); +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} diff --git a/test/github_issue_1299.cpp b/test/github_issue_1299.cpp new file mode 100644 index 000000000..bd29361ec --- /dev/null +++ b/test/github_issue_1299.cpp @@ -0,0 +1,145 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1299 + +#include +#include +#include + +using namespace boost::decimal; + +enum class result_t +{ + lhs, + rhs, + qnan +}; + +enum class result_sign_t +{ + positive, + negative +}; + +template +void test_fmax_value(const T lhs, const T rhs, const result_t result, const result_sign_t sign = result_sign_t::positive, const int payload_value = 0) +{ + const auto res {fmax(lhs, rhs)}; + + switch (result) + { + case result_t::lhs: + BOOST_TEST_EQ(lhs, res); + break; + + case result_t::rhs: + BOOST_TEST_EQ(rhs, res); + break; + + case result_t::qnan: + BOOST_TEST(isnan(res)); + BOOST_TEST(!issignaling(res)); + + if (sign == result_sign_t::negative) + { + BOOST_TEST(signbit(res)); + } + + if (payload_value) + { + const auto payload {read_payload(res)}; + BOOST_TEST_EQ(static_cast(payload_value), payload); + } + + break; + } +} + +template +void test_fmin_value(const T lhs, const T rhs, const result_t result, const result_sign_t sign = result_sign_t::positive, const int payload_value = 0) +{ + const auto res {fmin(lhs, rhs)}; + + switch (result) + { + case result_t::lhs: + BOOST_TEST_EQ(lhs, res); + break; + + case result_t::rhs: + BOOST_TEST_EQ(rhs, res); + break; + + case result_t::qnan: + BOOST_TEST(isnan(res)); + BOOST_TEST(!issignaling(res)); + + if (sign == result_sign_t::negative) + { + BOOST_TEST(signbit(res)); + } + + if (payload_value) + { + const auto payload {read_payload(res)}; + BOOST_TEST_EQ(static_cast(payload_value), payload); + } + + break; + } +} + +template +void test_driver() +{ + test_fmax_value(T{5}, T{42}, result_t::rhs); + test_fmax_value(std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN(), result_t::lhs); + test_fmax_value(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN(), result_t::lhs); + test_fmax_value(T{5}, std::numeric_limits::quiet_NaN(), result_t::lhs); + + // Any operation on SNAN is invalid and returns QNAN with the same payload (as applicable) + test_fmax_value(std::numeric_limits::signaling_NaN(), T{5}, result_t::qnan); + test_fmax_value(std::numeric_limits::quiet_NaN(), std::numeric_limits::signaling_NaN(), result_t::qnan); + test_fmax_value(std::numeric_limits::signaling_NaN(), std::numeric_limits::quiet_NaN(), result_t::qnan); + + T snan_payload {"-sNaN97"}; + test_fmax_value(snan_payload, std::numeric_limits::quiet_NaN(), result_t::qnan, result_sign_t::negative, 97); + test_fmax_value(std::numeric_limits::quiet_NaN(), snan_payload, result_t::qnan, result_sign_t::negative, 97); + + snan_payload = -snan_payload; + T qnan_payload {"NaN100"}; + test_fmax_value(snan_payload, qnan_payload, result_t::qnan, result_sign_t::positive, 97); + + test_fmin_value(T{5}, T{42}, result_t::lhs); + test_fmin_value(std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN(), result_t::lhs); + test_fmin_value(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN(), result_t::lhs); + test_fmin_value(T{5}, std::numeric_limits::quiet_NaN(), result_t::lhs); + + // Any operation on SNAN is invalid and returns QNAN with the same payload (as applicable) + test_fmin_value(std::numeric_limits::signaling_NaN(), T{5}, result_t::qnan); + test_fmin_value(std::numeric_limits::quiet_NaN(), std::numeric_limits::signaling_NaN(), result_t::qnan); + test_fmin_value(std::numeric_limits::signaling_NaN(), std::numeric_limits::quiet_NaN(), result_t::qnan); + + snan_payload = T{"-sNaN97"}; + test_fmin_value(snan_payload, std::numeric_limits::quiet_NaN(), result_t::qnan, result_sign_t::negative, 97); + test_fmin_value(std::numeric_limits::quiet_NaN(), snan_payload, result_t::qnan, result_sign_t::negative, 97); + + snan_payload = -snan_payload; + qnan_payload = T{"NaN100"}; + test_fmin_value(snan_payload, qnan_payload, result_t::qnan, result_sign_t::positive, 97); +} + +int main() +{ + test_driver(); + test_driver(); + test_driver(); + + test_driver(); + test_driver(); + test_driver(); + + return boost::report_errors(); +} diff --git a/test/github_issue_426.cpp b/test/github_issue_426.cpp index 9c17f446a..26a0405f1 100644 --- a/test/github_issue_426.cpp +++ b/test/github_issue_426.cpp @@ -7,7 +7,14 @@ #include #include -#if defined(__GNUC__) && __GNUC__ >= 5 && __cplusplus > 202002L +#ifdef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + +int main() +{ + return 0; +} + +#elif defined(__GNUC__) && __GNUC__ >= 5 && __cplusplus > 202002L #include diff --git a/test/github_issue_448.cpp b/test/github_issue_448.cpp index 917918eac..837c56f58 100644 --- a/test/github_issue_448.cpp +++ b/test/github_issue_448.cpp @@ -4,11 +4,20 @@ // // See: https://github.com/cppalliance/decimal/issues/448 -#include #include + +#ifdef BOOST_DECIMAL_USE_MODULE + +import boost.decimal; + +#else + +#include #include #include +#endif + #if defined(__GNUC__) && __GNUC__ >= 8 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wclass-memaccess" diff --git a/test/github_issue_798.cpp b/test/github_issue_798.cpp index e6a831726..45aaa03c1 100644 --- a/test/github_issue_798.cpp +++ b/test/github_issue_798.cpp @@ -3,12 +3,19 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include #include #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + template void test_zero() { diff --git a/test/github_issue_799.cpp b/test/github_issue_799.cpp index 8aad70bea..ed23e58a1 100644 --- a/test/github_issue_799.cpp +++ b/test/github_issue_799.cpp @@ -2,10 +2,17 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + #ifdef BOOST_DECIMAL_HAS_INT128 template diff --git a/test/github_issue_802.cpp b/test/github_issue_802.cpp index 54c67d5c7..fe459f2a5 100644 --- a/test/github_issue_802.cpp +++ b/test/github_issue_802.cpp @@ -2,10 +2,17 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + void fasting() { using namespace boost::decimal; diff --git a/test/github_issue_805.cpp b/test/github_issue_805.cpp index 7323793f9..af5ee0847 100644 --- a/test/github_issue_805.cpp +++ b/test/github_issue_805.cpp @@ -2,10 +2,17 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + using namespace boost::decimal; template diff --git a/test/github_issue_808.cpp b/test/github_issue_808.cpp index d80f3fe84..35e74a6d8 100644 --- a/test/github_issue_808.cpp +++ b/test/github_issue_808.cpp @@ -2,8 +2,16 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif using namespace boost::decimal; diff --git a/test/github_issue_890.cpp b/test/github_issue_890.cpp index 49ef228f5..1f75e63f2 100644 --- a/test/github_issue_890.cpp +++ b/test/github_issue_890.cpp @@ -2,9 +2,16 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include -#include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif #if BOOST_DECIMAL_ENDIAN_LITTLE_BYTE diff --git a/test/github_issue_893.cpp b/test/github_issue_893.cpp deleted file mode 100644 index 92366052a..000000000 --- a/test/github_issue_893.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2025 Matt Borland -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt -// -// See: https://github.com/cppalliance/decimal/issues/893 - -#include -#include -#include - -void test_32() -{ - const std::array comp_values = { - UINT64_C(12345678), - UINT64_C(123456789), - UINT64_C(1234567890), - }; - - int res {8}; - - for (const auto& value : comp_values) - { - BOOST_TEST_EQ(boost::decimal::detail::num_digits(value), res); - BOOST_TEST_EQ(boost::decimal::detail::d32_constructor_num_digits(value), res++); - } -} - -void test_64() -{ - const std::array comp_values = { - UINT64_C(12345678901234567), - UINT64_C(123456789012345678), - UINT64_C(1234567890123456789), - UINT64_C(12345678901234567890), - }; - - int res {17}; - - for (const auto& value : comp_values) - { - BOOST_TEST_EQ(boost::decimal::detail::num_digits(value), res); - BOOST_TEST_EQ(boost::decimal::detail::d64_constructor_num_digits(value), res++); - } -} - -void test_128() -{ - const std::array comp_values = { - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1234567890123456789012345678901234), - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(12345678901234567890123456789012345), - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(123456789012345678901234567890123456), - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(1234567890123456789012345678901234567), - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(12345678901234567890123456789012345678), - BOOST_DECIMAL_DETAIL_INT128_UINT128_C(123456789012345678901234567890123456789), - }; - - int res {34}; - for (const auto& value : comp_values) - { - BOOST_TEST_EQ(boost::decimal::detail::num_digits(value), res); - BOOST_TEST_EQ(boost::decimal::detail::d128_constructor_num_digits(value), res++); - } - - #ifdef BOOST_DECIMAL_HAS_INT128 - - res = 34; - for (const auto& value : comp_values) - { - BOOST_TEST_EQ(boost::decimal::detail::num_digits(static_cast(value)), res); - BOOST_TEST_EQ(boost::decimal::detail::d128_constructor_num_digits(static_cast(value)), res++); - } - - #endif -} - -int main() -{ - test_32(); - test_64(); - test_128(); - - return boost::report_errors(); -} diff --git a/test/github_issue_900.cpp b/test/github_issue_900.cpp index 4813d5736..1f78a8314 100644 --- a/test/github_issue_900.cpp +++ b/test/github_issue_900.cpp @@ -2,8 +2,16 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif using namespace boost::decimal; diff --git a/test/github_issue_988.cpp b/test/github_issue_988.cpp index 626486b7f..cdf20efa1 100644 --- a/test/github_issue_988.cpp +++ b/test/github_issue_988.cpp @@ -4,8 +4,16 @@ // // See: https://github.com/cppalliance/decimal/issues/988 +#ifndef BOOST_DECIMAL_USE_MODULE #include +#endif + #include +#include + +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif using namespace boost::decimal; @@ -20,7 +28,7 @@ void test() const auto r = to_chars(buffer, buffer + sizeof(buffer), decimal_value); BOOST_TEST(r); *r.ptr = '\0'; - BOOST_TEST_CSTR_EQ(buffer, "-9.9999999999984e-01"); + BOOST_TEST_CSTR_EQ(buffer, "-0.99999999999984"); } void general_precision_test() diff --git a/test/limits_link_1.cpp b/test/limits_link_1.cpp new file mode 100644 index 000000000..d6a794507 --- /dev/null +++ b/test/limits_link_1.cpp @@ -0,0 +1,31 @@ +// Copyright 2023 Peter Dimov +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +void test_odr_use( int const* ); +void test_odr_use( std::size_t const* ); + +template void test() +{ + test_odr_use( &boost::decimal::formatting_limits::scientific_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::fixed_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::hex_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::cohort_preserving_scientific_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::general_format_max_chars ); + test_odr_use( &std::numeric_limits::digits10 ); +} + +void f1() +{ + test(); + test(); + test(); + + test(); + test(); + test(); +} diff --git a/test/limits_link_2.cpp b/test/limits_link_2.cpp new file mode 100644 index 000000000..c1106a02f --- /dev/null +++ b/test/limits_link_2.cpp @@ -0,0 +1,31 @@ +// Copyright 2023 Peter Dimov +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +void test_odr_use( int const* ); +void test_odr_use( std::size_t const* ); + +template void test() +{ + test_odr_use( &boost::decimal::formatting_limits::scientific_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::fixed_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::hex_format_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::cohort_preserving_scientific_max_chars ); + test_odr_use( &boost::decimal::formatting_limits::general_format_max_chars ); + test_odr_use( &std::numeric_limits::digits10 ); +} + +void f2() +{ + test(); + test(); + test(); + + test(); + test(); + test(); +} diff --git a/test/limits_link_3.cpp b/test/limits_link_3.cpp new file mode 100644 index 000000000..ed079e4c8 --- /dev/null +++ b/test/limits_link_3.cpp @@ -0,0 +1,23 @@ +// Copyright 2023 Peter Dimov +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +void f1(); +void f2(); + +int main() +{ + f1(); + f2(); +} + +void test_odr_use( int const* ) +{ +} + +void test_odr_use ( std::size_t const* ) +{ +} diff --git a/test/random_decimal128_comp.cpp b/test/random_decimal128_comp.cpp index e889ecd05..91fb8e8a0 100644 --- a/test/random_decimal128_comp.cpp +++ b/test/random_decimal128_comp.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -10,9 +11,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/random_decimal128_fast_comp.cpp b/test/random_decimal128_fast_comp.cpp index b8c643698..fd3acc882 100644 --- a/test/random_decimal128_fast_comp.cpp +++ b/test/random_decimal128_fast_comp.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -10,9 +11,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/random_decimal128_fast_math.cpp b/test/random_decimal128_fast_math.cpp index 188b76070..ae7d9a44c 100644 --- a/test/random_decimal128_fast_math.cpp +++ b/test/random_decimal128_fast_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -20,9 +21,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); @@ -302,6 +303,11 @@ void random_mixed_multiplication(T lower, T upper) BOOST_TEST(isinf(dist(rng) * std::numeric_limits::infinity() * T(dist(rng)))); BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() * T(dist(rng)) * dist(rng))); BOOST_TEST(isnan(dist(rng) * std::numeric_limits::quiet_NaN() * T(dist(rng)))); + + const auto value {dist(rng)}; + decimal_fast128_t one_mul {1}; + one_mul *= value; + BOOST_TEST(one_mul == value); } template @@ -324,7 +330,7 @@ void spot_check_mul(T val1, T val2) << "\nInt res: " << decimal_fast128_t{val1 * val2} << std::endl; // LCOV_EXCL_STOP } -}; +} template void random_division(T lower, T upper) @@ -433,7 +439,10 @@ void random_mixed_division(T lower, T upper) BOOST_TEST(isnan(dist(rng) / std::numeric_limits::quiet_NaN() * T(dist(rng)))); BOOST_TEST_EQ(abs(dist(rng) / std::numeric_limits::infinity() * T(dist(rng))), zero); BOOST_TEST(isinf(decimal_fast128_t(dist(rng)) / 0 * dist(rng))); + BOOST_TEST(isinf(dist(rng) / zero)); BOOST_TEST(isinf(val1 / zero)); + + BOOST_TEST(T{0} / val1 == zero); } int main() diff --git a/test/random_decimal128_math.cpp b/test/random_decimal128_math.cpp index 1a5b320cc..4549050b3 100644 --- a/test/random_decimal128_math.cpp +++ b/test/random_decimal128_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -20,9 +21,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(8U); // Number of trials +static constexpr auto N = static_cast(8); // Number of trials #endif static std::mt19937_64 rng(42); @@ -426,446 +427,6 @@ void random_mixed_division(T lower, T upper) BOOST_TEST(isinf(val1 / zero)); } -void random_and() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 & dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_and() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 & val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {val1 & dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_or() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 | dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_or() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 | val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {val1 | dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 ^ dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 ^ val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {val1 ^ dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_left_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 << dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_left_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 << val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {val1 << dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_right_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 >> dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_right_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal128_t res {dec1 >> val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal128_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal128_t res {val1 >> dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - template void test_spot_sub(T lhs, T rhs) { @@ -968,21 +529,6 @@ int main() random_mixed_division(-5'000LL, 5'000LL); random_mixed_division(-sqrt_int_max, sqrt_int_max); - // Bitwise operators - #if BOOST_DECIMAL_ENDIAN_LITTLE_BYTE - random_and(); - random_mixed_and(); - random_or(); - random_mixed_or(); - random_xor(); - random_mixed_xor(); - - random_left_shift(); - random_mixed_left_shift(); - random_right_shift(); - random_mixed_right_shift(); - #endif - test_spot_sub(-813150, -905406); return boost::report_errors(); diff --git a/test/random_decimal32_comp.cpp b/test/random_decimal32_comp.cpp index f5a743d8f..6a19aab03 100644 --- a/test/random_decimal32_comp.cpp +++ b/test/random_decimal32_comp.cpp @@ -2,19 +2,26 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include -#include -#include +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include "testing_config.hpp" #include +#include #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability @@ -100,9 +107,9 @@ void random_mixed_LT(T lower, T upper) BOOST_TEST_EQ(decimal32_t(10) < T(10), false); BOOST_TEST_EQ(T(1) < decimal32_t(1), false); BOOST_TEST_EQ(T(10) < decimal32_t(10), false); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_INFINITY < T(1), false); - BOOST_TEST_EQ(-BOOST_DECIMAL_DEC_INFINITY < T(1), true); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_NAN < T(1), false); + BOOST_TEST_EQ(std::numeric_limits::infinity() < T(1), false); + BOOST_TEST_EQ(-std::numeric_limits::infinity() < T(1), true); + BOOST_TEST_EQ(std::numeric_limits::quiet_NaN() < T(1), false); } template @@ -377,8 +384,8 @@ void random_mixed_EQ(T lower, T upper) BOOST_TEST_EQ(decimal32_t(1000), T(1000)); BOOST_TEST_EQ(decimal32_t(10000), T(10000)); BOOST_TEST_EQ(decimal32_t(100000), T(100000)); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_NAN == T(1), false); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_INFINITY == T(1), false); + BOOST_TEST_EQ(std::numeric_limits::quiet_NaN() == T(1), false); + BOOST_TEST_EQ(std::numeric_limits::infinity() == T(1), false); } template diff --git a/test/random_decimal32_fast_comp.cpp b/test/random_decimal32_fast_comp.cpp index 32db000a2..879f9dafb 100644 --- a/test/random_decimal32_fast_comp.cpp +++ b/test/random_decimal32_fast_comp.cpp @@ -2,19 +2,26 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include -#include -#include +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include "testing_config.hpp" #include +#include #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif + using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability @@ -106,9 +113,9 @@ void random_mixed_LT(T lower, T upper) BOOST_TEST_EQ(decimal_fast32_t(10) < T(10), false); BOOST_TEST_EQ(T(1) < decimal_fast32_t(1), false); BOOST_TEST_EQ(T(10) < decimal_fast32_t(10), false); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_INFINITY < T(1), false); - BOOST_TEST_EQ(-BOOST_DECIMAL_DEC_INFINITY < T(1), true); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_NAN < T(1), false); + BOOST_TEST_EQ(std::numeric_limits::infinity() < T(1), false); + BOOST_TEST_EQ(-std::numeric_limits::infinity() < T(1), true); + BOOST_TEST_EQ(std::numeric_limits::quiet_NaN() < T(1), false); } template @@ -376,8 +383,8 @@ void random_mixed_EQ(T lower, T upper) BOOST_TEST_EQ(decimal_fast32_t(1000), T(1000)); BOOST_TEST_EQ(decimal_fast32_t(10000), T(10000)); BOOST_TEST_EQ(decimal_fast32_t(100000), T(100000)); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_NAN == T(1), false); - BOOST_TEST_EQ(BOOST_DECIMAL_DEC_INFINITY == T(1), false); + BOOST_TEST_EQ(std::numeric_limits::quiet_NaN() == T(1), false); + BOOST_TEST_EQ(std::numeric_limits::infinity() == T(1), false); } template diff --git a/test/random_decimal32_fast_math.cpp b/test/random_decimal32_fast_math.cpp index e9b4d081b..522111e63 100644 --- a/test/random_decimal32_fast_math.cpp +++ b/test/random_decimal32_fast_math.cpp @@ -2,12 +2,19 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include -#include +#ifndef BOOST_DECIMAL_USE_MODULE +#include +#endif + +#include "testing_config.hpp" +#include #include #include #include +#ifdef BOOST_DECIMAL_USE_MODULE +import boost.decimal; +#endif #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wfloat-equal" @@ -21,9 +28,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability @@ -69,10 +76,10 @@ void random_addition(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() + decimal_fast32_t{0,0})); - BOOST_TEST(isinf(decimal_fast32_t{0,0} + std::numeric_limits::infinity())); - BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() + decimal_fast32_t{0,0})); - BOOST_TEST(isnan(decimal_fast32_t{0,0} + std::numeric_limits::quiet_NaN())); + BOOST_TEST(isinf(std::numeric_limits::infinity() + decimal_fast32_t{0,0} * dist(rng))); + BOOST_TEST(isinf(decimal_fast32_t{0,0} * dist(rng) + std::numeric_limits::infinity())); + BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() + decimal_fast32_t{0,0} * dist(rng))); + BOOST_TEST(isnan(decimal_fast32_t{0,0} * dist(rng) + std::numeric_limits::quiet_NaN())); } template @@ -170,10 +177,11 @@ void random_subtraction(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() - decimal_fast32_t{0,0})); - BOOST_TEST(isinf(decimal_fast32_t{0,0} - std::numeric_limits::infinity())); - BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() - decimal_fast32_t{0,0})); - BOOST_TEST(isnan(decimal_fast32_t{0,0} - std::numeric_limits::quiet_NaN())); + BOOST_TEST(isinf(std::numeric_limits::infinity() - decimal_fast32_t{0,0} * dist(rng))); + BOOST_TEST(isinf(decimal_fast32_t{0,0} * dist(rng) - std::numeric_limits::infinity())); + BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() - decimal_fast32_t{0,0} * dist(rng))); + BOOST_TEST(isnan(decimal_fast32_t{0,0} * dist(rng) - std::numeric_limits::quiet_NaN())); + BOOST_TEST(decimal_fast32_t(1000000, -103) - std::abs(dist(rng)) <= decimal_fast32_t(0)); } template @@ -376,6 +384,7 @@ void random_division(T lower, T upper) BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() / decimal_fast32_t(dist(rng)))); BOOST_TEST(isnan(decimal_fast32_t(dist(rng)) / std::numeric_limits::quiet_NaN())); BOOST_TEST(isinf(decimal_fast32_t(dist(rng)) / decimal_fast32_t(0))); + BOOST_TEST(!isinf(decimal_fast32_t(0) / decimal_fast32_t(dist(rng)))); } template @@ -397,7 +406,7 @@ void random_mixed_division(T lower, T upper) if (isinf(res) && isinf(res_int)) { } - else if (!BOOST_TEST(abs(res - res_int) < decimal_fast32_t(1, -3))) + else if (!BOOST_TEST(abs(res - res_int) < decimal_fast32_t(1, -2))) { // LCOV_EXCL_START std::cerr << "Val 1: " << val1 @@ -475,6 +484,13 @@ void random_spot_division(T val1, T val2) int main() { + // Match the rounding mode of integers + #ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + return 0; + #else + + fesetround(rounding_mode::fe_dec_to_nearest_from_zero); + // Values that won't exceed the range of the significand // Only positive values random_addition(0, 5'000'000); @@ -598,6 +614,7 @@ int main() random_mixed_division(-sqrt_int_max, sqrt_int_max); return boost::report_errors(); + #endif } #ifdef _MSC_VER diff --git a/test/random_decimal32_math.cpp b/test/random_decimal32_math.cpp index aaf65a725..b2164039c 100644 --- a/test/random_decimal32_math.cpp +++ b/test/random_decimal32_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -20,9 +21,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability @@ -450,446 +451,6 @@ void random_mixed_division(T lower, T upper) BOOST_TEST(isinf(val1 / zero)); } -void random_and() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 & dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_and() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 & val2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {val1 & dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_or() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 | dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_or() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 | val2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {val1 | dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 ^ dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 ^ val2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {val1 ^ dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_left_shift() -{ - std::uniform_int_distribution dist(0, 5); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 << dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_left_shift() -{ - std::uniform_int_distribution dist(0, 5); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 << val2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {val1 << dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_right_shift() -{ - std::uniform_int_distribution dist(0, 5); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 >> dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_right_shift() -{ - std::uniform_int_distribution dist(0, 5); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint32_t)); - - const decimal32_t res {dec1 >> val2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal32_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint32_t)); - - const decimal32_t res {val1 >> dec2}; - std::uint32_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint32_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - template void spot_mixed_division(T val1, T val2) { @@ -941,6 +502,12 @@ void spot_mixed_division(T val1, T val2) int main() { + // Match the rounding mode of integers + #ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + return 0; + #else + + fesetround(rounding_mode::fe_dec_to_nearest_from_zero); // Values that won't exceed the range of the significand // Only positive values random_addition(0, 5'000'000); @@ -1056,24 +623,13 @@ int main() random_mixed_division(-5'000LL, 5'000LL); random_mixed_division(-sqrt_int_max, sqrt_int_max); - // Bitwise operators - random_and(); - random_mixed_and(); - random_or(); - random_mixed_or(); - random_xor(); - random_mixed_xor(); - random_left_shift(); - random_mixed_left_shift(); - random_right_shift(); - random_mixed_right_shift(); - spot_random_mixed_addition(-653573LL, 1391401LL); spot_random_mixed_addition(894090LL, -1886315LL); spot_mixed_division(-20902, -2810); return boost::report_errors(); + #endif } #ifdef _MSC_VER diff --git a/test/random_decimal64_comp.cpp b/test/random_decimal64_comp.cpp index 559eea48b..47773edb4 100644 --- a/test/random_decimal64_comp.cpp +++ b/test/random_decimal64_comp.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -11,9 +12,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/random_decimal64_fast_comp.cpp b/test/random_decimal64_fast_comp.cpp index cba3febc9..cf4b02c98 100644 --- a/test/random_decimal64_fast_comp.cpp +++ b/test/random_decimal64_fast_comp.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -12,9 +13,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/random_decimal64_fast_math.cpp b/test/random_decimal64_fast_math.cpp index e2ca2783d..7f5299dbc 100644 --- a/test/random_decimal64_fast_math.cpp +++ b/test/random_decimal64_fast_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -20,9 +21,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); @@ -67,10 +68,10 @@ void random_addition(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() + decimal_fast64_t{0,0})); - BOOST_TEST(isinf(decimal_fast64_t{0,0} + std::numeric_limits::infinity())); - BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() + decimal_fast64_t{0,0})); - BOOST_TEST(isnan(decimal_fast64_t{0,0} + std::numeric_limits::quiet_NaN())); + BOOST_TEST(isinf(std::numeric_limits::infinity() + decimal_fast64_t{0,0} * dist(rng))); + BOOST_TEST(isinf(decimal_fast64_t{0,0} * dist(rng) + std::numeric_limits::infinity())); + BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() + decimal_fast64_t{0,0} * dist(rng))); + BOOST_TEST(isnan(decimal_fast64_t{0,0} * dist(rng) + std::numeric_limits::quiet_NaN())); } template @@ -137,10 +138,10 @@ void random_subtraction(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() - decimal_fast64_t{0,0})); - BOOST_TEST(isinf(decimal_fast64_t{0,0} - std::numeric_limits::infinity())); - BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() - decimal_fast64_t{0,0})); - BOOST_TEST(isnan(decimal_fast64_t{0,0} - std::numeric_limits::quiet_NaN())); + BOOST_TEST(isinf(std::numeric_limits::infinity() - decimal_fast64_t{0,0} * dist(rng))); + BOOST_TEST(isinf(decimal_fast64_t{0,0} * dist(rng) - std::numeric_limits::infinity())); + BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() - decimal_fast64_t{0,0} * dist(rng))); + BOOST_TEST(isnan(decimal_fast64_t{0,0} * dist(rng) - std::numeric_limits::quiet_NaN())); } template @@ -343,6 +344,7 @@ void random_division(T lower, T upper) BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() / decimal_fast64_t(dist(rng)))); BOOST_TEST(isnan(decimal_fast64_t(dist(rng)) / std::numeric_limits::quiet_NaN())); BOOST_TEST(isinf(decimal_fast64_t(dist(rng)) / decimal_fast64_t(0))); + BOOST_TEST(decimal_fast64_t{0} / dist(rng) == decimal_fast64_t{0}); } template @@ -413,6 +415,8 @@ void random_mixed_division(T lower, T upper) BOOST_TEST_EQ(abs(dist(rng) / std::numeric_limits::infinity()), zero); BOOST_TEST(isinf(decimal_fast64_t(dist(rng)) / 0)); BOOST_TEST(isinf(val1 / zero)); + + BOOST_TEST(T{0} / val1 == zero); } int main() diff --git a/test/random_decimal64_math.cpp b/test/random_decimal64_math.cpp index a6f5efa26..f8d8232cc 100644 --- a/test/random_decimal64_math.cpp +++ b/test/random_decimal64_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -20,9 +21,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); @@ -379,7 +380,6 @@ void random_division(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() / decimal64_t(dist(rng)))); BOOST_TEST(!isinf(decimal64_t(dist(rng)) / std::numeric_limits::infinity())); BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() / decimal64_t(dist(rng)))); BOOST_TEST(isnan(decimal64_t(dist(rng)) / std::numeric_limits::quiet_NaN())); @@ -506,446 +506,6 @@ void random_mixed_division(T lower, T upper) BOOST_TEST(isinf(val1 / zero)); } -void random_and() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 & dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_and() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 & val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {val1 & dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 & val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_or() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 | dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_or() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 | val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {val1 | dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 | val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 ^ dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_xor() -{ - std::uniform_int_distribution dist(0, 9'999'999'999'999'999); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 ^ val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {val1 ^ dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 ^ val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_left_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 << dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_left_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 << val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {val1 << dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 << val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_right_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 >> dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - -void random_mixed_right_shift() -{ - std::uniform_int_distribution dist(0, 10); - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec1 {}; - std::memcpy(&dec1, &val1, sizeof(std::uint64_t)); - - const decimal64_t res {dec1 >> val2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nDec 1: " << dec1 - << "\nVal 2: " << val2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } - - for (std::size_t i {}; i < N; ++i) - { - const auto val1 {dist(rng)}; - const auto val2 {dist(rng)}; - - decimal64_t dec2 {}; - std::memcpy(&dec2, &val2, sizeof(std::uint64_t)); - - const decimal64_t res {val1 >> dec2}; - std::uint64_t dec_int {}; - std::memcpy(&dec_int, &res, sizeof(std::uint64_t)); - const auto res_int {val1 >> val2}; - - if (!BOOST_TEST_EQ(dec_int, res_int)) - { - // LCOV_EXCL_START - std::cerr << "Val 1: " << val1 - << "\nVal 2: " << val2 - << "\nDec 2: " << dec2 - << "\nDec res: " << res - << "\nInt res: " << res_int << std::endl; - // LCOV_EXCL_STOP - } - } -} - int main() { // Values that won't exceed the range of the significand @@ -1049,18 +609,6 @@ int main() spot_check_mul(27625, 2977); - // Bitwise operators - random_and(); - random_mixed_and(); - random_or(); - random_mixed_or(); - random_xor(); - random_mixed_xor(); - random_left_shift(); - random_mixed_left_shift(); - random_right_shift(); - random_mixed_right_shift(); - spot_mixed_division(4930, -24419); return boost::report_errors(); diff --git a/test/random_mixed_decimal_comp.cpp b/test/random_mixed_decimal_comp.cpp index d46a4f595..07b1933fd 100644 --- a/test/random_mixed_decimal_comp.cpp +++ b/test/random_mixed_decimal_comp.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -10,9 +11,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/random_mixed_decimal_math.cpp b/test/random_mixed_decimal_math.cpp index ba371cd62..04842730b 100644 --- a/test/random_mixed_decimal_math.cpp +++ b/test/random_mixed_decimal_math.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -19,9 +20,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability @@ -179,7 +180,6 @@ void random_mixed_division(T lower, T upper) } } - BOOST_TEST(isinf(std::numeric_limits::infinity() / Decimal2(dist(rng)))); BOOST_TEST(!isinf(Decimal2(dist(rng)) / std::numeric_limits::infinity())); BOOST_TEST(isnan(std::numeric_limits::quiet_NaN() / Decimal2(dist(rng)))); BOOST_TEST(isnan(Decimal2(dist(rng)) / std::numeric_limits::quiet_NaN())); diff --git a/test/roundtrip_decimal128.cpp b/test/roundtrip_decimal128.cpp index 0085ef27c..cb20e5fdb 100644 --- a/test/roundtrip_decimal128.cpp +++ b/test/roundtrip_decimal128.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #if defined(__clang__) @@ -23,6 +23,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -37,9 +38,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #ifdef _MSC_VER @@ -196,6 +197,8 @@ void test_roundtrip_conversion_float() } } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + template <> void test_roundtrip_conversion_float() { @@ -247,6 +250,8 @@ void test_roundtrip_conversion_float() } } +#endif + template void test_roundtrip_integer_stream() { @@ -308,6 +313,8 @@ void test_roundtrip_float_stream() } } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + template <> void test_roundtrip_float_stream() { @@ -340,6 +347,8 @@ void test_roundtrip_float_stream() } } +#endif + void test_roundtrip_conversion_decimal32_t() { std::mt19937_64 rng(42); @@ -406,7 +415,7 @@ int main() test_roundtrip_float_stream(); test_roundtrip_float_stream(); - #if BOOST_DECIMAL_LDBL_BITS < 128 + #if BOOST_DECIMAL_LDBL_BITS < 128 && !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) test_conversion_from_float(); test_conversion_to_float(); test_roundtrip_conversion_float(); diff --git a/test/roundtrip_decimal128_fast.cpp b/test/roundtrip_decimal128_fast.cpp index 4a42d2af2..1239502dd 100644 --- a/test/roundtrip_decimal128_fast.cpp +++ b/test/roundtrip_decimal128_fast.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #if defined(__clang__) @@ -23,6 +23,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -37,9 +38,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #ifdef _MSC_VER @@ -196,6 +197,8 @@ void test_roundtrip_conversion_float() } } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + template <> void test_roundtrip_conversion_float() { @@ -249,6 +252,8 @@ void test_roundtrip_conversion_float() BOOST_TEST(isnan(decimal_fast128_t(std::numeric_limits::quiet_NaN() * dist(rng)))); } +#endif + template void test_roundtrip_integer_stream() { @@ -310,6 +315,8 @@ void test_roundtrip_float_stream() } } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + template <> void test_roundtrip_float_stream() { @@ -342,6 +349,8 @@ void test_roundtrip_float_stream() } } +#endif + void test_roundtrip_conversion_decimal32_t() { std::mt19937_64 rng(42); @@ -408,7 +417,7 @@ int main() test_roundtrip_float_stream(); test_roundtrip_float_stream(); - #if BOOST_DECIMAL_LDBL_BITS < 128 + #if BOOST_DECIMAL_LDBL_BITS < 128 && !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) test_conversion_from_float(); test_conversion_to_float(); test_roundtrip_conversion_float(); diff --git a/test/roundtrip_decimal32.cpp b/test/roundtrip_decimal32.cpp index 247eee8eb..dec87985d 100644 --- a/test/roundtrip_decimal32.cpp +++ b/test/roundtrip_decimal32.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #include #include @@ -26,9 +26,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #ifdef _MSC_VER @@ -276,11 +276,9 @@ int main() test_conversion_to_float(); test_conversion_to_float(); - test_conversion_to_float(); test_roundtrip_conversion_float(); test_roundtrip_conversion_float(); - test_roundtrip_conversion_float(); test_roundtrip_integer_stream(); test_roundtrip_integer_stream(); @@ -291,7 +289,12 @@ int main() test_roundtrip_float_stream(); test_roundtrip_float_stream(); + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + test_conversion_to_float(); + test_roundtrip_conversion_float(); test_roundtrip_float_stream(); + #endif #ifdef BOOST_DECIMAL_HAS_FLOAT16 test_conversion_to_float(); diff --git a/test/roundtrip_decimal32_fast.cpp b/test/roundtrip_decimal32_fast.cpp index 54520aeb7..cfe044510 100644 --- a/test/roundtrip_decimal32_fast.cpp +++ b/test/roundtrip_decimal32_fast.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #include #include @@ -24,9 +24,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #ifdef _MSC_VER @@ -283,11 +283,9 @@ int main() test_conversion_to_float(); test_conversion_to_float(); - test_conversion_to_float(); test_roundtrip_conversion_float(); test_roundtrip_conversion_float(); - test_roundtrip_conversion_float(); test_roundtrip_integer_stream(); test_roundtrip_integer_stream(); @@ -298,7 +296,12 @@ int main() test_roundtrip_float_stream(); test_roundtrip_float_stream(); + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + test_conversion_to_float(); + test_roundtrip_conversion_float(); test_roundtrip_float_stream(); + #endif #ifdef BOOST_DECIMAL_HAS_FLOAT16 test_conversion_to_float(); diff --git a/test/roundtrip_decimal64.cpp b/test/roundtrip_decimal64.cpp index f3d459cb0..7ffc3972c 100644 --- a/test/roundtrip_decimal64.cpp +++ b/test/roundtrip_decimal64.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #include #include @@ -24,9 +24,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #ifdef _MSC_VER @@ -294,15 +294,12 @@ int main() test_conversion_from_float(); test_conversion_from_float(); - test_conversion_from_float(); test_conversion_to_float(); test_conversion_to_float(); - test_conversion_to_float(); test_roundtrip_conversion_float(); test_roundtrip_conversion_float(); - test_roundtrip_conversion_float(); test_roundtrip_integer_stream(); test_roundtrip_integer_stream(); @@ -313,7 +310,13 @@ int main() test_roundtrip_float_stream(); test_roundtrip_float_stream(); + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + test_conversion_from_float(); + test_conversion_to_float(); + test_roundtrip_conversion_float(); test_roundtrip_float_stream(); + #endif #ifdef BOOST_DECIMAL_HAS_FLOAT16 test_conversion_to_float(); diff --git a/test/test_acos.cpp b/test/test_acos.cpp index 04aca2231..fcb64aa10 100644 --- a/test/test_acos.cpp +++ b/test/test_acos.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -35,9 +37,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_acosh.cpp b/test/test_acosh.cpp index 77307da65..9124897af 100644 --- a/test/test_acosh.cpp +++ b/test/test_acosh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -89,9 +90,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -225,15 +226,15 @@ auto main() -> int const auto result_eps_is_ok = local::test_acosh ( - static_cast(INT32_C(16) * INT32_C(262144)), - 1.0L + static_cast(std::numeric_limits::epsilon()) * 10.0L, - 1.0L + static_cast(std::numeric_limits::epsilon()) * 100.0L + INT32_C(16) * INT32_C(262144), + 1.0L + static_cast(std::numeric_limits::epsilon()) * 10.0L, + 1.0L + static_cast(std::numeric_limits::epsilon()) * 100.0L ); - const auto result_tiny_is_ok = local::test_acosh(static_cast(INT32_C(4096)), 1.001L, 1.1L); - const auto result_small_is_ok = local::test_acosh(static_cast(INT32_C(96)), 1.1L, 1.59L); - const auto result_medium_is_ok = local::test_acosh(static_cast(INT32_C(48)), 1.59L, 10.1L); - const auto result_large_is_ok = local::test_acosh(static_cast(INT32_C(48)), 1.0E+01L, 1.0E+26L); + const auto result_tiny_is_ok = local::test_acosh(INT32_C(4096), 1.001L, 1.1L); + const auto result_small_is_ok = local::test_acosh(INT32_C(96), 1.1L, 1.59L); + const auto result_medium_is_ok = local::test_acosh(INT32_C(48), 1.59L, 10.1L); + const auto result_large_is_ok = local::test_acosh(INT32_C(48), 1.0E+01L, 1.0E+26L); BOOST_TEST(result_eps_is_ok); BOOST_TEST(result_tiny_is_ok); diff --git a/test/test_asin.cpp b/test/test_asin.cpp index 9d3ae4427..68e750eb9 100644 --- a/test/test_asin.cpp +++ b/test/test_asin.cpp @@ -1,10 +1,12 @@ -// Copyright 2024 Matt Borland +// Copyright 2024 - 2025 Matt Borland +// Copyright 2024 - 2025 Christopher Kormanyos // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -14,7 +16,7 @@ # pragma clang diagnostic ignored "-Wconversion" # pragma clang diagnostic ignored "-Wsign-conversion" # pragma clang diagnostic ignored "-Wfloat-equal" -# if __clang_major__ >= 20 +# if (__clang_major__ >= 20) # pragma clang diagnostic ignored "-Wfortify-source" # endif #elif defined(__GNUC__) @@ -24,24 +26,28 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include #include -#include -#include + #include +#include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); using namespace boost::decimal; +template auto my_zero() -> T; +template auto my_one () -> T; + template void test_asin() { @@ -137,6 +143,100 @@ void print_value(T value, const char* str) << "\nExp: " << ptr << "\n" << std::endl; } +template +auto test_asin_edge() -> void +{ + using nl = std::numeric_limits; + + const T tiny0 { nl::epsilon() * 999 / 1000 }; + const T tiny1 { nl::epsilon() }; + const T tiny2 { nl::epsilon() * 1000 / 999 }; + + const T asin_tiny0 { asin(tiny0) }; + const T asin_tiny1 { asin(tiny1) }; + const T asin_tiny2 { asin(tiny2) }; + + // tiny1: 1 + // tiny2: 1.001001 + // tiny0: 0.999 + // tiny1: 1 + // tiny2: 1.001001001001001 + // tiny0: 0.999 + // tiny1: 1 + // tiny2: 1.001001001001001001001001001001001 + + constexpr T ctrl_tiny2 + { + std::numeric_limits::digits10 < 10 ? T("1.001001") + : std::numeric_limits::digits10 < 20 ? T("1.001001001001001") + : T("1.001001001001001001001001001001001") + }; + + BOOST_TEST_EQ(asin_tiny0 / nl::epsilon(), T(999, -3)); + BOOST_TEST_EQ(asin_tiny1 / nl::epsilon(), T(1)); + BOOST_TEST_EQ(asin_tiny2 / nl::epsilon(), ctrl_tiny2); + + constexpr T half_pi { numbers::pi_v / 2 }; + + BOOST_TEST_EQ(asin(my_zero() + my_one()), half_pi); + BOOST_TEST_EQ(asin(my_zero() - my_one()), -half_pi); +} + +template +void test_asin_1137() +{ + using nl = std::numeric_limits; + + const T tiny0 { nl::epsilon() * 999/1000 }; + const T tiny1 { nl::epsilon() }; + const T tiny2 { nl::epsilon() * 1000/999 }; + + BOOST_TEST(tiny0 != tiny1); + BOOST_TEST(tiny1 != tiny2); + + std::stringstream strm { }; + + BOOST_TEST_EQ(tiny0, asin(tiny0)); + BOOST_TEST_EQ(tiny1, asin(tiny1)); + BOOST_TEST_EQ(tiny2, asin(tiny2)); + + const T sqrt_tiny0 { sqrt(nl::epsilon() * 999/1000) }; + const T sqrt_tiny1 { sqrt(nl::epsilon()) }; + const T sqrt_tiny2 { sqrt(nl::epsilon() * 1000/999) }; + + BOOST_TEST_EQ(sqrt_tiny0, asin(sqrt_tiny0)); + BOOST_TEST_EQ(sqrt_tiny1, asin(sqrt_tiny1)); + BOOST_TEST_EQ(sqrt_tiny2, asin(sqrt_tiny2)); + + const T cbrt_tiny0 { cbrt(nl::epsilon() * 999/1000) }; + const T cbrt_tiny1 { cbrt(nl::epsilon()) }; + const T cbrt_tiny2 { cbrt(nl::epsilon() * 1000/999) }; + const T cbrt_tiny3 { cbrt(nl::epsilon() * 1004/999) }; + + auto mini_series + { + [](const T eps) + { + return eps * (1 + (eps / 6) * eps); + } + }; + + auto is_close + { + [](const T a, const T b) + { + const T delta { fabs(a - b) }; + + return (delta < (std::numeric_limits::epsilon() * 4)); + } + }; + + BOOST_TEST(is_close(asin(cbrt_tiny0), mini_series(cbrt_tiny0))); + BOOST_TEST(is_close(asin(cbrt_tiny1), mini_series(cbrt_tiny1))); + BOOST_TEST(is_close(asin(cbrt_tiny2), mini_series(cbrt_tiny2))); + BOOST_TEST(is_close(asin(cbrt_tiny3), mini_series(cbrt_tiny3))); +} + int main() { #ifdef BOOST_DECIMAL_GENERATE_CONSTANT_SIGS @@ -187,12 +287,22 @@ int main() test_asin(); test_asin(); - #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) test_asin(); #endif test_asin(); + test_asin_edge(); + test_asin_edge(); + test_asin_edge(); + + test_asin_1137(); + test_asin_1137(); + test_asin_1137(); + return boost::report_errors(); } + +template auto my_zero() -> T { T zero { 0 }; return zero; } +template auto my_one () -> T { T one { 1 }; return one; } diff --git a/test/test_asinh.cpp b/test/test_asinh.cpp index e32415087..17e58cadf 100644 --- a/test/test_asinh.cpp +++ b/test/test_asinh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -67,7 +68,7 @@ namespace local return result_is_ok; } - auto test_asinh(const std::int32_t tol_factor, const bool negate, const long double range_lo, const long double range_hi) -> bool + auto test_asinh(const std::int32_t tol_factor, const bool negate, const double range_lo, const double range_hi) -> bool { using decimal_type = boost::decimal::decimal32_t; @@ -88,9 +89,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -228,17 +229,17 @@ auto main() -> int const auto result_eps_is_ok = local::test_asinh ( - static_cast(INT32_C(16) * INT32_C(262144)), + INT32_C(16) * INT32_C(262144), false, - static_cast(fourth_root_epsilon) / 40.0L, - static_cast(fourth_root_epsilon) * 40.0L + static_cast(static_cast(fourth_root_epsilon) / 40.0), + static_cast(static_cast(fourth_root_epsilon) * 40.0) ); - const auto result_tiny_is_ok = local::test_asinh(static_cast(INT32_C(4096)), false, 1.001L, 1.1L); - const auto result_small_is_ok = local::test_asinh(static_cast(INT32_C(96)), false, 0.1L, 1.59L); - const auto result_medium_is_ok = local::test_asinh(static_cast(INT32_C(48)), false, 1.59L, 10.1L); - const auto result_medium_neg_is_ok = local::test_asinh(static_cast(INT32_C(48)), true, 1.59L, 10.1L); - const auto result_large_is_ok = local::test_asinh(static_cast(INT32_C(48)), false, 1.0E+01L, 1.0E+19L); + const auto result_tiny_is_ok = local::test_asinh(INT32_C(4096), false, 1.001, 1.1); + const auto result_small_is_ok = local::test_asinh(INT32_C(96), false, 0.1, 1.59); + const auto result_medium_is_ok = local::test_asinh(INT32_C(48), false, 1.59, 10.1); + const auto result_medium_neg_is_ok = local::test_asinh(INT32_C(48), true, 1.59, 10.1); + const auto result_large_is_ok = local::test_asinh(INT32_C(48), false, 1.0E+01, 1.0E+19); BOOST_TEST(result_eps_is_ok); BOOST_TEST(result_tiny_is_ok); diff --git a/test/test_assoc_laguerre.cpp b/test/test_assoc_laguerre.cpp index 338211c88..f48e0877b 100644 --- a/test/test_assoc_laguerre.cpp +++ b/test/test_assoc_laguerre.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_assoc_legendre.cpp b/test/test_assoc_legendre.cpp index b94206994..8ea3a82ba 100644 --- a/test/test_assoc_legendre.cpp +++ b/test/test_assoc_legendre.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif // Windows in Github actions has a broken chrono header @@ -43,11 +45,7 @@ int main() #include #include -#if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(10U); // Number of trials -#else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials -#endif +static constexpr std::size_t N {10}; static std::mt19937_64 rng(42); @@ -58,8 +56,8 @@ void test() { std::uniform_real_distribution dist(-1, 1); - constexpr auto max_iter {std::is_same::value ? N / 4 : N}; - for (std::size_t i {}; i < max_iter / 4; ++i) + constexpr auto max_iter {std::is_same::value ? static_cast(2) : N}; + for (std::size_t i {}; i < max_iter; ++i) { for (unsigned n {}; n < 4; ++n) { diff --git a/test/test_atan.cpp b/test/test_atan.cpp index 75acf0984..3193540e1 100644 --- a/test/test_atan.cpp +++ b/test/test_atan.cpp @@ -6,6 +6,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -25,6 +26,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif namespace local { diff --git a/test/test_atan2.cpp b/test/test_atan2.cpp index 98bd8c6ce..2bc8fa3d8 100644 --- a/test/test_atan2.cpp +++ b/test/test_atan2.cpp @@ -5,6 +5,7 @@ // Propagates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_atanh.cpp b/test/test_atanh.cpp index a188aec07..cd6b656dc 100644 --- a/test/test_atanh.cpp +++ b/test/test_atanh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -68,7 +69,7 @@ namespace local return result_is_ok; } - auto test_atanh(const std::int32_t tol_factor, const bool negate, const long double range_lo, const long double range_hi) -> bool + auto test_atanh(const std::int32_t tol_factor, const bool negate, const double range_lo, const double range_hi) -> bool { using decimal_type = boost::decimal::decimal32_t; @@ -89,9 +90,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -229,24 +230,24 @@ auto main() -> int const auto result_eps_is_ok = local::test_atanh ( - static_cast(INT32_C(128)), + INT32_C(128), false, - static_cast(fourth_root_epsilon) / 32.0L, - static_cast(fourth_root_epsilon) * 32.0L + static_cast(static_cast(fourth_root_epsilon) / 32.0), + static_cast(static_cast(fourth_root_epsilon) * 32.0) ); const auto result_eps_near_one_is_ok = local::test_atanh ( - static_cast(INT32_C(256)), + INT32_C(256), false, - static_cast( static_cast(1.0L) - static_cast(static_cast(fourth_root_epsilon) * 32.0L)), - static_cast( static_cast(1.0L) - static_cast(static_cast(fourth_root_epsilon) / 32.0L)) + static_cast(static_cast( static_cast(1.0L) - static_cast(static_cast(fourth_root_epsilon) * 32.0L))), + static_cast(static_cast( static_cast(1.0L) - static_cast(static_cast(fourth_root_epsilon) / 32.0L))) ); - const auto result_tiny_is_ok = local::test_atanh(static_cast(INT32_C(96)), false, 0.001L, 0.1L); - const auto result_medium_is_ok = local::test_atanh(static_cast(INT32_C(96)), true, 0.1L, 0.9L); - const auto result_medium_neg_is_ok = local::test_atanh(static_cast(INT32_C(96)), false, 0.1L, 0.9L); + const auto result_tiny_is_ok = local::test_atanh(INT32_C(96), false, 0.001, 0.1); + const auto result_medium_is_ok = local::test_atanh(INT32_C(96), true, 0.1, 0.9); + const auto result_medium_neg_is_ok = local::test_atanh(INT32_C(96), false, 0.1, 0.9); BOOST_TEST(result_eps_is_ok); BOOST_TEST(result_eps_near_one_is_ok); diff --git a/test/test_beta.cpp b/test/test_beta.cpp index 0d3988e22..dd70a0ff9 100644 --- a/test/test_beta.cpp +++ b/test/test_beta.cpp @@ -5,6 +5,7 @@ // Propagates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -25,6 +26,7 @@ # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" # pragma GCC diagnostic ignored "-Wfloat-conversion" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -36,9 +38,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_big_uints.cpp b/test/test_big_uints.cpp index 7adac665f..b8cefe275 100644 --- a/test/test_big_uints.cpp +++ b/test/test_big_uints.cpp @@ -46,6 +46,7 @@ int main() # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" # pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #if defined(__GNUC__) && !defined(__clang__) @@ -478,6 +479,7 @@ void test_digit_counting() int current_digits {1}; for (int i {}; i <= max_power; ++i) { + BOOST_TEST_EQ(current_power, boost::decimal::detail::pow10(static_cast(i))); BOOST_TEST_EQ(num_digits(current_power), current_digits); current_power = current_power * UINT64_C(10); ++current_digits; diff --git a/test/test_boost_math_univariate_stats.cpp b/test/test_boost_math_univariate_stats.cpp index 9d5827a1c..00f2c29b9 100644 --- a/test/test_boost_math_univariate_stats.cpp +++ b/test/test_boost_math_univariate_stats.cpp @@ -9,6 +9,9 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +// Needed for operations with boost math +#define BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS + #include #if defined(__clang__) @@ -32,6 +35,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include diff --git a/test/test_cbrt.cpp b/test/test_cbrt.cpp index 92e4404c3..7c8713cd9 100644 --- a/test/test_cbrt.cpp +++ b/test/test_cbrt.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #if defined(__clang__) @@ -100,8 +101,8 @@ namespace local auto dis_sign = std::uniform_int_distribution { - static_cast(INT8_C(0)), - static_cast(INT8_C(1)) + 0, + 1 }; auto result_is_ok = true; @@ -109,9 +110,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x400)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -340,9 +341,9 @@ int main() using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_small_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E-26L, 1.0E-01L); - const auto result_medium_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 0.9E-01L, 1.1E+01L); - const auto result_large_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E+01L, 1.0E+26L); + const auto result_small_is_ok = local::test_cbrt(INT32_C(16), 1.0E-26L, 1.0E-01L); + const auto result_medium_is_ok = local::test_cbrt(INT32_C(16), 0.9E-01L, 1.1E+01L); + const auto result_large_is_ok = local::test_cbrt(INT32_C(16), 1.0E+01L, 1.0E+26L); BOOST_TEST(result_small_is_ok); BOOST_TEST(result_medium_is_ok); @@ -363,9 +364,9 @@ int main() using decimal_type = boost::decimal::decimal_fast32_t; using float_type = float; - const auto result_small_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E-26L, 1.0E-01L); - const auto result_medium_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 0.9E-01L, 1.1E+01L); - const auto result_large_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E+01L, 1.0E+26L); + const auto result_small_is_ok = local::test_cbrt(INT32_C(16), 1.0E-26L, 1.0E-01L); + const auto result_medium_is_ok = local::test_cbrt(INT32_C(16), 0.9E-01L, 1.1E+01L); + const auto result_large_is_ok = local::test_cbrt(INT32_C(16), 1.0E+01L, 1.0E+26L); BOOST_TEST(result_small_is_ok); BOOST_TEST(result_medium_is_ok); @@ -386,9 +387,9 @@ int main() using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_small_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E-76L, 1.0E-01L); - const auto result_medium_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 0.9E-01L, 1.1E+01L); - const auto result_large_is_ok = local::test_cbrt(static_cast(INT32_C(16)), 1.0E+01L, 1.0E+76L); + const auto result_small_is_ok = local::test_cbrt(INT32_C(16), 1.0E-76L, 1.0E-01L); + const auto result_medium_is_ok = local::test_cbrt(INT32_C(16), 0.9E-01L, 1.1E+01L); + const auto result_large_is_ok = local::test_cbrt(INT32_C(16), 1.0E+01L, 1.0E+76L); BOOST_TEST(result_small_is_ok); BOOST_TEST(result_medium_is_ok); diff --git a/test/test_charconv_preservation.cpp b/test/test_charconv_preservation.cpp new file mode 100644 index 000000000..bc76fa3fb --- /dev/null +++ b/test/test_charconv_preservation.cpp @@ -0,0 +1,213 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + +using namespace boost::decimal; + +template +void test_to_chars_scientific(const ResultsType& decimals, const StringsType& strings) +{ + for (std::size_t i {}; i < decimals.size(); ++i) + { + for (std::size_t j {}; j < decimals.size(); ++j) + { + BOOST_TEST_EQ(decimals[i], decimals[j]); + } + } + + for (std::size_t i {}; i < decimals.size(); ++i) + { + char buffer[64] {}; + const auto r {to_chars(buffer, buffer + sizeof(buffer), decimals[i], chars_format::cohort_preserving_scientific)}; + BOOST_TEST(r); + *r.ptr = '\0'; + + BOOST_TEST_CSTR_EQ(buffer, strings[i]); + } +} + +// The cohorts will compare equal regardless so here we check bit-wise equality to be a successful roundtrip +template +void test_roundtrip(const std::array& decimals, const std::array& strings) +{ + using bit_type = std::conditional_t::value, std::uint32_t, + std::conditional_t::value, std::uint64_t, boost::int128::uint128_t>>; + + for (std::size_t i {}; i < decimals.size(); ++i) + { + bit_type initial_bits; + std::memcpy(&initial_bits, &decimals[i], sizeof(initial_bits)); + + char buffer[64] {}; + const auto r {to_chars(buffer, buffer + sizeof(buffer), decimals[i], chars_format::cohort_preserving_scientific)}; + BOOST_TEST(r); + *r.ptr = '\0'; + BOOST_TEST_CSTR_EQ(buffer, strings[i]); + + T return_val; + const auto return_r {from_chars(buffer, buffer + sizeof(buffer), return_val, chars_format::cohort_preserving_scientific)}; + BOOST_TEST(return_r); + + bit_type return_bits; + std::memcpy(&return_bits, &return_val, sizeof(return_bits)); + + BOOST_TEST_EQ(initial_bits, return_bits); + } +} + +template +void test_invalid_values(const std::array& strings) +{ + for (std::size_t i {}; i < strings.size(); ++i) + { + TargetDecimalType val; + const auto r {from_chars(strings[i], strings[i] + sizeof(strings[i]), val, chars_format::cohort_preserving_scientific)}; + BOOST_TEST(!r); + } +} + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) +#endif + +template +void test_invalid_to_chars(const std::array& decimals) +{ + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_fast_type_v) + { + for (std::size_t i {}; i < decimals.size(); ++i) + { + char buffer[64] {}; + const auto r {to_chars(buffer, buffer + sizeof(buffer), decimals[i], chars_format::cohort_preserving_scientific)}; + BOOST_TEST(!r); + } + } + + for (std::size_t i {}; i < decimals.size(); ++i) + { + char buffer[64] {}; + const auto r {to_chars(buffer, buffer + sizeof(buffer), decimals[i], chars_format::cohort_preserving_scientific, 5)}; + BOOST_TEST(!r); + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +template +const std::array decimals = { + T{3, 2}, + T{30, 1}, + T{300, 0}, + T{3000, -1}, + T{30000, -2}, + T{300000, -3}, + T{3000000, -4}, +}; + +constexpr std::array strings = { + "3e+02", + "3.0e+02", + "3.00e+02", + "3.000e+02", + "3.0000e+02", + "3.00000e+02", + "3.000000e+02", +}; + +template +const std::array decimals_with_exp = { + T {42, 50}, + T {420, 49}, + T {4200, 48}, + T {42000, 47}, + T {420000, 46}, + T {4200000, 45} +}; + +constexpr std::array decimals_with_exp_strings = { + "4.2e+51", + "4.20e+51", + "4.200e+51", + "4.2000e+51", + "4.20000e+51", + "4.200000e+51", +}; + +template +const std::array negative_values = { + T {-321, -49}, + T {-3210, -50}, + T {-32100, -51}, + T {-321000, -52}, + T {-3210000, -53} +}; + +constexpr std::array negative_values_strings = { + "-3.21e-47", + "-3.210e-47", + "-3.2100e-47", + "-3.21000e-47", + "-3.210000e-47" +}; + +constexpr std::array invalid_decimal32_strings = { + "+3.2e+20", + "3.421", + "9.999999999999999e+05", +}; + +int main() +{ + test_to_chars_scientific(decimals, strings); + test_to_chars_scientific(decimals, strings); + test_to_chars_scientific(decimals, strings); + + test_to_chars_scientific(decimals_with_exp, decimals_with_exp_strings); + test_to_chars_scientific(decimals_with_exp, decimals_with_exp_strings); + test_to_chars_scientific(decimals_with_exp, decimals_with_exp_strings); + + test_to_chars_scientific(negative_values, negative_values_strings); + test_to_chars_scientific(negative_values, negative_values_strings); + test_to_chars_scientific(negative_values, negative_values_strings); + + test_roundtrip(decimals, strings); + test_roundtrip(decimals, strings); + test_roundtrip(decimals, strings); + + test_roundtrip(decimals_with_exp, decimals_with_exp_strings); + test_roundtrip(decimals_with_exp, decimals_with_exp_strings); + test_roundtrip(decimals_with_exp, decimals_with_exp_strings); + + test_roundtrip(negative_values, negative_values_strings); + test_roundtrip(negative_values, negative_values_strings); + test_roundtrip(negative_values, negative_values_strings); + + test_invalid_values(invalid_decimal32_strings); + + // Every value for fast types are invalid + test_invalid_values(strings); + test_invalid_values(decimals_with_exp_strings); + test_invalid_values(negative_values_strings); + test_invalid_to_chars(decimals); + test_invalid_to_chars(decimals); + test_invalid_to_chars(decimals); + + // Specified precision is not allowed + test_invalid_to_chars(decimals); + test_invalid_to_chars(decimals); + test_invalid_to_chars(decimals); + + return boost::report_errors(); +} diff --git a/test/test_cmath.cpp b/test/test_cmath.cpp index ad63ae15a..d79b38468 100644 --- a/test/test_cmath.cpp +++ b/test/test_cmath.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #include #include @@ -31,6 +32,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -39,12 +41,12 @@ #include #include #include - +#include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && !defined(_WIN32) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); @@ -60,7 +62,6 @@ void test_fmax() BOOST_TEST_EQ(fmax(Dec(1), std::numeric_limits::quiet_NaN() * Dec(dist(rng))), Dec(1)); BOOST_TEST_EQ(fmax(std::numeric_limits::quiet_NaN() * Dec(dist(rng)), Dec(1)), Dec(1)); BOOST_TEST(isnan(fmax(std::numeric_limits::quiet_NaN() * Dec(dist(rng)), std::numeric_limits::quiet_NaN() * Dec(dist(rng))))); - BOOST_TEST_EQ(fmax(std::numeric_limits::infinity() * Dec(dist(rng)), -std::numeric_limits::infinity() * Dec(dist(rng))), std::numeric_limits::infinity()); BOOST_TEST_EQ(fmax(Dec(1), Dec(0)), Dec(1)); BOOST_TEST_EQ(fmax(Dec(-2), Dec(1)), Dec(1)); @@ -73,10 +74,12 @@ void test_fmax() template void test_isgreater() { - BOOST_TEST_EQ(isgreater(Dec(1), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isgreater(std::numeric_limits::quiet_NaN(), Dec(1)), false); - BOOST_TEST_EQ(isgreater(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isgreater(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), true); + std::uniform_int_distribution dist(1, 10); + + BOOST_TEST_EQ(isgreater(Dec(1), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(isgreater(std::numeric_limits::quiet_NaN() * dist(rng), Dec(1)), false); + BOOST_TEST_EQ(isgreater(std::numeric_limits::quiet_NaN() * dist(rng), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(isgreater(std::numeric_limits::infinity() * dist(rng), -std::numeric_limits::infinity() * dist(rng)), true); BOOST_TEST_EQ(isgreater(Dec(1), Dec(0)), true); BOOST_TEST_EQ(isgreater(Dec(-2), Dec(1)), false); @@ -86,10 +89,12 @@ void test_isgreater() template void test_isgreaterequal() { - BOOST_TEST_EQ(isgreaterequal(Dec(1), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::quiet_NaN(), Dec(1)), false); - BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), true); + std::uniform_int_distribution dist(1, 10); + + BOOST_TEST_EQ(isgreaterequal(Dec(1), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::quiet_NaN() * dist(rng), Dec(1)), false); + BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::quiet_NaN() * dist(rng), std::numeric_limits::quiet_NaN()), false); + BOOST_TEST_EQ(isgreaterequal(std::numeric_limits::infinity() * dist(rng), -std::numeric_limits::infinity()), true); BOOST_TEST_EQ(isgreaterequal(Dec(1), Dec(0)), true); BOOST_TEST_EQ(isgreaterequal(Dec(-2), Dec(1)), false); @@ -115,10 +120,12 @@ void test_fmin() template void test_isless() { - BOOST_TEST_EQ(isless(Dec(1), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isless(std::numeric_limits::quiet_NaN(), Dec(1)), false); - BOOST_TEST_EQ(isless(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(isless(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), false); + std::uniform_int_distribution dist(1, 10); + + BOOST_TEST_EQ(isless(Dec(1), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(isless(std::numeric_limits::quiet_NaN() * dist(rng), Dec(1)), false); + BOOST_TEST_EQ(isless(std::numeric_limits::quiet_NaN() * dist(rng), std::numeric_limits::quiet_NaN()), false); + BOOST_TEST_EQ(isless(std::numeric_limits::infinity() * dist(rng), -std::numeric_limits::infinity()), false); BOOST_TEST_EQ(isless(Dec(1), Dec(0)), false); BOOST_TEST_EQ(isless(Dec(-2), Dec(1)), true); @@ -128,10 +135,12 @@ void test_isless() template void test_islessequal() { - BOOST_TEST_EQ(islessequal(Dec(1), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(islessequal(std::numeric_limits::quiet_NaN(), Dec(1)), false); - BOOST_TEST_EQ(islessequal(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(islessequal(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), false); + std::uniform_int_distribution dist(1, 10); + + BOOST_TEST_EQ(islessequal(Dec(1), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(islessequal(std::numeric_limits::quiet_NaN() * dist(rng), Dec(1)), false); + BOOST_TEST_EQ(islessequal(std::numeric_limits::quiet_NaN() * dist(rng), std::numeric_limits::quiet_NaN()), false); + BOOST_TEST_EQ(islessequal(std::numeric_limits::infinity() * dist(rng), -std::numeric_limits::infinity()), false); BOOST_TEST_EQ(islessequal(Dec(1), Dec(0)), false); BOOST_TEST_EQ(islessequal(Dec(-2), Dec(1)), true); @@ -141,10 +150,12 @@ void test_islessequal() template void test_islessgreater() { - BOOST_TEST_EQ(islessgreater(Dec(1), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(islessgreater(std::numeric_limits::quiet_NaN(), Dec(1)), false); - BOOST_TEST_EQ(islessgreater(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), false); - BOOST_TEST_EQ(islessgreater(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), true); + std::uniform_int_distribution dist(1, 10); + + BOOST_TEST_EQ(islessgreater(Dec(1), std::numeric_limits::quiet_NaN() * dist(rng)), false); + BOOST_TEST_EQ(islessgreater(std::numeric_limits::quiet_NaN() * dist(rng), Dec(1)), false); + BOOST_TEST_EQ(islessgreater(std::numeric_limits::quiet_NaN() * dist(rng), std::numeric_limits::quiet_NaN()), false); + BOOST_TEST_EQ(islessgreater(std::numeric_limits::infinity() * dist(rng), -std::numeric_limits::infinity()), true); BOOST_TEST_EQ(islessgreater(Dec(1), Dec(0)), true); BOOST_TEST_EQ(islessgreater(Dec(-2), Dec(1)), true); @@ -517,33 +528,37 @@ void test_ilogb() BOOST_TEST_EQ(ilogb(Dec(10, 0)), 6177); } - BOOST_TEST_EQ(ilogb(Dec(0)), FP_ILOGB0); - BOOST_TEST_EQ(ilogb(std::numeric_limits::infinity()), INT_MAX); - BOOST_TEST_EQ(ilogb(std::numeric_limits::quiet_NaN()), FP_ILOGBNAN); + std::uniform_int_distribution dist(1, 2); + + BOOST_TEST_EQ(ilogb(Dec(0 * dist(rng))), FP_ILOGB0); + BOOST_TEST_EQ(ilogb(std::numeric_limits::infinity() * dist(rng)), INT_MAX); + BOOST_TEST_EQ(ilogb(std::numeric_limits::quiet_NaN() * dist(rng)), FP_ILOGBNAN); } template void test_logb() { + std::uniform_int_distribution dist(1, 1); + BOOST_DECIMAL_IF_CONSTEXPR (std::is_same::value || std::is_same::value) { - BOOST_TEST_EQ(ilogb(Dec(1, 0)), Dec(101)); - BOOST_TEST_EQ(ilogb(Dec(10, 0)), Dec(102)); + BOOST_TEST_EQ(ilogb(Dec(1 * dist(rng), 0)), Dec(101)); + BOOST_TEST_EQ(ilogb(Dec(10 * dist(rng), 0)), Dec(102)); } else BOOST_DECIMAL_IF_CONSTEXPR (std::is_same::value || std::is_same::value) { - BOOST_TEST_EQ(ilogb(Dec(1, 0)), Dec(398)); - BOOST_TEST_EQ(ilogb(Dec(10, 0)), Dec(399)); + BOOST_TEST_EQ(ilogb(Dec(1 * dist(rng), 0)), Dec(398)); + BOOST_TEST_EQ(ilogb(Dec(10 * dist(rng), 0)), Dec(399)); } else { - BOOST_TEST_EQ(ilogb(Dec(1, 0)), 6176); - BOOST_TEST_EQ(ilogb(Dec(10, 0)), 6177); + BOOST_TEST_EQ(ilogb(Dec(1 * dist(rng), 0)), 6176); + BOOST_TEST_EQ(ilogb(Dec(10 * dist(rng), 0)), 6177); } - BOOST_TEST_EQ(logb(Dec(0)), -std::numeric_limits::infinity()); - BOOST_TEST_EQ(logb(std::numeric_limits::infinity()), std::numeric_limits::infinity()); - BOOST_TEST(isnan(logb(std::numeric_limits::quiet_NaN()))); + BOOST_TEST_EQ(logb(Dec(0 * dist(rng))), -std::numeric_limits::infinity()); + BOOST_TEST_EQ(logb(std::numeric_limits::infinity() * dist(rng)), std::numeric_limits::infinity()); + BOOST_TEST(isnan(logb(std::numeric_limits::quiet_NaN() * dist(rng)))); } #ifdef _MSC_VER @@ -1224,13 +1239,96 @@ void test_exp2() } #if !defined(BOOST_DECIMAL_DISABLE_CLIB) + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + template -void test_nan() +auto test_nan() + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_ieee_type_v, T, void) { - BOOST_TEST(!isnan(nan("1") & std::numeric_limits::quiet_NaN())); - BOOST_TEST(!isnan(nan("2") & std::numeric_limits::quiet_NaN())); - BOOST_TEST(!isnan(nan("-1") & std::numeric_limits::quiet_NaN())); + using sig_type = typename T::significand_type; + + const std::array sigs {1U, 2U, 3U, 0U, 0U}; + constexpr std::array payloads {"1", "2", "3", "Junk", "999999999999999999999999999999999999999999999999999999999999"}; + + const T quiet_nan {std::numeric_limits::quiet_NaN()}; + sig_type quiet_nan_bits; + std::memcpy(&quiet_nan_bits, &quiet_nan, sizeof(sig_type)); + + const T signaling_nan {std::numeric_limits::signaling_NaN()}; + sig_type signaling_nan_bits; + std::memcpy(&signaling_nan_bits, &signaling_nan, sizeof(sig_type)); + + for (std::size_t i {}; i < sigs.size(); ++i) + { + const auto payload {nan(payloads[i])}; + BOOST_TEST(isnan(payload)); + BOOST_TEST(!issignaling(payload)); + + // Check the payload + sig_type bits {}; + std::memcpy(&bits, &payload, sizeof(sig_type)); + bits ^= quiet_nan_bits; + BOOST_TEST_EQ(bits, sigs[i]); + + const auto payload_func_bits {read_payload(payload)}; + BOOST_TEST_EQ(payload_func_bits, bits); + } + + for (std::size_t i {}; i < sigs.size(); ++i) + { + const auto payload {snan(payloads[i])}; + BOOST_TEST(isnan(payload)); + BOOST_TEST(issignaling(payload)); + + // Check the payload + sig_type bits {}; + std::memcpy(&bits, &payload, sizeof(sig_type)); + bits ^= signaling_nan_bits; + BOOST_TEST_EQ(bits, sigs[i]); + + const auto payload_func_bits {read_payload(payload)}; + BOOST_TEST_EQ(payload_func_bits, bits); + } } + +template +auto test_nan() + BOOST_DECIMAL_REQUIRES_RETURN(detail::is_fast_type_v, T, void) +{ + using sig_type = typename T::significand_type; + + const std::array sigs {1U, 2U, 3U, 0U, 0U}; + constexpr std::array payloads {"1", "2", "3", "Junk", "999999999999999999999999999999999999999999999999999999999999"}; + + for (std::size_t i {}; i < sigs.size(); ++i) + { + const auto payload {nan(payloads[i])}; + BOOST_TEST(isnan(payload)); + BOOST_TEST(!issignaling(payload)); + + const auto recovered_payload {read_payload(payload)}; + BOOST_TEST_EQ(recovered_payload, sigs[i]); + } + + for (std::size_t i {}; i < sigs.size(); ++i) + { + const auto payload {snan(payloads[i])}; + BOOST_TEST(isnan(payload)); + BOOST_TEST(issignaling(payload)); + + const auto recovered_payload {read_payload(payload)}; + BOOST_TEST_EQ(recovered_payload, sigs[i]); + } +} + +#if defined(__GNUC__) && __GNUC__ >= 8 +# pragma GCC diagnostic pop +#endif + #endif template @@ -1509,16 +1607,16 @@ int main() test_llround(); test_nextafter(); - test_nexttoward(); - test_nextafter(); - test_nexttoward(); - test_nextafter(); - test_nexttoward(); - test_nextafter(); + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE + test_nexttoward(); + test_nexttoward(); + test_nexttoward(); test_nexttoward(); + #endif test_pow(); test_pow(); @@ -1533,6 +1631,10 @@ int main() test_nan(); test_nan(); test_nan(); + + test_nan(); + test_nan(); + test_nan(); #endif test_log2(); diff --git a/test/test_constants.cpp b/test/test_constants.cpp index 06144a05a..6c4a0b344 100644 --- a/test/test_constants.cpp +++ b/test/test_constants.cpp @@ -29,7 +29,8 @@ void test_constants() BOOST_TEST_EQ(Dec(0.5641895835477562869), inv_sqrtpi_v); BOOST_TEST_EQ(Dec(0.6931471805599453094), ln2_v); BOOST_TEST_EQ(Dec(2.302585092994045684), ln10_v); - BOOST_TEST_EQ(Dec(1.414213562373095049), sqrt2_v); + constexpr Dec root2 = Dec{UINT64_C(1414213562373095049), -18}; // Rounds different for decimal32 since it terminates with 35 + BOOST_TEST_EQ(root2, sqrt2_v); BOOST_TEST_EQ(Dec(1.732050807568877294), sqrt3_v); BOOST_TEST(abs(Dec(0.707106781186547524) - inv_sqrt2_v) <= std::numeric_limits::epsilon()); BOOST_TEST(abs(Dec(0.5773502691896257645) - inv_sqrt3_v) <= std::numeric_limits::epsilon()); @@ -50,20 +51,20 @@ void print_value(T value, const char* str) template <> void test_constants() { - BOOST_TEST_EQ("2.718281828459045235360287471352662"_DL, e_v); - BOOST_TEST_EQ("1.4426950408889634073599246810018921"_DL, log2e_v); - BOOST_TEST_EQ("0.43429448190325182765112891891660508"_DL, log10e_v); - BOOST_TEST_EQ("3.1415926535897932384626433832795029"_DL, pi_v); - BOOST_TEST_EQ("0.31830988618379067153776752674502872"_DL, inv_pi_v); - BOOST_TEST_EQ("0.56418958354775628694807945156077259"_DL, inv_sqrtpi_v); - BOOST_TEST_EQ("0.69314718055994530941723212145817657"_DL, ln2_v); - BOOST_TEST_EQ("2.3025850929940456840179914546843642"_DL, ln10_v); - BOOST_TEST_EQ("1.4142135623730950488016887242096981"_DL, sqrt2_v); - BOOST_TEST_EQ("1.7320508075688772935274463415058724"_DL, sqrt3_v); - BOOST_TEST_EQ("0.70710678118654752440084436210484904"_DL, inv_sqrt2_v); - BOOST_TEST_EQ("0.57735026918962576450914878050195746"_DL, inv_sqrt3_v); - BOOST_TEST_EQ("0.57721566490153286060651209008240243"_DL, egamma_v); - BOOST_TEST_EQ("1.6180339887498948482045868343656381"_DL, phi_v); + BOOST_TEST_EQ("2.7182818284590452353602874713526624977572470937000"_DL, e_v); + BOOST_TEST_EQ("1.4426950408889634073599246810018921374266459541530"_DL, log2e_v); + BOOST_TEST_EQ("0.43429448190325182765112891891660508229439700580367"_DL, log10e_v); + BOOST_TEST_EQ("3.1415926535897932384626433832795028841971693993751"_DL, pi_v); + BOOST_TEST_EQ("0.31830988618379067153776752674502872406891929148091"_DL, inv_pi_v); + BOOST_TEST_EQ("0.56418958354775628694807945156077258584405062932900"_DL, inv_sqrtpi_v); + BOOST_TEST_EQ("0.69314718055994530941723212145817656807550013436026"_DL, ln2_v); + BOOST_TEST_EQ("2.3025850929940456840179914546843642076011014886288"_DL, ln10_v); + BOOST_TEST_EQ("1.4142135623730950488016887242096980785696718753769"_DL, sqrt2_v); + BOOST_TEST_EQ("1.7320508075688772935274463415058723669428052538104"_DL, sqrt3_v); + BOOST_TEST_EQ("0.70710678118654752440084436210484903928483593768847"_DL, inv_sqrt2_v); + BOOST_TEST_EQ("0.57735026918962576450914878050195745564760175127013"_DL, inv_sqrt3_v); + BOOST_TEST_EQ("0.57721566490153286060651209008240243104215933593992"_DL, egamma_v); + BOOST_TEST_EQ("1.6180339887498948482045868343656381177203091798058"_DL, phi_v); BOOST_TEST_EQ(static_cast(e_v), e_v); BOOST_TEST_EQ(static_cast(log2e_v), log2e_v); @@ -108,20 +109,25 @@ int main() test_defaults(); #ifdef BOOST_DECIMAL_GENERATE_CONSTANT_SIGS - print_value("2.718281828459045235360287471352662"_DL, "e"); - print_value("1.4426950408889634073599246810018921"_DL, "log2"); - print_value("0.43429448190325182765112891891660508"_DL, "log10"); - print_value("3.1415926535897932384626433832795029"_DL, "pi"); - print_value("0.31830988618379067153776752674502872"_DL, "inv_pi"); - print_value("0.56418958354775628694807945156077259"_DL, "inv_sqrt_pi"); - print_value("0.69314718055994530941723212145817657"_DL, "ln2"); - print_value("2.3025850929940456840179914546843642"_DL, "ln10"); - print_value("1.4142135623730950488016887242096981"_DL, "sqrt(2)"); - print_value("1.7320508075688772935274463415058724"_DL, "sqrt(3)"); - print_value("0.70710678118654752440084436210484904"_DL, "1/sqrt(2)"); - print_value("0.57735026918962576450914878050195746"_DL, "1/sqrt(3)"); - print_value("0.57721566490153286060651209008240243"_DL, "egamma"); - print_value("1.6180339887498948482045868343656381"_DL, "phi"); + print_value("2.7182818284590452353602874713526624977572470937000"_DL, "e"); + print_value("1.4426950408889634073599246810018921374266459541530"_DL, "log2e"); + print_value("0.43429448190325182765112891891660508229439700580367"_DL, "log10e"); + print_value("0.30102999566398119521373889472449302676818988146211"_DL, "log10_2"); + print_value("3.1415926535897932384626433832795028841971693993751"_DL, "pi"); + print_value("0.78539816339744830961566084581987572104929234984378"_DL, "pi_over_four"); + print_value("0.31830988618379067153776752674502872406891929148091"_DL, "inv_pi"); + print_value("0.56418958354775628694807945156077258584405062932900"_DL, "inv_sqrt_pi"); + print_value("0.69314718055994530941723212145817656807550013436026"_DL, "ln2"); + print_value("2.3025850929940456840179914546843642076011014886288"_DL, "ln10"); + print_value("1.4142135623730950488016887242096980785696718753769"_DL, "sqrt(2)"); + print_value("1.7320508075688772935274463415058723669428052538104"_DL, "sqrt(3)"); + print_value("3.1622776601683793319988935444327185337195551393252"_DL, "sqrt(10)"); + print_value("1.2599210498948731647672106072782283505702514647015"_DL, "cbrt(2)"); + print_value("2.1544346900318837217592935665193504952593449421921"_DL, "cbrt(10)"); + print_value("0.70710678118654752440084436210484903928483593768847"_DL, "1/sqrt(2)"); + print_value("0.57735026918962576450914878050195745564760175127013"_DL, "1/sqrt(3)"); + print_value("0.57721566490153286060651209008240243104215933593992"_DL, "egamma"); + print_value("1.6180339887498948482045868343656381177203091798058"_DL, "phi"); #endif return boost::report_errors(); diff --git a/test/test_constexpr_rounding_mode.cpp b/test/test_constexpr_rounding_mode.cpp new file mode 100644 index 000000000..a69154e61 --- /dev/null +++ b/test/test_constexpr_rounding_mode.cpp @@ -0,0 +1,28 @@ +// Copyright 2023 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + + +#define BOOST_DECIMAL_FE_DEC_DOWNWARD +#include +#include + +using namespace boost::decimal; + +int main() +{ + BOOST_TEST(_boost_decimal_global_rounding_mode == rounding_mode::fe_dec_downward); + BOOST_TEST(_boost_decimal_global_rounding_mode == _boost_decimal_global_runtime_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == rounding_mode::fe_dec_downward); + + #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + + BOOST_TEST(boost::decimal::fesetround(rounding_mode::fe_dec_default) == rounding_mode::fe_dec_default); + BOOST_TEST(_boost_decimal_global_rounding_mode == rounding_mode::fe_dec_downward); + BOOST_TEST(_boost_decimal_global_rounding_mode != _boost_decimal_global_runtime_rounding_mode); + BOOST_TEST(boost::decimal::fegetround() == rounding_mode::fe_dec_default); + + #endif + + return boost::report_errors(); +} diff --git a/test/test_cosh.cpp b/test/test_cosh.cpp index 6ea567867..4cc0719da 100644 --- a/test/test_cosh.cpp +++ b/test/test_cosh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -103,9 +104,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -339,8 +340,8 @@ auto main() -> int { auto result_is_ok = true; - const auto result_pos_is_ok = local::test_cosh(96, false, 0.03125L, 32.0L); - const auto result_neg_is_ok = local::test_cosh(96, true, 0.03125L, 32.0L); + const auto result_pos_is_ok = local::test_cosh(128, false, 0.03125L, 32.0L); + const auto result_neg_is_ok = local::test_cosh(128, true, 0.03125L, 32.0L); const auto result_pos_narrow_is_ok = local::test_cosh(24, false, 0.125L, 8.0L); const auto result_neg_narrow_is_ok = local::test_cosh(24, true, 0.125L, 8.0L); diff --git a/test/test_decimal128_basis.cpp b/test/test_decimal128_basis.cpp index a383e93a7..758e3315e 100644 --- a/test/test_decimal128_basis.cpp +++ b/test/test_decimal128_basis.cpp @@ -14,61 +14,6 @@ using namespace boost::decimal; -#if BOOST_DECIMAL_ENDIAN_LITTLE_BYTE && defined(BOOST_DECIMAL_HAS_INT128) -void test_binary_constructor() -{ - decimal128_t one(0b1, -6175); - // 0 for sign - // 00000 for combination field - // 00000000 for exp - // 1 for significand - BOOST_TEST_EQ(bit_string(one), "4000000000001"); - - decimal128_t neg_one(-0b1, -6175); - // 1 for sign - // 00000 for combination field - // 00000000 for exp - // 1 for significand - BOOST_TEST_EQ(bit_string(neg_one), "80004000000000001"); - - decimal128_t two(0b10, -6175); - // 0 for sign - // 00000 for combination field - // 00000000 for exp - // 2 for significand - BOOST_TEST_EQ(bit_string(two), "4000000000002"); - - decimal128_t three(0b11, -6175); - // 0 for sign - // 00000 for combination field - // 00000000 for exp - // 3 for significand - BOOST_TEST_EQ(bit_string(three), "4000000000003"); - - decimal128_t big(UINT64_MAX, -6175); - // 0 for sign - // 00000 for combination field - // 00000000 for exp - // FFFFFFFFFFFFFFFF for significand - BOOST_TEST_EQ(bit_string(big), "400000000000ffffffffffffffff"); - - decimal128_t onee1(0b1, -6174); - // 0 for sign - // 00000 for combination field - // 00000001 for exp - // 1 for significand - BOOST_TEST_EQ(bit_string(onee1), "8000000000001"); -} - -#else - -void test_binary_constructor() -{ - //nothing -} - -#endif - void test_non_finite_values() { const decimal128_t one(0b1, 0); @@ -123,7 +68,6 @@ void test_float_constructor() int main() { - test_binary_constructor(); test_non_finite_values(); test_float_constructor(); diff --git a/test/test_decimal32.cpp b/test/test_decimal32.cpp index f31737ebc..a3bdc32e4 100644 --- a/test/test_decimal32.cpp +++ b/test/test_decimal32.cpp @@ -417,31 +417,6 @@ void test_construct_from_integer() } } -template -void test_construct_from_float() -{ - constexpr decimal32_t one(1, 0); - decimal32_t float_one(T(1)); - if(!BOOST_TEST_EQ(one, float_one)) - { - debug_pattern(float_one); // LCOV_EXCL_LINE - } - - constexpr decimal32_t fraction(12345, -4); - decimal32_t float_frac(T(1.2345)); - if(!BOOST_TEST_EQ(fraction, float_frac)) - { - debug_pattern(float_frac); // LCOV_EXCL_LINE - } - - constexpr decimal32_t neg_frac(98123, -4, true); - decimal32_t neg_float_frac(T(-9.8123)); - if(!BOOST_TEST_EQ(neg_frac, neg_float_frac)) - { - debug_pattern(neg_float_frac); // LCOV_EXCL_LINE - } -} - template void spot_check_addition(T a, T b, T res) { @@ -491,16 +466,6 @@ int main() test_construct_from_integer(); test_construct_from_integer(); - test_construct_from_float(); - test_construct_from_float(); - - #if BOOST_DECIMAL_LDBL_BITS != 128 - test_construct_from_float(); - #endif - #ifdef BOOST_DECIMAL_HAS_FLOAT128 - //test_construct_from_float<__float128>(); - #endif - test_comp(); test_addition(); diff --git a/test/test_decimal32_fast_basis.cpp b/test/test_decimal32_fast_basis.cpp index 7fd9a81f5..ca6f8d3ee 100644 --- a/test/test_decimal32_fast_basis.cpp +++ b/test/test_decimal32_fast_basis.cpp @@ -91,6 +91,10 @@ void test_decimal_constructor() decimal_fast32_t rounded_big(1234568, 2); BOOST_TEST_EQ(big, rounded_big); + + // Try to make a denorm value + decimal_fast32_t denorm(1000000, -102); + BOOST_TEST_EQ(denorm, 0); } void test_non_finite_values() @@ -109,6 +113,7 @@ void test_non_finite_values() BOOST_TEST(std::numeric_limits::has_signaling_NaN); BOOST_TEST(isnan(std::numeric_limits::quiet_NaN())); BOOST_TEST(isnan(std::numeric_limits::signaling_NaN())); + BOOST_TEST(isnan(decimal_fast32_t{std::numeric_limits::quiet_NaN()})); BOOST_TEST(!isnan(one)); BOOST_TEST(!isnan(std::numeric_limits::infinity())); BOOST_TEST(!isnan(-std::numeric_limits::infinity())); @@ -158,6 +163,8 @@ void test_non_finite_values() BOOST_TEST(isnan(detail::check_non_finite(std::numeric_limits::quiet_NaN() * dist(rng), one))); BOOST_TEST(isinf(detail::check_non_finite(one, std::numeric_limits::infinity() * dist(rng)))); BOOST_TEST(isinf(detail::check_non_finite(std::numeric_limits::infinity() * dist(rng), one))); + + BOOST_TEST(isnan(decimal_fast32_t{std::numeric_limits::quiet_NaN() * dist(rng)})); } #if !defined(__GNUC__) || (__GNUC__ != 7 && __GNUC__ != 8) @@ -205,7 +212,7 @@ void test_addition() // Pre- and post- increment BOOST_TEST_EQ(mutable_one, one); - BOOST_TEST_EQ(mutable_one++, two); + BOOST_TEST_EQ(mutable_one++, one); BOOST_TEST_EQ(++mutable_one, three); // Different orders of magnitude @@ -255,7 +262,7 @@ void test_subtraction() // Pre- and post- increment BOOST_TEST_EQ(mutable_three, three); - BOOST_TEST_EQ(mutable_three--, two); + BOOST_TEST_EQ(mutable_three--, three); BOOST_TEST_EQ(--mutable_three, one); // Different orders of magnitude @@ -439,7 +446,7 @@ int main() test_construct_from_float(); test_construct_from_float(); - #if BOOST_DECIMAL_LDBL_BITS != 128 + #if BOOST_DECIMAL_LDBL_BITS != 128 && !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) test_construct_from_float(); #endif diff --git a/test/test_decimal32_fast_stream.cpp b/test/test_decimal32_fast_stream.cpp index 416477c25..ccae5fc0e 100644 --- a/test/test_decimal32_fast_stream.cpp +++ b/test/test_decimal32_fast_stream.cpp @@ -15,7 +15,7 @@ void test_istream() { decimal_fast32_t val; std::stringstream in; - in.str("1.234567e+06"); + in.str("+1.234567e+06"); in >> val; BOOST_TEST_EQ(val, decimal_fast32_t(1234567, 0)); @@ -113,6 +113,30 @@ void test_ostream() #ifndef BOOST_DECIMAL_DISABLE_EXCEPTIONS +void test_issue_1127_locales(const char* locale) +{ + try + { + const std::locale a(locale); + + std::stringstream out_double; + out_double.imbue(a); + out_double << 1122.89; + + constexpr decimal_fast32_t val4{ 112289, -2 }; + std::stringstream out_decimal; + out_decimal.imbue(a); + out_decimal << val4; + + BOOST_TEST_CSTR_EQ(out_decimal.str().c_str(), out_double.str().c_str()); + } + catch (...) + { + std::cerr << "Locale not installed. Skipping test." << std::endl; + return; + } +} + void test_locales() { const char buffer[] = "1,1897e+02"; @@ -152,7 +176,14 @@ int main() test_ostream(); // Homebrew GCC does not support locales - #if !(defined(__GNUC__) && __GNUC__ >= 5 && defined(__APPLE__)) && !defined(BOOST_DECIMAL_QEMU_TEST) && !defined(BOOST_DECIMAL_DISABLE_EXCEPTIONS) + #if !(defined(__GNUC__) && __GNUC__ >= 8 && defined(__APPLE__)) && !defined(BOOST_DECIMAL_QEMU_TEST) && !defined(BOOST_DECIMAL_DISABLE_EXCEPTIONS) + #ifndef _MSC_VER + test_issue_1127_locales("en_US.UTF-8"); // . decimal, , thousands + test_issue_1127_locales("de_DE.UTF-8"); // , decimal, . thousands + #if (defined(__clang__) && __clang_major__ > 9) || (defined(__GNUC__) && __GNUC__ > 9) + test_issue_1127_locales("fr_FR.UTF-8"); // , decimal, . thousands + #endif + #endif test_locales(); #endif diff --git a/test/test_decimal32_stream.cpp b/test/test_decimal32_stream.cpp index 1027829ba..e8e795229 100644 --- a/test/test_decimal32_stream.cpp +++ b/test/test_decimal32_stream.cpp @@ -15,9 +15,12 @@ void test_istream() { decimal32_t val; std::stringstream in; - in.str("1.234567e+06"); + in.str("+1.234567e+06"); in >> val; BOOST_TEST_EQ(val, decimal32_t(1234567, 0)); + in.clear(); + const auto endpos {in.tellg()}; + BOOST_TEST_EQ(endpos, 13); errno = 0; decimal32_t val2; diff --git a/test/test_decimal64_fast_basis.cpp b/test/test_decimal64_fast_basis.cpp index 92aa567ec..f9329447f 100644 --- a/test/test_decimal64_fast_basis.cpp +++ b/test/test_decimal64_fast_basis.cpp @@ -143,6 +143,8 @@ void test_non_finite_values() BOOST_TEST(isnan(detail::check_non_finite(std::numeric_limits::quiet_NaN() * dist(rng), one))); BOOST_TEST(isinf(detail::check_non_finite(one, std::numeric_limits::infinity() * dist(rng)))); BOOST_TEST(isinf(detail::check_non_finite(std::numeric_limits::infinity() * dist(rng), one))); + + BOOST_TEST(isnan(decimal_fast64_t{std::numeric_limits::quiet_NaN() * static_cast(dist(rng))})); } #if !defined(__GNUC__) || (__GNUC__ != 7 && __GNUC__ != 8) @@ -190,7 +192,7 @@ void test_addition() // Pre- and post- increment BOOST_TEST_EQ(mutable_one, one); - BOOST_TEST_EQ(mutable_one++, two); + BOOST_TEST_EQ(mutable_one++, one); BOOST_TEST_EQ(++mutable_one, three); // Different orders of magnitude @@ -234,7 +236,7 @@ void test_subtraction() // Pre- and post- increment BOOST_TEST_EQ(mutable_three, three); - BOOST_TEST_EQ(mutable_three--, two); + BOOST_TEST_EQ(mutable_three--, three); BOOST_TEST_EQ(--mutable_three, one); // Different orders of magnitude @@ -411,7 +413,9 @@ int main() test_construct_from_float(); test_construct_from_float(); + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE test_construct_from_float(); + #endif #if defined(BOOST_DECIMAL_HAS_FLOAT128) && (!defined(__clang_major__) || __clang_major__ >= 13) test_construct_from_float<__float128>(); #endif diff --git a/test/test_decimal64_fast_stream.cpp b/test/test_decimal64_fast_stream.cpp index 3ca8d8173..f512f91fc 100644 --- a/test/test_decimal64_fast_stream.cpp +++ b/test/test_decimal64_fast_stream.cpp @@ -16,7 +16,7 @@ void test_istream() { decimal_fast64_t val; std::stringstream in; - in.str("1.234567e+06"); + in.str("+1.234567e+06"); in >> val; BOOST_TEST_EQ(val, decimal_fast64_t(1234567, 0)); diff --git a/test/test_decimal64_stream.cpp b/test/test_decimal64_stream.cpp index 8b04042a4..08d549036 100644 --- a/test/test_decimal64_stream.cpp +++ b/test/test_decimal64_stream.cpp @@ -16,7 +16,7 @@ void test_istream() { decimal64_t val; std::stringstream in; - in.str("1.234567e+06"); + in.str("+1.234567e+06"); in >> val; BOOST_TEST_EQ(val, decimal64_t(1234567, 0)); diff --git a/test/test_decimal_quantum.cpp b/test/test_decimal_quantum.cpp index 5af453324..3672419a9 100644 --- a/test/test_decimal_quantum.cpp +++ b/test/test_decimal_quantum.cpp @@ -3,7 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include "mini_to_chars.hpp" - +#include "testing_config.hpp" #include #include #include @@ -18,9 +18,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/test_downward_rounding.cpp b/test/test_downward_rounding.cpp new file mode 100644 index 000000000..9112169d8 --- /dev/null +++ b/test/test_downward_rounding.cpp @@ -0,0 +1,100 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +// Use compile-time rounding mode change so the test run on all platforms +#define BOOST_DECIMAL_FE_DEC_DOWNWARD + +#include +#include +#include +#include +#include + +template +void test(const char* lhs_str, const char* rhs_str, const char* result_str, Func f) +{ + const T lhs {lhs_str}; + const T rhs {rhs_str}; + const T result {result_str}; + + const T func_result {f(lhs, rhs)}; + + BOOST_TEST_EQ(func_result, result); +} + +template +void test_add(const char* lhs, const char* rhs, const char* result) +{ + std::cerr << std::setprecision(std::numeric_limits::max_digits10); + test(lhs, rhs, result, std::plus<>()); + test(rhs, lhs, result, std::plus<>()); +} + +template +void test_sub(const char* lhs, const char* rhs, const char* result) +{ + std::cerr << std::setprecision(std::numeric_limits::max_digits10); + test(lhs, rhs, result, std::minus<>()); +} + +int main() +{ + using namespace boost::decimal; + + test_add("1e+2", "-1e-383", "99.99999999999999"); + test_add("1e+1", "-1e-383", "9.999999999999999"); + + test_add("1e+2", "-1e-383", "99.99999999999999"); + test_add("1e+1", "-1e-383", "9.999999999999999"); + + test_sub("1e+2", "1e-383", "99.99999999999999"); + test_sub("1e+1", "1e-383", "9.999999999999999"); + + test_sub("1e+2", "1e-383", "99.99999999999999"); + test_sub("1e+1", "1e-383", "9.999999999999999"); + + test_add("1e+2", "-1e-20", "99.99999"); + test_add("1e+1", "-1e-20", "9.999999"); + + test_add("1e+2", "-1e-20", "99.99999"); + test_add("1e+1", "-1e-20", "9.999999"); + + test_sub("1e+2", "1e-20", "99.99999"); + test_sub("1e+1", "1e-20", "9.999999"); + + test_sub("1e+2", "1e-20", "99.99999"); + test_sub("1e+1", "1e-20", "9.999999"); + + test_add("1e+2", "-1e-383", "99.99999999999999999999999999999999"); + test_add("1e+1", "-1e-383", "9.999999999999999999999999999999999"); + + test_add("1e+2", "-1e-383", "99.99999999999999999999999999999999"); + test_add("1e+1", "-1e-383", "9.999999999999999999999999999999999"); + + test_sub("1e+2", "1e-383", "99.99999999999999999999999999999999"); + test_sub("1e+1", "1e-383", "9.999999999999999999999999999999999"); + + test_sub("1e+2", "1e-383", "99.99999999999999999999999999999999"); + test_sub("1e+1", "1e-383", "9.999999999999999999999999999999999"); + + test_add("9.999999e20", "0", "9.999999e20"); + test_add("9.999999e20", "0", "9.999999e20"); + + test_sub("9.999999e20", "0", "9.999999e20"); + test_sub("9.999999e20", "0", "9.999999e20"); + + test_add("9.999999999999999e200", "0", "9.999999999999999e200"); + test_add("9.999999999999999e200", "0", "9.999999999999999e200"); + + test_sub("9.999999999999999e200", "0", "9.999999999999999e200"); + test_sub("9.999999999999999e200", "0", "9.999999999999999e200"); + + test_add("9.999999999999999e200", "0", "9.999999999999999e200"); + test_add("9.999999999999999e200", "0", "9.999999999999999e200"); + + test_sub("9.999999999999999e200", "0", "9.999999999999999e200"); + test_sub("9.999999999999999e200", "0", "9.999999999999999e200"); + + return boost::report_errors(); +} diff --git a/test/test_dpd_conversions.cpp b/test/test_dpd_conversions.cpp index 9dd1728f5..5dd4ddb7e 100644 --- a/test/test_dpd_conversions.cpp +++ b/test/test_dpd_conversions.cpp @@ -63,6 +63,31 @@ void test_float_range() } } +// See: https://github.com/cppalliance/decimal/issues/1081 +template +void test_git_issue_1081() +{ + std::mt19937_64 rng(42); + std::uniform_int_distribution dist(std::numeric_limits::min(), + std::numeric_limits::max()); + + for (std::size_t i {}; i < 1024; ++i) + { + const T val {dist(rng), std::numeric_limits::min_exponent}; + const T return_val {roundtrip(val)}; + BOOST_TEST_EQ(val, return_val); + } + + for (std::size_t i {}; i < 1024; ++i) + { + const T val {dist(rng), std::numeric_limits::max_exponent - std::numeric_limits::digits10 - 1}; + const T return_val {roundtrip(val)}; + BOOST_TEST_EQ(val, return_val); + } + + BOOST_TEST(roundtrip(std::numeric_limits::denorm_min())); +} + int main() { test(); @@ -83,5 +108,9 @@ int main() test_float_range(); test_float_range(); + test_git_issue_1081(); + test_git_issue_1081(); + test_git_issue_1081(); + return boost::report_errors(); } diff --git a/test/test_edges_and_behave.cpp b/test/test_edges_and_behave.cpp index cb5d835c4..a8f931a92 100644 --- a/test/test_edges_and_behave.cpp +++ b/test/test_edges_and_behave.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include @@ -84,15 +85,20 @@ namespace local { static_cast(i); - const auto local_nan_to_construct_f = decimal_type { std::numeric_limits::quiet_NaN() * static_cast(dist(gen)) }; + const auto local_nan_to_construct_f = decimal_type { std::numeric_limits::quiet_NaN() * dist(gen) }; const auto local_nan_to_construct_d = decimal_type { std::numeric_limits::quiet_NaN() * static_cast(dist(gen)) }; + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE const auto local_nan_to_construct_ld = decimal_type { std::numeric_limits::quiet_NaN() * static_cast(dist(gen)) }; + #endif const auto result_nan_construct_is_ok = ( isnan(local_nan_to_construct_f) && isnan(local_nan_to_construct_d) + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE && isnan(local_nan_to_construct_ld) + #endif ); BOOST_TEST(result_nan_construct_is_ok); @@ -102,7 +108,7 @@ namespace local { const auto sum_nan_01 = local_nan_to_construct_f + 1; const auto sum_nan_02 = local_nan_to_construct_f + decimal_type { 2, 0 }; - const auto sum_nan_03 = local_nan_to_construct_f + decimal_type { 3.0L }; + const auto sum_nan_03 = local_nan_to_construct_f + decimal_type { 3.0 }; const auto result_sum_nan_is_ok = (isnan(sum_nan_01) && isnan(sum_nan_02) && isnan(sum_nan_03)); @@ -114,7 +120,7 @@ namespace local { const auto dif_nan_01 = local_nan_to_construct_f - 1; const auto dif_nan_02 = local_nan_to_construct_f - decimal_type { 2, 0 }; - const auto dif_nan_03 = local_nan_to_construct_f - decimal_type { 3.0L }; + const auto dif_nan_03 = local_nan_to_construct_f - decimal_type { 3.0 }; const auto result_dif_nan_is_ok = (isnan(dif_nan_01) && isnan(dif_nan_02) && isnan(dif_nan_03)); @@ -301,7 +307,7 @@ namespace local const decimal_type c = a + b; - const auto result_prec_add_is_ok = (c == static_cast(123456.8L)); + const auto result_prec_add_is_ok = (c == static_cast(123456.8)); BOOST_TEST(result_prec_add_is_ok); @@ -317,7 +323,7 @@ namespace local const decimal_type c = a + b; - const auto result_prec_add_vary_is_ok = (c > decimal_type(123456.709876543L)); + const auto result_prec_add_vary_is_ok = (c > decimal_type(123456.709876543)); BOOST_TEST(result_prec_add_vary_is_ok); @@ -511,5 +517,5 @@ auto my_one () -> boost::decimal::decimal32_t& { static boost::decimal::decimal3 auto my_inf () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_inf = std::numeric_limits::infinity(); return val_inf; } auto my_nan () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_nan = std::numeric_limits::quiet_NaN(); return val_nan; } auto my_pi () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_pi = boost::decimal::numbers::pi_v; return val_pi; } -auto my_a () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_a { 1.234567e5L }; return val_a; } -auto my_b () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_b { 9.876543e-2L }; return val_b; } +auto my_a () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_a { 1.234567e5 }; return val_a; } +auto my_b () -> boost::decimal::decimal32_t& { static boost::decimal::decimal32_t val_b { 9.876543e-2 }; return val_b; } diff --git a/test/test_edit_members.cpp b/test/test_edit_members.cpp index c4e36c801..0fa887c72 100644 --- a/test/test_edit_members.cpp +++ b/test/test_edit_members.cpp @@ -4,6 +4,7 @@ #define BOOST_DECIMAL_DEBUG_MEMBERS +#include "testing_config.hpp" #include #include #include @@ -12,9 +13,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/test_ellint_1.cpp b/test/test_ellint_1.cpp index 9ce19e78e..b0fd39d2d 100644 --- a/test/test_ellint_1.cpp +++ b/test/test_ellint_1.cpp @@ -6,6 +6,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -29,6 +30,7 @@ # if __GNUC__ == 10 # pragma GCC diagnostic ignored "-Wmisleading-indentation" # endif +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -63,7 +65,7 @@ namespace local #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) static constexpr auto N = static_cast(64U); #else -static constexpr auto N = static_cast(8U); +static constexpr auto N = static_cast(8); #endif static std::mt19937_64 rng(42); diff --git a/test/test_ellint_2.cpp b/test/test_ellint_2.cpp index b1f8c1450..bd9fde8f7 100644 --- a/test/test_ellint_2.cpp +++ b/test/test_ellint_2.cpp @@ -6,6 +6,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -29,6 +30,7 @@ # if __GNUC__ == 10 # pragma GCC diagnostic ignored "-Wmisleading-indentation" # endif +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -63,7 +65,7 @@ namespace local #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) static constexpr auto N = static_cast(64U); #else -static constexpr auto N = static_cast(8U); +static constexpr auto N = static_cast(8); #endif static std::mt19937_64 rng(42); diff --git a/test/test_erf.cpp b/test/test_erf.cpp index 9e5c9b859..e5d52097a 100644 --- a/test/test_erf.cpp +++ b/test/test_erf.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include #include @@ -33,7 +35,9 @@ // Needed to reduce CI runtime #ifdef _MSC_VER -# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +# ifndef BOOST_DECIMAL_REDUCE_TEST_DEPTH +# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +# endif #endif #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && !defined(_MSC_VER) @@ -220,6 +224,7 @@ void test_erf() BOOST_TEST_EQ(erf(T{120}), T{1} * dist(rng)); } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) template <> void test_erf() { @@ -457,6 +462,8 @@ void test_erf() BOOST_TEST_EQ(erf(decimal128_t{120}), decimal128_t{1} * dist(rng)); } +#endif + template void test_erfc() { @@ -638,6 +645,8 @@ void test_erfc() BOOST_TEST_EQ(erfc(T{120}), T{0} * dist(rng)); } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + template <> void test_erfc() { @@ -875,6 +884,8 @@ void test_erfc() BOOST_TEST_EQ(erfc(decimal128_t{120}), decimal128_t{0} * dist(rng)); } +#endif + int main() { #ifdef BOOST_DECIMAL_GENERATE_CONSTANT_SIGS @@ -1136,7 +1147,7 @@ int main() test_erfc(); test_erfc(); - #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && BOOST_DECIMAL_LDBL_BITS != 128 && !defined(__i386__) && !defined(_WIN32) + #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && BOOST_DECIMAL_LDBL_BITS != 128 && !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) && !defined(__i386__) && !defined(_WIN32) test_erf(); test_erfc(); #endif diff --git a/test/test_exp.cpp b/test/test_exp.cpp index c37ecab50..ecf164cf3 100644 --- a/test/test_exp.cpp +++ b/test/test_exp.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -105,9 +106,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x400)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) diff --git a/test/test_expm1.cpp b/test/test_expm1.cpp index da22e8bb7..c2660ec6a 100644 --- a/test/test_expm1.cpp +++ b/test/test_expm1.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -102,9 +103,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -326,8 +327,8 @@ auto main() -> int { auto result_is_ok = true; - const auto result_pos_is_ok = local::test_expm1(96, false, 0.03125L, 32.0L); - const auto result_neg_is_ok = local::test_expm1(96, true, 0.03125L, 32.0L); + const auto result_pos_is_ok = local::test_expm1(128, false, 0.03125L, 32.0L); + const auto result_neg_is_ok = local::test_expm1(128, true, 0.03125L, 32.0L); const auto result_pos_narrow_is_ok = local::test_expm1(24, false, 0.125L, 8.0L); const auto result_neg_narrow_is_ok = local::test_expm1(24, true, 0.125L, 8.0L); diff --git a/test/test_fast_math.cpp b/test/test_fast_math.cpp index 6e8ec10d7..9d1d28917 100644 --- a/test/test_fast_math.cpp +++ b/test/test_fast_math.cpp @@ -4,6 +4,7 @@ #define BOOST_DECIMAL_FAST_MATH +#include "testing_config.hpp" #include #include #include @@ -12,9 +13,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // NOLINTNEXTLINE : Seed with a constant for repeatability diff --git a/test/test_fenv.cpp b/test/test_fenv.cpp index 11f051c53..a093eed61 100644 --- a/test/test_fenv.cpp +++ b/test/test_fenv.cpp @@ -10,9 +10,9 @@ using namespace boost::decimal; void test_environment() { - BOOST_TEST(boost::decimal::fegetround() == boost::decimal::rounding_mode::fe_dec_to_nearest_from_zero); - BOOST_TEST(boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_to_nearest) == boost::decimal::rounding_mode::fe_dec_to_nearest); BOOST_TEST(boost::decimal::fegetround() == boost::decimal::rounding_mode::fe_dec_to_nearest); + BOOST_TEST(boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_to_nearest_from_zero) == boost::decimal::rounding_mode::fe_dec_to_nearest_from_zero); + BOOST_TEST(boost::decimal::fegetround() == boost::decimal::rounding_mode::fe_dec_to_nearest_from_zero); BOOST_TEST(boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_downward) == boost::decimal::rounding_mode::fe_dec_downward); BOOST_TEST(boost::decimal::fegetround() == boost::decimal::rounding_mode::fe_dec_downward); BOOST_TEST(boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_upward) == boost::decimal::rounding_mode::fe_dec_upward); @@ -69,9 +69,8 @@ void test_constructor_rounding() int main() { - test_environment(); - #ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + test_environment(); test_constructor_rounding(); #endif diff --git a/test/test_fixed_width_trunc.cpp b/test/test_fixed_width_trunc.cpp index 44f50b097..27c46de4f 100644 --- a/test/test_fixed_width_trunc.cpp +++ b/test/test_fixed_width_trunc.cpp @@ -15,7 +15,7 @@ void test() constexpr T validation_val_1 {UINT32_C(1), 5}; constexpr T validation_val_2 {UINT32_C(12), 4}; constexpr T validation_val_3 {UINT32_C(123), 3}; - constexpr T validation_val_4 {UINT32_C(1235), 2}; + constexpr T validation_val_4 {UINT32_C(1234), 2}; constexpr T validation_val_5 {UINT32_C(12346), 1}; BOOST_TEST_EQ(rescale(test_val, 0), rescale(test_val)); diff --git a/test/test_float_conversion.cpp b/test/test_float_conversion.cpp index 0448b3fa5..72b0fda1b 100644 --- a/test/test_float_conversion.cpp +++ b/test/test_float_conversion.cpp @@ -3,6 +3,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include +#include #include #include #include @@ -62,7 +63,7 @@ void test_compute_float64() bool success {}; - // Trivial verifcation + // Trivial verification BOOST_TEST_EQ(compute_float64(1, dist(gen), false, success), 1e1); BOOST_TEST_EQ(compute_float64(0, dist(gen), true, success), -1e0); BOOST_TEST_EQ(compute_float64(308, dist(gen), false, success), 1e308); @@ -84,6 +85,20 @@ void test_compute_float64() BOOST_TEST_EQ(compute_float64(100 * static_cast(dist(gen)), UINT64_C(10000000000000000000), false, success), 10000000000000000000e100); } +void test_compute_float80_128() +{ + using boost::decimal::detail::fast_float::compute_float80_128; + + std::mt19937_64 gen(42); + std::uniform_int_distribution dist (1, 1); + + bool success {}; + + BOOST_TEST_EQ(compute_float80_128(1, dist(gen), false, success), 1e1L); + BOOST_TEST_EQ(compute_float80_128(0, dist(gen), true, success), -1e0L); + BOOST_TEST_EQ(compute_float80_128(-1, dist(gen), false, success), 1e-1L); +} + #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wstrict-aliasing" @@ -325,9 +340,13 @@ int main() { test_compute_float32(); test_compute_float64(); + test_compute_float80_128(); test_generic_binary_to_decimal(); test_generic_binary_to_decimal(); + + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE test_generic_binary_to_decimal(); + #endif test_parser(); test_hex_integer(); diff --git a/test/test_format.cpp b/test/test_format.cpp index 03927e18e..430b268b8 100644 --- a/test/test_format.cpp +++ b/test/test_format.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include using namespace boost::decimal; @@ -84,9 +87,9 @@ void test_general() template void test_fixed() { - BOOST_TEST_EQ(std::format("{:f}", T {-21, 6}), "-21000000.000000"); - BOOST_TEST_EQ(std::format("{:f}", T {-211, 6}), "-211000000.000000"); - BOOST_TEST_EQ(std::format("{:f}", T {-2111, 6}), "-2111000000.000000"); + BOOST_TEST_EQ(std::format("{:f}", T {-21, 6}), "-21000000"); + BOOST_TEST_EQ(std::format("{:f}", T {-211, 6}), "-211000000"); + BOOST_TEST_EQ(std::format("{:f}", T {-2111, 6}), "-2111000000"); BOOST_TEST_EQ(std::format("{:.0f}", T {-21, 6}), std::string{"-21000000"}); BOOST_TEST_EQ(std::format("{:.0f}", T {-211, 6}), std::string{"-211000000"}); @@ -115,13 +118,13 @@ void test_fixed() template void test_scientific() { - BOOST_TEST_EQ(std::format("{:e}", T {-21, 6}), "-2.100000e+07"); - BOOST_TEST_EQ(std::format("{:e}", T {-211, 6}), "-2.110000e+08"); - BOOST_TEST_EQ(std::format("{:e}", T {-2111, 6}), "-2.111000e+09"); + BOOST_TEST_EQ(std::format("{:e}", T {-21, 6}), "-2.1e+07"); + BOOST_TEST_EQ(std::format("{:e}", T {-211, 6}), "-2.11e+08"); + BOOST_TEST_EQ(std::format("{:e}", T {-2111, 6}), "-2.111e+09"); - BOOST_TEST_EQ(std::format("{:E}", T {-21, 6}), "-2.100000E+07"); - BOOST_TEST_EQ(std::format("{:E}", T {-211, 6}), "-2.110000E+08"); - BOOST_TEST_EQ(std::format("{:E}", T {-2111, 6}), "-2.111000E+09"); + BOOST_TEST_EQ(std::format("{:E}", T {-21, 6}), "-2.1E+07"); + BOOST_TEST_EQ(std::format("{:E}", T {-211, 6}), "-2.11E+08"); + BOOST_TEST_EQ(std::format("{:E}", T {-2111, 6}), "-2.111E+09"); BOOST_TEST_EQ(std::format("{:.0E}", T {0}), "0E+00"); BOOST_TEST_EQ(std::format("{:e}", std::numeric_limits::infinity()), "inf"); @@ -173,21 +176,21 @@ void test_scientific() template void test_hex() { - BOOST_TEST_EQ(std::format("{:.0a}", T {0}), "0p+00"); - BOOST_TEST_EQ(std::format("{:.3A}", T {0}), "0.000P+00"); - BOOST_TEST_EQ(std::format("{:a}", std::numeric_limits::infinity()), "inf"); - BOOST_TEST_EQ(std::format("{:a}", -std::numeric_limits::infinity()), "-inf"); - BOOST_TEST_EQ(std::format("{:a}", std::numeric_limits::quiet_NaN()), "nan"); - BOOST_TEST_EQ(std::format("{:a}", -std::numeric_limits::quiet_NaN()), "-nan(ind)"); - BOOST_TEST_EQ(std::format("{:a}", std::numeric_limits::signaling_NaN()), "nan(snan)"); - BOOST_TEST_EQ(std::format("{:a}", -std::numeric_limits::signaling_NaN()), "-nan(snan)"); - - BOOST_TEST_EQ(std::format("{:A}", std::numeric_limits::infinity()), "INF"); - BOOST_TEST_EQ(std::format("{:A}", -std::numeric_limits::infinity()), "-INF"); - BOOST_TEST_EQ(std::format("{:A}", std::numeric_limits::quiet_NaN()), "NAN"); - BOOST_TEST_EQ(std::format("{:A}", -std::numeric_limits::quiet_NaN()), "-NAN(IND)"); - BOOST_TEST_EQ(std::format("{:A}", std::numeric_limits::signaling_NaN()), "NAN(SNAN)"); - BOOST_TEST_EQ(std::format("{:A}", -std::numeric_limits::signaling_NaN()), "-NAN(SNAN)"); + BOOST_TEST_EQ(std::format("{:.0x}", T {0}), "0p+00"); + BOOST_TEST_EQ(std::format("{:.3X}", T {0}), "0.000P+00"); + BOOST_TEST_EQ(std::format("{:x}", std::numeric_limits::infinity()), "inf"); + BOOST_TEST_EQ(std::format("{:x}", -std::numeric_limits::infinity()), "-inf"); + BOOST_TEST_EQ(std::format("{:x}", std::numeric_limits::quiet_NaN()), "nan"); + BOOST_TEST_EQ(std::format("{:x}", -std::numeric_limits::quiet_NaN()), "-nan(ind)"); + BOOST_TEST_EQ(std::format("{:x}", std::numeric_limits::signaling_NaN()), "nan(snan)"); + BOOST_TEST_EQ(std::format("{:x}", -std::numeric_limits::signaling_NaN()), "-nan(snan)"); + + BOOST_TEST_EQ(std::format("{:X}", std::numeric_limits::infinity()), "INF"); + BOOST_TEST_EQ(std::format("{:X}", -std::numeric_limits::infinity()), "-INF"); + BOOST_TEST_EQ(std::format("{:X}", std::numeric_limits::quiet_NaN()), "NAN"); + BOOST_TEST_EQ(std::format("{:X}", -std::numeric_limits::quiet_NaN()), "-NAN(IND)"); + BOOST_TEST_EQ(std::format("{:X}", std::numeric_limits::signaling_NaN()), "NAN(SNAN)"); + BOOST_TEST_EQ(std::format("{:X}", -std::numeric_limits::signaling_NaN()), "-NAN(SNAN)"); } template @@ -197,6 +200,83 @@ void test_with_string() BOOST_TEST_EQ(std::format("Height is: {} meters", T {2}), "Height is: 2 meters"); } +template +void test_cohort_preservation() +{ + const std::array decimals = { + T {5, 4}, + T {50, 3}, + T {500, 2}, + T {5000, 1}, + T {50000, 0}, + T {500000, -1}, + T {5000000, -2}, + }; + + const std::array result_strings = { + "5e+04", + "5.0e+04", + "5.00e+04", + "5.000e+04", + "5.0000e+04", + "5.00000e+04", + "5.000000e+04", + }; + + for (std::size_t i {}; i < decimals.size(); ++i) + { + BOOST_TEST_CSTR_EQ(std::format("{:a}", decimals[i]).c_str(), result_strings[i]); + + std::string s {result_strings[i]}; + + #ifdef _MSC_VER + # pragma warning(push) + # pragma warning(disable : 4244) + #endif + + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) + { return std::toupper(c); }); + + #ifdef _MSC_VER + # pragma warning(pop) + #endif + + BOOST_TEST_CSTR_EQ(std::format("{:A}", decimals[i]).c_str(), s.c_str()); + } +} + +template +void test_locale_conversion(const char* locale, const std::string& result) +{ + try + { + const std::locale a(locale); + std::locale::global(a); + + const T value {112289, -2}; + BOOST_TEST_EQ(std::format("{:.2fL}", value), result); + } + // LCOV_EXCL_START + catch (...) + { + std::cerr << "Test not run" << std::endl; + } + // LCOV_EXCL_STOP +} + +template +void test_wide_strings() +{ + BOOST_TEST(std::format(L"{}", T{1}) == L"1"); + BOOST_TEST(std::format(L"{}", T{10}) == L"10"); + BOOST_TEST(std::format(L"{}", T{100}) == L"100"); + BOOST_TEST(std::format(L"{}", T{1000}) == L"1000"); + BOOST_TEST(std::format(L"{}", T{10000}) == L"10000"); + BOOST_TEST(std::format(L"{}", T{210000}) == L"210000"); + BOOST_TEST(std::format(L"{}", T{2100000}) == L"2100000"); +} + int main() { test_general(); @@ -234,6 +314,28 @@ int main() test_with_string(); test_with_string(); + test_cohort_preservation(); + test_cohort_preservation(); + test_cohort_preservation(); + + #if !(defined(__GNUC__) && __GNUC__ >= 5 && defined(__APPLE__)) && !defined(BOOST_DECIMAL_QEMU_TEST) && !defined(BOOST_DECIMAL_DISABLE_EXCEPTIONS) && !defined(_MSC_VER) + + test_locale_conversion("en_US.UTF-8", "1,122.89"); + test_locale_conversion("de_DE.UTF-8", "1.122,89"); + + #if (defined(__clang__) && __clang_major__ > 9) || (defined(__GNUC__) && __GNUC__ > 9) + test_locale_conversion("fr_FR.UTF-8", "1 122,89"); + #endif + + #endif + + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + return boost::report_errors(); } diff --git a/test/test_format_fmtlib.cpp b/test/test_format_fmtlib.cpp index 1efd552c7..e664ae4b8 100644 --- a/test/test_format_fmtlib.cpp +++ b/test/test_format_fmtlib.cpp @@ -9,8 +9,12 @@ #define FMT_HEADER_ONLY #include +#include #include #include +#include +#include +#include using namespace boost::decimal; @@ -130,9 +134,9 @@ void test_general() template void test_fixed() { - BOOST_TEST_EQ(fmt::format("{:f}", T {21u, 6, true}), "-21000000.000000"); - BOOST_TEST_EQ(fmt::format("{:f}", T {211u, 6, true}), "-211000000.000000"); - BOOST_TEST_EQ(fmt::format("{:f}", T {2111u, 6, true}), "-2111000000.000000"); + BOOST_TEST_EQ(fmt::format("{:f}", T {21u, 6, true}), "-21000000"); + BOOST_TEST_EQ(fmt::format("{:f}", T {211u, 6, true}), "-211000000"); + BOOST_TEST_EQ(fmt::format("{:f}", T {2111u, 6, true}), "-2111000000"); BOOST_TEST_EQ(fmt::format("{:.0f}", T {21u, 6, true}), std::string{"-21000000"}); BOOST_TEST_EQ(fmt::format("{:.0f}", T {211u, 6, true}), std::string{"-211000000"}); @@ -161,13 +165,13 @@ void test_fixed() template void test_scientific() { - BOOST_TEST_EQ(fmt::format("{:e}", T {21u, 6, true}), "-2.100000e+07"); - BOOST_TEST_EQ(fmt::format("{:e}", T {211u, 6, true}), "-2.110000e+08"); - BOOST_TEST_EQ(fmt::format("{:e}", T {2111u, 6, true}), "-2.111000e+09"); + BOOST_TEST_EQ(fmt::format("{:e}", T {21u, 6, true}), "-2.1e+07"); + BOOST_TEST_EQ(fmt::format("{:e}", T {211u, 6, true}), "-2.11e+08"); + BOOST_TEST_EQ(fmt::format("{:e}", T {2111u, 6, true}), "-2.111e+09"); - BOOST_TEST_EQ(fmt::format("{:E}", T {21u, 6, true}), "-2.100000E+07"); - BOOST_TEST_EQ(fmt::format("{:E}", T {211u, 6, true}), "-2.110000E+08"); - BOOST_TEST_EQ(fmt::format("{:E}", T {2111u, 6, true}), "-2.111000E+09"); + BOOST_TEST_EQ(fmt::format("{:E}", T {21u, 6, true}), "-2.1E+07"); + BOOST_TEST_EQ(fmt::format("{:E}", T {211u, 6, true}), "-2.11E+08"); + BOOST_TEST_EQ(fmt::format("{:E}", T {2111u, 6, true}), "-2.111E+09"); BOOST_TEST_EQ(fmt::format("{:.0E}", T {0}), "0E+00"); BOOST_TEST_EQ(fmt::format("{:e}", std::numeric_limits::infinity()), "inf"); @@ -197,21 +201,21 @@ void test_scientific() template void test_hex() { - BOOST_TEST_EQ(fmt::format("{:.0a}", T {0}), "0p+00"); - BOOST_TEST_EQ(fmt::format("{:.3A}", T {0}), "0.000P+00"); - BOOST_TEST_EQ(fmt::format("{:a}", std::numeric_limits::infinity()), "inf"); - BOOST_TEST_EQ(fmt::format("{:a}", -std::numeric_limits::infinity()), "-inf"); - BOOST_TEST_EQ(fmt::format("{:a}", std::numeric_limits::quiet_NaN()), "nan"); - BOOST_TEST_EQ(fmt::format("{:a}", -std::numeric_limits::quiet_NaN()), "-nan(ind)"); - BOOST_TEST_EQ(fmt::format("{:a}", std::numeric_limits::signaling_NaN()), "nan(snan)"); - BOOST_TEST_EQ(fmt::format("{:a}", -std::numeric_limits::signaling_NaN()), "-nan(snan)"); - - BOOST_TEST_EQ(fmt::format("{:A}", std::numeric_limits::infinity()), "INF"); - BOOST_TEST_EQ(fmt::format("{:A}", -std::numeric_limits::infinity()), "-INF"); - BOOST_TEST_EQ(fmt::format("{:A}", std::numeric_limits::quiet_NaN()), "NAN"); - BOOST_TEST_EQ(fmt::format("{:A}", -std::numeric_limits::quiet_NaN()), "-NAN(IND)"); - BOOST_TEST_EQ(fmt::format("{:A}", std::numeric_limits::signaling_NaN()), "NAN(SNAN)"); - BOOST_TEST_EQ(fmt::format("{:A}", -std::numeric_limits::signaling_NaN()), "-NAN(SNAN)"); + BOOST_TEST_EQ(fmt::format("{:.0x}", T {0}), "0p+00"); + BOOST_TEST_EQ(fmt::format("{:.3X}", T {0}), "0.000P+00"); + BOOST_TEST_EQ(fmt::format("{:x}", std::numeric_limits::infinity()), "inf"); + BOOST_TEST_EQ(fmt::format("{:x}", -std::numeric_limits::infinity()), "-inf"); + BOOST_TEST_EQ(fmt::format("{:x}", std::numeric_limits::quiet_NaN()), "nan"); + BOOST_TEST_EQ(fmt::format("{:x}", -std::numeric_limits::quiet_NaN()), "-nan(ind)"); + BOOST_TEST_EQ(fmt::format("{:x}", std::numeric_limits::signaling_NaN()), "nan(snan)"); + BOOST_TEST_EQ(fmt::format("{:x}", -std::numeric_limits::signaling_NaN()), "-nan(snan)"); + + BOOST_TEST_EQ(fmt::format("{:X}", std::numeric_limits::infinity()), "INF"); + BOOST_TEST_EQ(fmt::format("{:X}", -std::numeric_limits::infinity()), "-INF"); + BOOST_TEST_EQ(fmt::format("{:X}", std::numeric_limits::quiet_NaN()), "NAN"); + BOOST_TEST_EQ(fmt::format("{:X}", -std::numeric_limits::quiet_NaN()), "-NAN(IND)"); + BOOST_TEST_EQ(fmt::format("{:X}", std::numeric_limits::signaling_NaN()), "NAN(SNAN)"); + BOOST_TEST_EQ(fmt::format("{:X}", -std::numeric_limits::signaling_NaN()), "-NAN(SNAN)"); } template @@ -221,6 +225,115 @@ void test_with_string() BOOST_TEST_EQ(fmt::format("Height is: {} meters", T {2}), "Height is: 2 meters"); } +template +void test_cohort_preservation() +{ + const std::array decimals = { + T {5, 4}, + T {50, 3}, + T {500, 2}, + T {5000, 1}, + T {50000, 0}, + T {500000, -1}, + T {5000000, -2}, + }; + + const std::array result_strings = { + "5e+04", + "5.0e+04", + "5.00e+04", + "5.000e+04", + "5.0000e+04", + "5.00000e+04", + "5.000000e+04", + }; + + for (std::size_t i {}; i < decimals.size(); ++i) + { + BOOST_TEST_CSTR_EQ(fmt::format("{:a}", decimals[i]).c_str(), result_strings[i]); + + #ifdef _MSC_VER + # pragma warning(push) + # pragma warning(disable : 4244) + #endif + + std::string s {result_strings[i]}; + std::transform(s.begin(), s.end(), s.begin(), + [](unsigned char c) + { return std::toupper(c); }); + + #ifdef _MSC_VER + # pragma warning(pop) + #endif + + BOOST_TEST_CSTR_EQ(fmt::format("{:A}", decimals[i]).c_str(), s.c_str()); + } +} + +template +void test_locale_conversion(const char* locale, const std::string& result) +{ + try + { + const std::locale a(locale); + std::locale::global(a); + + const T value {112289, -2}; + BOOST_TEST_EQ(fmt::format("{:.2fL}", value), result); + } + // LCOV_EXCL_START + catch (...) + { + std::cerr << "Test not run" << std::endl; + } + // LCOV_EXCL_STOP +} + +template +void test_wide_strings() +{ + #ifndef BOOST_DECIMAL_NO_CXX17_IF_CONSTEXPR + + BOOST_TEST(fmt::format(L"{}", T{1}) == L"1"); + BOOST_TEST(fmt::format(L"{}", T{10}) == L"10"); + BOOST_TEST(fmt::format(L"{}", T{100}) == L"100"); + BOOST_TEST(fmt::format(L"{}", T{1000}) == L"1000"); + BOOST_TEST(fmt::format(L"{}", T{10000}) == L"10000"); + BOOST_TEST(fmt::format(L"{}", T{210000}) == L"210000"); + BOOST_TEST(fmt::format(L"{}", T{2100000}) == L"2100000"); + + BOOST_TEST(fmt::format(u"{}", T{1}) == u"1"); + BOOST_TEST(fmt::format(u"{}", T{10}) == u"10"); + BOOST_TEST(fmt::format(u"{}", T{100}) == u"100"); + BOOST_TEST(fmt::format(u"{}", T{1000}) == u"1000"); + BOOST_TEST(fmt::format(u"{}", T{10000}) == u"10000"); + BOOST_TEST(fmt::format(u"{}", T{210000}) == u"210000"); + BOOST_TEST(fmt::format(u"{}", T{2100000}) == u"2100000"); + + BOOST_TEST(fmt::format(U"{}", T{1}) == U"1"); + BOOST_TEST(fmt::format(U"{}", T{10}) == U"10"); + BOOST_TEST(fmt::format(U"{}", T{100}) == U"100"); + BOOST_TEST(fmt::format(U"{}", T{1000}) == U"1000"); + BOOST_TEST(fmt::format(U"{}", T{10000}) == U"10000"); + BOOST_TEST(fmt::format(U"{}", T{210000}) == U"210000"); + BOOST_TEST(fmt::format(U"{}", T{2100000}) == U"2100000"); + + #ifdef BOOST_DECIMAL_HAS_CHAR8_T + + BOOST_TEST(fmt::format(u8"{}", T{1}) == u8"1"); + BOOST_TEST(fmt::format(u8"{}", T{10}) == u8"10"); + BOOST_TEST(fmt::format(u8"{}", T{100}) == u8"100"); + BOOST_TEST(fmt::format(u8"{}", T{1000}) == u8"1000"); + BOOST_TEST(fmt::format(u8"{}", T{10000}) == u8"10000"); + BOOST_TEST(fmt::format(u8"{}", T{210000}) == u8"210000"); + BOOST_TEST(fmt::format(u8"{}", T{2100000}) == u8"2100000"); + + + #endif // BOOST_DECIMAL_HAS_CHAR8_T + + #endif +} + #ifdef _MSC_VER #pragma warning(pop) #endif @@ -262,6 +375,28 @@ int main() test_with_string(); test_with_string(); + test_cohort_preservation(); + test_cohort_preservation(); + test_cohort_preservation(); + + #if !(defined(__GNUC__) && __GNUC__ >= 5 && defined(__APPLE__)) && !defined(BOOST_DECIMAL_QEMU_TEST) && !defined(BOOST_DECIMAL_DISABLE_EXCEPTIONS) && !defined(_MSC_VER) + + test_locale_conversion("en_US.UTF-8", "1,122.89"); + test_locale_conversion("de_DE.UTF-8", "1.122,89"); + + #if (defined(__clang__) && __clang_major__ > 9) || (defined(__GNUC__) && __GNUC__ > 9) + test_locale_conversion("fr_FR.UTF-8", "1 122,89"); + #endif + + #endif + + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + test_wide_strings(); + return boost::report_errors(); } diff --git a/test/test_frexp_ldexp.cpp b/test/test_frexp_ldexp.cpp index f9637f985..3144415d7 100644 --- a/test/test_frexp_ldexp.cpp +++ b/test/test_frexp_ldexp.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -144,9 +145,9 @@ namespace local auto test_frexp_ldexp() -> bool { #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto test_frexp_ldexp_depth = static_cast(UINT32_C(0x800)); + constexpr auto test_frexp_ldexp_depth = UINT32_C(0x800); #else - constexpr auto test_frexp_ldexp_depth = static_cast(UINT32_C(0x80)); + constexpr auto test_frexp_ldexp_depth = UINT32_C(0x80); #endif const local::test_frexp_ldexp_ctrl flt_ctrl[static_cast(UINT8_C(7))] = @@ -175,7 +176,7 @@ namespace local } template - auto test_frexp_ldexp_exact_impl(long double f_in, long double fr_ctrl, int nr_ctrl) -> bool + auto test_frexp_ldexp_exact_impl(double f_in, double fr_ctrl, int nr_ctrl) -> bool { using decimal_type = boost::decimal::decimal32_t; @@ -210,9 +211,9 @@ namespace local // 7.625L, 0.953125L, 3 auto result_frexp_ldexp_exact_is_ok = true; - result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(+7.625L, +0.953125L, 3) && result_frexp_ldexp_exact_is_ok); - result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(+0.125L, +0.5L, -2) && result_frexp_ldexp_exact_is_ok); - result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(-0.125L, -0.5L, -2) && result_frexp_ldexp_exact_is_ok); + result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(+7.625, +0.953125, 3) && result_frexp_ldexp_exact_is_ok); + result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(+0.125, +0.5, -2) && result_frexp_ldexp_exact_is_ok); + result_frexp_ldexp_exact_is_ok = (test_frexp_ldexp_exact_impl(-0.125, -0.5, -2) && result_frexp_ldexp_exact_is_ok); return result_frexp_ldexp_exact_is_ok; } @@ -262,10 +263,10 @@ namespace local auto result_is_ok = true; { - auto ldexp_dec = ldexp(static_cast(0.0L), 0); + auto ldexp_dec = ldexp(static_cast(0.0), 0); auto result_zero_is_ok = (ldexp_dec == 0); - ldexp_dec = ldexp(static_cast(0.0L), 3); + ldexp_dec = ldexp(static_cast(0.0), 3); result_zero_is_ok = ((ldexp_dec == 0) && result_zero_is_ok); result_is_ok = (result_zero_is_ok && result_is_ok); diff --git a/test/test_from_chars.cpp b/test/test_from_chars.cpp index 82fa694ac..48e8b75f3 100644 --- a/test/test_from_chars.cpp +++ b/test/test_from_chars.cpp @@ -2,9 +2,11 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// Needed for operations with boost math +#define BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS + #include "mini_to_chars.hpp" #include -#include #if defined(__clang__) # pragma clang diagnostic push @@ -23,8 +25,10 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif +#include #include #include #include @@ -38,9 +42,9 @@ using namespace boost::decimal; static std::mt19937_64 rng(42); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif #if !defined(BOOST_DECIMAL_DISABLE_CLIB) @@ -177,7 +181,7 @@ void test_non_finite_values() const char* inf_str = "inf"; val = 0; r = from_chars(inf_str, inf_str + std::strlen(inf_str), val); - BOOST_TEST(r.ec == std::errc::result_out_of_range); + BOOST_TEST(r); BOOST_TEST(isinf(val)); } diff --git a/test/test_from_chars_nan_payloads.cpp b/test/test_from_chars_nan_payloads.cpp new file mode 100644 index 000000000..a18fde675 --- /dev/null +++ b/test/test_from_chars_nan_payloads.cpp @@ -0,0 +1,81 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +using namespace boost::decimal; + +template +void test_signaling() +{ + const std::array lhs_values { "NAN(SNAN)", "SNAN", "SNAN(42)", "SNAN42", "+sNaN400JUNK", "NAN(SNAN42)" }; + const std::array rhs_values { "nan(snan)", "snan", "snan(43)", "snan43", "+SnAn410JUNK", "nan(snan4000)" }; + + for (std::size_t i {}; i < lhs_values.size(); ++i) + { + const T lhs {lhs_values[i]}; + const T rhs {rhs_values[i]}; + + BOOST_TEST(isnan(lhs)); + BOOST_TEST(isnan(rhs)); + + BOOST_TEST(issignaling(lhs)); + BOOST_TEST(issignaling(rhs)); + + if (i >= 2) + { + // A nan with a higher payload compares higher + BOOST_TEST(comparetotal(lhs, rhs)); + } + } +} + +template +void test_quiet() +{ + const std::array lhs_values { "nan(IND)", "NAN", "NAN(42)", "NAN42", "NaN400JUNK", "-nan(IND4200)" }; + const std::array rhs_values { "nan(ind)", "nan", "nan(43)", "nan43", "nAn410junk", "-nan(ind4000)" }; + + for (std::size_t i {}; i < lhs_values.size(); ++i) + { + const T lhs {lhs_values[i]}; + const T rhs {rhs_values[i]}; + + BOOST_TEST(isnan(lhs)); + BOOST_TEST(isnan(rhs)); + + BOOST_TEST(!issignaling(lhs)); + BOOST_TEST(!issignaling(rhs)); + + if (i >= 2) + { + // A nan with a higher payload compares higher + BOOST_TEST(comparetotal(lhs, rhs)); + } + } +} + +int main() +{ + test_signaling(); + test_signaling(); + test_signaling(); + + test_signaling(); + test_signaling(); + test_signaling(); + + test_quiet(); + test_quiet(); + test_quiet(); + + test_quiet(); + test_quiet(); + test_quiet(); + + return boost::report_errors(); +} diff --git a/test/test_from_string.cpp b/test/test_from_string.cpp new file mode 100644 index 000000000..8842e92f4 --- /dev/null +++ b/test/test_from_string.cpp @@ -0,0 +1,123 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +using namespace boost::decimal; + +static std::mt19937_64 rng {42}; +static constexpr std::size_t N {1024}; + +template +T recover_value(const std::string& str, std::size_t* ptr); + +template <> +decimal32_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod32(str, ptr); +} + +template <> +decimal_fast32_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod32f(str, ptr); +} + +template <> +decimal64_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod64(str, ptr); +} + +template <> +decimal_fast64_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod64f(str, ptr); +} + +template <> +decimal128_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod128(str, ptr); +} + +template <> +decimal_fast128_t recover_value(const std::string& str, std::size_t* ptr) +{ + return stod128f(str, ptr); +} + +template +void test() +{ + std::uniform_int_distribution sig_dist {-9'999'999, 9'999'999}; + std::uniform_int_distribution exp_dist {-50, 50}; + + for (std::size_t i {}; i < N; ++i) + { + const T val {sig_dist(rng), exp_dist(rng)}; + + char buffer[64]; + const auto r {to_chars(buffer, buffer + sizeof(buffer), val)}; + BOOST_TEST(r); + const auto dist {static_cast(r.ptr - buffer)}; + + *r.ptr = '\0'; + const std::string str {buffer}; + std::size_t idx {}; + const T return_value {recover_value(str, &idx)}; + + BOOST_TEST_EQ(return_value, val); + BOOST_TEST_EQ(idx, dist); + } +} + +inline void test_overflow_path() +{ + const std::string str {"INF"}; + + #ifndef BOOST_DECIMAL_DISABLE_EXCEPTIONS + + BOOST_TEST_THROWS(recover_value(str, nullptr), std::out_of_range); + + #else + + BOOST_TEST(isnan(recover_value(str, nullptr))); + + #endif +} + +inline void test_invalid_path() +{ + const std::string str {"JUNK"}; + + #ifndef BOOST_DECIMAL_DISABLE_EXCEPTIONS + + BOOST_TEST_THROWS(recover_value(str, nullptr), std::invalid_argument); + + #else + + BOOST_TEST(isnan(recover_value(str, nullptr))); + + #endif +} + +int main() +{ + test(); + test(); + test(); + test(); + test(); + test(); + + test_overflow_path(); + test_invalid_path(); + + return boost::report_errors(); +} + diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 539716896..f1272b775 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -14,6 +14,7 @@ #include #include #include +#include template void test_hash() @@ -26,6 +27,31 @@ void test_hash() } } +// See: https://github.com/cppalliance/decimal/issues/1120 +template +void test_hash_cohorts() +{ + const std::array values { + T {3, 7}, + T {30, 6}, + T {300, 5}, + T {3000, 4}, + T {30000, 3}, + T {300000, 2}, + T {3000000, 1} + }; + + std::hash hasher; + + for (const auto val1 : values) + { + for (const auto val2 : values) + { + BOOST_TEST_EQ(hasher(val1), hasher(val2)); + } + } +} + int main() { test_hash(); @@ -35,5 +61,12 @@ int main() test_hash(); test_hash(); + test_hash_cohorts(); + test_hash_cohorts(); + test_hash_cohorts(); + test_hash_cohorts(); + test_hash_cohorts(); + test_hash_cohorts(); + return boost::report_errors(); } diff --git a/test/test_hermite.cpp b/test/test_hermite.cpp index dd15dc9de..eac92a027 100644 --- a/test/test_hermite.cpp +++ b/test/test_hermite.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_implicit_integral_conversion.cpp b/test/test_implicit_integral_conversion.cpp index cbf055337..b124c7b30 100644 --- a/test/test_implicit_integral_conversion.cpp +++ b/test/test_implicit_integral_conversion.cpp @@ -2,6 +2,9 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +// Needed for operations with boost math +#define BOOST_DECIMAL_ALLOW_IMPLICIT_INTEGER_CONVERSIONS + #include #include #include diff --git a/test/test_laguerre.cpp b/test/test_laguerre.cpp index 7d114454e..3d70f1143 100644 --- a/test/test_laguerre.cpp +++ b/test/test_laguerre.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_legendre.cpp b/test/test_legendre.cpp index afc3faffb..b8e3d9279 100644 --- a/test/test_legendre.cpp +++ b/test/test_legendre.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_lgamma.cpp b/test/test_lgamma.cpp index acedf41c6..a00da2e3b 100644 --- a/test/test_lgamma.cpp +++ b/test/test_lgamma.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -116,7 +117,7 @@ namespace local } template - auto test_lgamma(const int tol_factor, const long double range_lo, const long double range_hi) -> bool + auto test_lgamma(const int tol_factor, const double range_lo, const double range_hi) -> bool { using decimal_type = DecimalType; using float_type = FloatType; @@ -138,9 +139,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x200)) : static_cast(UINT32_C(0x20)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x200) : UINT32_C(0x20); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x20)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x20) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -174,6 +175,8 @@ namespace local return result_is_ok; } + #if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) + auto test_lgamma_neg32(const int tol_factor) -> bool { // Table[N[Log[Gamma[-23/100 - n]], 32], {n, 1, 12, 1}] @@ -184,18 +187,18 @@ namespace local constexpr auto ctrl_values = ctrl_as_long_double_array_type { - static_cast(+1.4447269693351526224039790879560L), - static_cast(+0.64272538386312523180385678760158L), - static_cast(-0.52975675337143994041872235279067L), - static_cast(-1.9719587464296265419941805870392L), - static_cast(-3.6263700245064580747683408545835L), - static_cast(-5.4557463573058198501555262293278L), - static_cast(-7.4339853934764931689811998755925L), - static_cast(-9.5417714081654716128550899316691L), - static_cast(-11.764230456680232402202048996379L), - static_cast(-14.089555036643767515552419226440L), - static_cast(-16.508143805394119328051805784031L), - static_cast(-19.012035755093200315277355952189L), + +1.4447269693351526224039790879560L, + +0.64272538386312523180385678760158L, + -0.52975675337143994041872235279067L, + -1.9719587464296265419941805870392L, + -3.6263700245064580747683408545835L, + -5.4557463573058198501555262293278L, + -7.4339853934764931689811998755925L, + -9.5417714081654716128550899316691L, + -11.764230456680232402202048996379L, + -14.089555036643767515552419226440L, + -16.508143805394119328051805784031L, + -19.012035755093200315277355952189L, }; auto result_is_ok = true; @@ -207,7 +210,7 @@ namespace local n < std::tuple_size::value; ++n) { - const auto ld_arg = static_cast(-0.23L - static_cast(n + 1U)); + const auto ld_arg = -0.23L - static_cast(n + 1U); const auto x_dec = static_cast(ld_arg); const auto x_flt = static_cast(ld_arg); @@ -236,6 +239,8 @@ namespace local return result_is_ok; } + #endif + template auto test_lgamma_edge() -> bool { @@ -320,7 +325,7 @@ namespace local for(auto i = static_cast(UINT8_C(0)); i < static_cast(UINT8_C(6)); ++i) { - const auto n_neg = static_cast(-static_cast(i) - 1); + const auto n_neg = -static_cast(i) - 1; const auto val_neg_int = lgamma( decimal_type { n_neg, 0 } ); @@ -448,7 +453,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 0.01L, 0.9L); + const auto result_lgamma_is_ok = local::test_lgamma(512, 0.01, 0.9); BOOST_TEST(result_lgamma_is_ok); @@ -459,7 +464,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 1.1L, 1.9L); + const auto result_lgamma_is_ok = local::test_lgamma(512, 1.1, 1.9); BOOST_TEST(result_lgamma_is_ok); @@ -470,7 +475,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_lgamma_is_ok = local::test_lgamma(512, 2.1L, 123.4L); + const auto result_lgamma_is_ok = local::test_lgamma(512, 2.1, 123.4); BOOST_TEST(result_lgamma_is_ok); @@ -481,7 +486,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 0.01L, 0.9L); + const auto result_lgamma_is_ok = local::test_lgamma(4096, 0.01, 0.9); BOOST_TEST(result_lgamma_is_ok); @@ -492,7 +497,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 1.1L, 1.9L); + const auto result_lgamma_is_ok = local::test_lgamma(4096, 1.1, 1.9); BOOST_TEST(result_lgamma_is_ok); @@ -503,13 +508,14 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_lgamma_is_ok = local::test_lgamma(4096, 2.1L, 123.4L); + const auto result_lgamma_is_ok = local::test_lgamma(4096, 2.1, 123.4); BOOST_TEST(result_lgamma_is_ok); result_is_ok = (result_lgamma_is_ok && result_is_ok); } + #if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) { const auto result_neg32_is_ok = local::test_lgamma_neg32(2048); @@ -517,6 +523,7 @@ auto main() -> int result_is_ok = (result_neg32_is_ok && result_is_ok); } + #endif { using decimal_type = boost::decimal::decimal32_t; @@ -530,11 +537,13 @@ auto main() -> int } { + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE const auto result_lgamma128_is_ok = local::test_lgamma_128(4096); BOOST_TEST(result_lgamma128_is_ok); result_is_ok = (result_lgamma128_is_ok && result_is_ok); + #endif } result_is_ok = ((boost::report_errors() == 0) && result_is_ok); diff --git a/test/test_literals.cpp b/test/test_literals.cpp index 15f5ca22a..1ad2a836b 100644 --- a/test/test_literals.cpp +++ b/test/test_literals.cpp @@ -120,6 +120,30 @@ void test_decimal_fast128_t_literals() BOOST_TEST_EQ(decimal_fast128_t(3, 1), 3e1_dlf); } +// https://github.com/cppalliance/decimal/issues/1058 +void construct_negative_infinity() +{ + using namespace boost::decimal::literals; + BOOST_TEST_EQ("-inf"_DF, -"inf"_DF); + BOOST_TEST_EQ("-inf"_DD, -"inf"_DD); + BOOST_TEST_EQ("-inf"_DL, -"inf"_DL); + BOOST_TEST_EQ("-inf"_DFF, -"inf"_DFF); + BOOST_TEST_EQ("-inf"_DDF, -"inf"_DDF); + BOOST_TEST_EQ("-inf"_DLF, -"inf"_DLF); +} + +void test_issue_1119() +{ + using namespace boost::decimal::literals; + + const auto val = 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_DD; + BOOST_TEST_EQ(val, decimal64_t(1, 198)); + + const auto overflow_val = 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_df; + BOOST_TEST(isinf(overflow_val)); + BOOST_TEST(!signbit(overflow_val)); +} + int main() { test_decimal32_t_literals(); @@ -130,5 +154,9 @@ int main() test_decimal_fast64_t_literals(); test_decimal_fast128_t_literals(); + construct_negative_infinity(); + + test_issue_1119(); + return boost::report_errors(); } diff --git a/test/test_log.cpp b/test/test_log.cpp index fecb47ba9..3c523dbb2 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -113,9 +114,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x200)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x200) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) diff --git a/test/test_log10.cpp b/test/test_log10.cpp index d8312606e..56cedb21e 100644 --- a/test/test_log10.cpp +++ b/test/test_log10.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #if defined(__clang__) @@ -107,9 +108,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x200)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x200) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -119,8 +120,8 @@ namespace local auto dis_n = std::uniform_int_distribution { - static_cast(INT8_C(-17)), - static_cast(INT8_C(17)) + -17, + 17 }; std::string str_e { "1.0E" + std::to_string(dis_n(gen)) }; @@ -167,7 +168,7 @@ namespace local bool result_is_ok { true }; - for(int i = static_cast(INT8_C(-23)); i <= static_cast(INT8_C(23)); ++i) + for(int i = INT8_C(-23); i <= INT8_C(23); ++i) { const decimal_type x_arg { 1, i }; diff --git a/test/test_log1p.cpp b/test/test_log1p.cpp index 830bca5b4..5fe31d93f 100644 --- a/test/test_log1p.cpp +++ b/test/test_log1p.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -105,9 +106,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) diff --git a/test/test_nan_conversions.cpp b/test/test_nan_conversions.cpp new file mode 100644 index 000000000..e260e7d8e --- /dev/null +++ b/test/test_nan_conversions.cpp @@ -0,0 +1,311 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: IEEE 754-2008 Section 7.2 + +#include +#include +#include +#include +#include + +enum class ops +{ + add, + sub, + mul, + div +}; + +static std::mt19937_64 rng{42}; +static std::uniform_int_distribution dist{5, 100}; + +using namespace boost::decimal; + +template +void test(const T lhs, const T rhs, Func op, U payload) +{ + BOOST_TEST(isnan(lhs) || isnan(rhs)); + BOOST_TEST(issignaling(lhs) || issignaling(rhs)); + + const auto res {op(lhs, rhs)}; + + BOOST_TEST(isnan(res)); + BOOST_TEST(!issignaling(res)); + + if (payload > 0U) + { + const auto result_payload {read_payload(res)}; + BOOST_TEST_EQ(result_payload, payload); + } +} + +template +void test_qnan_preservation(const T lhs, const T rhs, Func op, U payload) +{ + BOOST_TEST(isnan(lhs) || isnan(rhs)); + + const auto res {op(lhs, rhs)}; + + BOOST_TEST(isnan(res)); + BOOST_TEST(!issignaling(res)); + + if (payload > 0U) + { + const auto result_payload {read_payload(res)}; + BOOST_TEST_EQ(result_payload, payload); + } +} + +template , bool> = true> +bool test_signaling(const T x) +{ + return issignaling(x); +} + +template , bool> = true> +bool test_signaling(const T) +{ + return false; +} + +template , bool> = true> +bool test_nan(const T x) +{ + return issignaling(x); +} + +template , bool> = true> +bool test_nan(const T) +{ + return false; +} + +template +void test_mixed_arithmetic(const T1 lhs, const T2 rhs, const ops op, U payload) +{ + using decimal_type = std::conditional_t, T1, T2>; + static_assert(detail::is_decimal_floating_point_v, ""); + + BOOST_TEST(test_signaling(lhs) || test_signaling(rhs)); + BOOST_TEST(test_nan(lhs) || test_nan(rhs)); + + decimal_type res; + + switch (op) + { + case ops::add: + res = lhs + rhs; + break; + case ops::sub: + res = lhs - rhs; + break; + case ops::mul: + res = lhs * rhs; + break; + case ops::div: + res = lhs / rhs; + break; + } + + BOOST_TEST(isnan(res)); + if (!BOOST_TEST(!issignaling(res))) + { + // LCOV_EXCL_START + switch (op) + { + case ops::add: + std::cerr << "add\n"; + std::cerr << "Lhs: " << lhs << "\n"; + std::cerr << "Rhs: " << rhs << "\n"; + break; + case ops::sub: + std::cerr << "sub\n"; + std::cerr << "Lhs: " << lhs << "\n"; + std::cerr << "Rhs: " << rhs << "\n"; + break; + case ops::mul: + std::cerr << "mul\n"; + std::cerr << "Lhs: " << lhs << "\n"; + std::cerr << "Rhs: " << rhs << "\n"; + break; + case ops::div: + std::cerr << "div\n"; + std::cerr << "Lhs: " << lhs << "\n"; + std::cerr << "Rhs: " << rhs << "\n"; + break; + } + // LCOV_EXCL_STOP + } + + if (payload > 0U) + { + const auto result_payload {read_payload(res)}; + BOOST_TEST_EQ(result_payload, payload); + } +} + +template +void generate_tests() +{ + constexpr std::size_t N {5}; + + const std::array payloads {0, 0, 1, 2, 3}; + const std::array nans {"sNaN", "SNAN", "snan1", "SnAn2", "SNAN3"}; + + for (std::size_t i = 0; i < N; ++i) + { + const T value1 {nans[i]}; + const T value2 {dist(rng)}; + const auto current_payload {payloads[i]}; + + test(value1, value2, std::plus<>(), current_payload); + test(value1, value2, std::minus<>(), current_payload); + test(value1, value2, std::multiplies<>(), current_payload); + test(value1, value2, std::divides<>(), current_payload); + test(value1, value2, std::modulus<>(), current_payload); + + test(value2, value1, std::plus<>(), current_payload); + test(value2, value1, std::minus<>(), current_payload); + test(value2, value1, std::multiplies<>(), current_payload); + test(value2, value1, std::divides<>(), current_payload); + test(value2, value1, std::modulus<>(), current_payload); + } +} + +template +void generate_qnan_tests() +{ + constexpr std::size_t N {5}; + + const std::array payloads {0, 0, 1, 2, 3}; + const std::array nans {"NaN", "NAN", "nan1", "nAn2", "NAN(3)"}; + + for (std::size_t i = 0; i < N; ++i) + { + const T value1 {nans[i]}; + const T value2 {dist(rng)}; + const auto current_payload {payloads[i]}; + + test_qnan_preservation(value1, value2, std::plus<>(), current_payload); + test_qnan_preservation(value1, value2, std::minus<>(), current_payload); + test_qnan_preservation(value1, value2, std::multiplies<>(), current_payload); + test_qnan_preservation(value1, value2, std::divides<>(), current_payload); + test_qnan_preservation(value1, value2, std::modulus<>(), current_payload); + + test_qnan_preservation(value2, value1, std::plus<>(), current_payload); + test_qnan_preservation(value2, value1, std::minus<>(), current_payload); + test_qnan_preservation(value2, value1, std::multiplies<>(), current_payload); + test_qnan_preservation(value2, value1, std::divides<>(), current_payload); + test_qnan_preservation(value2, value1, std::modulus<>(), current_payload); + } +} + +template +void generate_mixed_tests() +{ + constexpr std::size_t N {5}; + + const std::array payloads {0, 0, 1, 2, 3}; + const std::array nans {"sNaN", "SNAN", "snan1", "SnAn2", "SNAN3"}; + + for (std::size_t i = 0; i < N; ++i) + { + const T value1 {nans[i]}; + const auto value2 {dist(rng)}; + const auto current_payload {payloads[i]}; + + test_mixed_arithmetic(value1, value2, ops::add, current_payload); + test_mixed_arithmetic(value1, value2, ops::sub, current_payload); + test_mixed_arithmetic(value1, value2, ops::mul, current_payload); + test_mixed_arithmetic(value1, value2, ops::div, current_payload); + + test_mixed_arithmetic(value2, value1, ops::add, current_payload); + test_mixed_arithmetic(value2, value1, ops::sub, current_payload); + test_mixed_arithmetic(value2, value1, ops::mul, current_payload); + test_mixed_arithmetic(value2, value1, ops::div, current_payload); + } +} + +// See: Github issue 1254 +template +void generate_two_nan_tests() +{ + constexpr std::size_t N {5}; + + const std::array payloads {0, 0, 1, 2, 3}; + const std::array snans {"sNaN", "SNAN", "snan1", "SnAn2", "SNAN3"}; + const std::array qnans {"NAN", "NAN12", "nan3", "Nan5", "NAN4"}; + + for (std::size_t i = 0; i < N; ++i) + { + const T value1 {snans[i]}; + const T value2 {qnans[i]}; + const auto current_payload {payloads[i]}; + + test(value1, value2, std::plus<>(), current_payload); + test(value1, value2, std::minus<>(), current_payload); + test(value1, value2, std::multiplies<>(), current_payload); + test(value1, value2, std::divides<>(), current_payload); + test(value1, value2, std::modulus<>(), current_payload); + + test(value2, value1, std::plus<>(), current_payload); + test(value2, value1, std::minus<>(), current_payload); + test(value2, value1, std::multiplies<>(), current_payload); + test(value2, value1, std::divides<>(), current_payload); + test(value2, value1, std::modulus<>(), current_payload); + } + + const std::array second_snans {"snan5", "snan6", "snan7", "snan8", "snan9"}; + + for (std::size_t i = 0; i < N; ++i) + { + const T value1 {snans[i]}; + const T value2 {second_snans[i]}; + const auto current_payload {payloads[i]}; + + test(value1, value2, std::plus<>(), current_payload); + test(value1, value2, std::minus<>(), current_payload); + test(value1, value2, std::multiplies<>(), current_payload); + test(value1, value2, std::divides<>(), current_payload); + test(value1, value2, std::modulus<>(), current_payload); + } +} + +int main() +{ + generate_tests(); + generate_tests(); + generate_tests(); + + generate_tests(); + generate_tests(); + generate_tests(); + + generate_qnan_tests(); + generate_qnan_tests(); + generate_qnan_tests(); + + generate_qnan_tests(); + generate_qnan_tests(); + generate_qnan_tests(); + + generate_mixed_tests(); + generate_mixed_tests(); + generate_mixed_tests(); + + generate_mixed_tests(); + generate_mixed_tests(); + generate_mixed_tests(); + + generate_two_nan_tests(); + generate_two_nan_tests(); + generate_two_nan_tests(); + + generate_two_nan_tests(); + generate_two_nan_tests(); + generate_two_nan_tests(); + + return boost::report_errors(); +} diff --git a/test/test_pow.cpp b/test/test_pow.cpp index 3b45b9c77..f5d129f5e 100644 --- a/test/test_pow.cpp +++ b/test/test_pow.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -101,9 +102,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x400)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -335,7 +336,7 @@ namespace local decimal_type p10 = pow(pow(::my_ten(), n), n); - const bool result_p10_is_ok = (p10 == ctrl_values[static_cast(i)]); + const bool result_p10_is_ok = (p10 == ctrl_values[i]); result_is_ok = (result_p10_is_ok && result_is_ok); } @@ -357,7 +358,7 @@ namespace local decimal_type p10 = pow(pow(::my_ten(), -n), n); - const bool result_p10_is_ok = (p10 == ctrl_values[static_cast(i)]); + const bool result_p10_is_ok = (p10 == ctrl_values[i]); result_is_ok = (result_p10_is_ok && result_is_ok); } @@ -750,8 +751,8 @@ namespace local std::uniform_int_distribution dist_n ( - static_cast(INT8_C(2)), - static_cast(INT8_C(12)) + 2, + 12 ); using std::fpclassify; @@ -828,7 +829,7 @@ namespace local result_is_ok = (result_val_pow2_zero_is_ok && result_is_ok); } - for(auto index = static_cast(UINT8_C(2)); index <= static_cast(UINT8_C(10)); index += static_cast(UINT8_C(2))) + for(auto index = 2; index <= 10; index += 2) { const auto dec_zero_pos = pow(::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_pos = pow(static_cast(0.0L), static_cast(index)); @@ -844,7 +845,7 @@ namespace local result_is_ok = (result_val_zero_pos_is_ok && result_is_ok); } - for(auto index = static_cast(UINT8_C(2)); index <= static_cast(UINT8_C(10)); index += static_cast(UINT8_C(2))) + for(auto index = 2; index <= 10; index += 2) { const auto dec_zero_neg = pow(-::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_neg = pow(static_cast(-0.0L), static_cast(index)); @@ -860,7 +861,7 @@ namespace local result_is_ok = (result_val_zero_neg_is_ok && result_is_ok); } - for(auto index = static_cast(UINT8_C(3)); index <= static_cast(UINT8_C(11)); index += static_cast(UINT8_C(2))) + for(auto index = 3; index <= 11; index += 2) { const auto dec_zero_pos = pow(::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_pos = pow(static_cast(0.0L), static_cast(index)); @@ -876,7 +877,7 @@ namespace local result_is_ok = (result_val_zero_pos_is_ok && result_is_ok); } - for(auto index = static_cast(UINT8_C(3)); index <= static_cast(UINT8_C(11)); index += static_cast(UINT8_C(2))) + for(auto index = 3; index <= 11; index += 2) { const decimal_type arg_zero_neg = -(::my_zero() * static_cast(dist(gen))); @@ -894,7 +895,7 @@ namespace local result_is_ok = (result_val_zero_neg_is_ok && result_is_ok); } - for(auto index = static_cast(INT8_C(-11)); index <= static_cast(INT8_C(-3)); index += static_cast(INT8_C(2))) + for(auto index = -11; index <= -3; index += 2) { const auto dec_zero_pos = pow(::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_pos = pow(static_cast(0.0L), static_cast(index)); @@ -910,7 +911,7 @@ namespace local result_is_ok = (result_val_zero_pos_is_ok && result_is_ok); } - for(auto index = static_cast(INT8_C(-11)); index <= static_cast(INT8_C(-3)); index += static_cast(INT8_C(2))) + for(auto index = -11; index <= -3; index += 2) { const auto dec_zero_neg = pow(-::my_zero() * static_cast(dist(gen)), decimal_type(index)); @@ -921,7 +922,7 @@ namespace local result_is_ok = (result_val_zero_neg_is_ok && result_is_ok); } - for(auto index = static_cast(INT8_C(-10)); index <= static_cast(INT8_C(-2)); index += static_cast(INT8_C(2))) + for(auto index = -10; index <= -2; index += 2) { const auto dec_zero_pos = pow(::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_pos = pow(static_cast(0.0L), static_cast(index)); @@ -937,7 +938,7 @@ namespace local result_is_ok = (result_val_zero_pos_is_ok && result_is_ok); } - for(auto index = static_cast(INT8_C(-10)); index <= static_cast(INT8_C(-2)); index += static_cast(INT8_C(2))) + for(auto index = -10; index <= -2; index += 2) { const auto dec_zero_neg = pow(-::my_zero() * static_cast(dist(gen)), decimal_type(index)); const auto flt_zero_neg = pow(-static_cast(0.0L), static_cast(index)); @@ -1123,10 +1124,10 @@ auto main() -> int using float_type = float; const auto test_pow_edge_is_ok = local::test_pow_edge (); - const auto test_pow_n_edge_is_ok = local::test_pow_n_edge(256); - const auto test_pow_pos_is_ok = local::test_pow (256, false); - const auto test_pow_neg_is_ok = local::test_pow (256, true); - const auto test_pow_n_is_ok = local::test_pow_n (256); + const auto test_pow_n_edge_is_ok = local::test_pow_n_edge(512); + const auto test_pow_pos_is_ok = local::test_pow (512, false); + const auto test_pow_neg_is_ok = local::test_pow (512, true); + const auto test_pow_n_is_ok = local::test_pow_n (512); const auto result_test_pow_is_ok = (test_pow_pos_is_ok && test_pow_neg_is_ok && test_pow_edge_is_ok && test_pow_n_edge_is_ok && test_pow_n_is_ok); diff --git a/test/test_remainder_remquo.cpp b/test/test_remainder_remquo.cpp index 24949d99a..cd8714ef4 100644 --- a/test/test_remainder_remquo.cpp +++ b/test/test_remainder_remquo.cpp @@ -5,6 +5,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -24,6 +25,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); diff --git a/test/test_remove_trailing_zeros.cpp b/test/test_remove_trailing_zeros.cpp index 3e58a63a9..4a66a53f8 100644 --- a/test/test_remove_trailing_zeros.cpp +++ b/test/test_remove_trailing_zeros.cpp @@ -39,30 +39,11 @@ void test() void test_extended() { using namespace boost::decimal; - constexpr std::array powers_of_10 = - {{ - boost::int128::uint128_t {UINT64_C(0x5), UINT64_C(0x6BC75E2D63100000)}, - boost::int128::uint128_t {UINT64_C(0x36), UINT64_C(0x35C9ADC5DEA00000)}, - boost::int128::uint128_t {UINT64_C(0x21E), UINT64_C(0x19E0C9BAB2400000)}, - boost::int128::uint128_t {UINT64_C(0x152D), UINT64_C(0x02C7E14AF6800000)}, - boost::int128::uint128_t {UINT64_C(0x84595), UINT64_C(0x161401484A000000)}, - boost::int128::uint128_t {UINT64_C(0x52B7D2), UINT64_C(0xDCC80CD2E4000000)}, - boost::int128::uint128_t {UINT64_C(0x33B2E3C), UINT64_C(0x9FD0803CE8000000)}, - boost::int128::uint128_t {UINT64_C(0x204FCE5E), UINT64_C(0x3E25026110000000)}, - boost::int128::uint128_t {UINT64_C(0x1431E0FAE), UINT64_C(0x6D7217CAA0000000)}, - boost::int128::uint128_t {UINT64_C(0xC9F2C9CD0), UINT64_C(0x4674EDEA40000000)}, - boost::int128::uint128_t {UINT64_C(0x7E37BE2022), UINT64_C(0xC0914B2680000000)}, - boost::int128::uint128_t {UINT64_C(0x4EE2D6D415B), UINT64_C(0x85ACEF8100000000)}, - boost::int128::uint128_t {UINT64_C(0x314DC6448D93), UINT64_C(0x38C15B0A00000000)}, - boost::int128::uint128_t {UINT64_C(0x1ED09BEAD87C0), UINT64_C(0x378D8E6400000000)}, - boost::int128::uint128_t {UINT64_C(0x13426172C74D82), UINT64_C(0x2B878FE800000000)}, - boost::int128::uint128_t {UINT64_C(0xC097CE7BC90715), UINT64_C(0xB34B9F1000000000)}, - boost::int128::uint128_t {UINT64_C(0x785EE10D5DA46D9), UINT64_C(0x00F436A000000000)}, - boost::int128::uint128_t {UINT64_C(0x4B3B4CA85A86C47A), UINT64_C(0x098A224000000000)} - }}; + const auto powers_of_10 = detail::impl::BOOST_DECIMAL_DETAIL_INT128_pow10; - for (const auto& val : powers_of_10) + for (std::size_t i {}; i < 39; ++i) { + const auto val = powers_of_10[i]; const auto temp {boost::decimal::detail::remove_trailing_zeros(val)}; if (!BOOST_TEST_EQ(temp.trimmed_number, boost::int128::uint128_t(1))) { diff --git a/test/test_sin_cos.cpp b/test/test_sin_cos.cpp index e479a9abd..cfb3a1d74 100644 --- a/test/test_sin_cos.cpp +++ b/test/test_sin_cos.cpp @@ -6,6 +6,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #include @@ -26,6 +27,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif #include @@ -34,9 +36,9 @@ #include #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(128U); // Number of trials +static constexpr auto N = static_cast(128); // Number of trials #else -static constexpr auto N = static_cast(128U >> 4U); // Number of trials +static constexpr auto N = static_cast(128 >> 4U); // Number of trials #endif static std::mt19937_64 rng(42); @@ -57,7 +59,7 @@ void test_sin() auto ret_val {std::sin(val1)}; auto ret_dec {static_cast(sin(d1))}; - if (!BOOST_TEST(std::fabs(ret_val - ret_dec) < 35*std::numeric_limits::epsilon())) + if (!BOOST_TEST(std::fabs(ret_val - ret_dec) < 40*std::numeric_limits::epsilon())) { // LCOV_EXCL_START std::cerr << "Val 1: " << val1 diff --git a/test/test_sinh.cpp b/test/test_sinh.cpp index 8113f929e..74dd83fdd 100644 --- a/test/test_sinh.cpp +++ b/test/test_sinh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -102,9 +103,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) @@ -338,8 +339,8 @@ auto main() -> int { auto result_is_ok = true; - const auto result_pos_is_ok = local::test_sinh(96, false, 0.03125L, 32.0L); - const auto result_neg_is_ok = local::test_sinh(96, true, 0.03125L, 32.0L); + const auto result_pos_is_ok = local::test_sinh(128, false, 0.03125L, 32.0L); + const auto result_neg_is_ok = local::test_sinh(128, true, 0.03125L, 32.0L); const auto result_pos_narrow_is_ok = local::test_sinh(24, false, 0.125L, 8.0L); const auto result_neg_narrow_is_ok = local::test_sinh(24, true, 0.125L, 8.0L); diff --git a/test/test_snprintf.cpp b/test/test_snprintf.cpp index 645c6678d..f0aa0d3d6 100644 --- a/test/test_snprintf.cpp +++ b/test/test_snprintf.cpp @@ -45,12 +45,20 @@ void test(T value, const char* format_sprintf, chars_format fmt = chars_format:: char buffer[256]; errno = 0; - int num_bytes = boost::decimal::snprintf(buffer, sizeof(buffer), format_sprintf, value); + const int num_bytes = boost::decimal::snprintf(buffer, sizeof(buffer), format_sprintf, value); BOOST_TEST_EQ(errno, 0); - char charconv_buffer[256]; - auto r = to_chars(charconv_buffer, charconv_buffer + sizeof(charconv_buffer), value, fmt, precision); + char charconv_buffer[256] {}; + auto first = charconv_buffer; + auto format_first = format_sprintf; + + while (*format_first != '%') + { + *first++ = *format_first++; + } + + auto r = to_chars(first, charconv_buffer + sizeof(charconv_buffer), value, fmt, precision); BOOST_TEST(r); *r.ptr = '\0'; @@ -114,6 +122,9 @@ void test_bootstrap() const char* format = std::is_same::value ? "%H" : std::is_same::value ? "%D" : "%DD"; + const char* format_w_spaces = std::is_same::value ? " %H" : + std::is_same::value ? " %D" : "\t%DD"; + const char* general_format = std::is_same::value ? "%Hg" : std::is_same::value ? "%Dg" : "%DDg"; @@ -153,6 +164,7 @@ void test_bootstrap() { // General test test(T{rng()}, format); + test(T{rng()}, format_w_spaces); test(T{rng()}, general_format); test(T{rng()}, three_digit_format, chars_format::general, 3); test_uppercase(T{rng()}, general_upper_format); diff --git a/test/test_sqrt.cpp b/test/test_sqrt.cpp index f82885a0d..2847913bc 100644 --- a/test/test_sqrt.cpp +++ b/test/test_sqrt.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -91,9 +92,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x400)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -352,9 +353,9 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_small_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 1.0E-26L, 1.0E-01L); - const auto result_medium_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 0.9E-01L, 1.1E+01L); - const auto result_large_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 1.0E+01L, 1.0E+26L); + const auto result_small_is_ok = local::test_sqrt(16, 1.0E-26L, 1.0E-01L); + const auto result_medium_is_ok = local::test_sqrt(16, 0.9E-01L, 1.1E+01L); + const auto result_large_is_ok = local::test_sqrt(16, 1.0E+01L, 1.0E+26L); BOOST_TEST(result_small_is_ok); BOOST_TEST(result_medium_is_ok); @@ -375,9 +376,9 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_small_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 1.0E-76L, 1.0E-01L); - const auto result_medium_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 0.9E-01L, 1.1E+01L); - const auto result_large_is_ok = local::test_sqrt(static_cast(INT32_C(16)), 1.0E+01L, 1.0E+76L); + const auto result_small_is_ok = local::test_sqrt(16, 1.0E-76L, 1.0E-01L); + const auto result_medium_is_ok = local::test_sqrt(16, 0.9E-01L, 1.1E+01L); + const auto result_large_is_ok = local::test_sqrt(16, 1.0E+01L, 1.0E+76L); BOOST_TEST(result_small_is_ok); BOOST_TEST(result_medium_is_ok); @@ -395,7 +396,7 @@ auto main() -> int } { - const auto result_sqrt128_is_ok = local::test_sqrt_128(96); + const auto result_sqrt128_is_ok = local::test_sqrt_128(8); BOOST_TEST(result_sqrt128_is_ok); diff --git a/test/test_string_construction.cpp b/test/test_string_construction.cpp new file mode 100644 index 000000000..305865883 --- /dev/null +++ b/test/test_string_construction.cpp @@ -0,0 +1,104 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +using namespace boost::decimal; + +template +void test_trivial() +{ + const auto str = "42"; + const T str_val {str}; + const T int_val {42}; + BOOST_TEST_EQ(str_val, int_val); + BOOST_TEST_EQ(T{std::string(str)}, int_val); + + // We allow plus signs here by popular demand + const auto str2 = "+1.2e+3"; + const T str2_val {str2}; + const T int2_val {12, 2}; + BOOST_TEST_EQ(str2_val, int2_val); + BOOST_TEST_EQ(T{std::string(str2)}, int2_val); + + const auto str3 = "-1.2E003"; + const T str3_val {str3}; + BOOST_TEST_EQ(str3_val, -str2_val); + BOOST_TEST_EQ(T{std::string(str3)}, str3_val); +} + +#ifndef BOOST_DECIMAL_DISABLE_EXCEPTIONS + +template +void test_invalid() +{ + BOOST_TEST_THROWS(T("orange"), std::runtime_error); + BOOST_TEST_THROWS(T(nullptr), std::runtime_error); + BOOST_TEST_THROWS(T(""), std::runtime_error); + BOOST_TEST_THROWS(T(std::string{""}), std::runtime_error); +} + +#else + +template +void test_invalid() +{ + BOOST_TEST(isnan(T("orange"))); + BOOST_TEST(isnan(T(nullptr))); + BOOST_TEST(isnan(T(""))); + BOOST_TEST(isnan(T(std::string{""}))); +} + +#endif + +template +void test_nonfinite() +{ + const auto nan_str = "nan"; + const T nan_val {nan_str}; + BOOST_TEST(isnan(nan_val)); + BOOST_TEST(!signbit(nan_val)); + + const auto inf_str = "inf"; + const T inf_val {inf_str}; + BOOST_TEST(isinf(inf_val)); + BOOST_TEST(!signbit(inf_val)); + + const auto neg_inf_str = "-inf"; + const T neg_inf_val {neg_inf_str}; + BOOST_TEST(isinf(neg_inf_val)); + BOOST_TEST(signbit(neg_inf_val)); +} + +int main() +{ + test_trivial(); + test_nonfinite(); + + test_trivial(); + test_nonfinite(); + + test_trivial(); + test_nonfinite(); + + test_trivial(); + test_nonfinite(); + + test_trivial(); + test_nonfinite(); + + test_trivial(); + test_nonfinite(); + + test_invalid(); + test_invalid(); + test_invalid(); + test_invalid(); + test_invalid(); + test_invalid(); + + return boost::report_errors(); +} diff --git a/test/test_string_locale_conversion.cpp b/test/test_string_locale_conversion.cpp new file mode 100644 index 000000000..6c83d1a77 --- /dev/null +++ b/test/test_string_locale_conversion.cpp @@ -0,0 +1,93 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if !(defined(__GNUC__) && __GNUC__ >= 5 && defined(__APPLE__)) && !defined(BOOST_DECIMAL_QEMU_TEST) && !defined(BOOST_DECIMAL_DISABLE_EXCEPTIONS) && !defined(_MSC_VER) + +#include +#include +#include +#include +#include +#include + +using namespace boost::decimal::detail; + +void test_conversion_to_c_locale(const char* locale) +{ + try + { + const std::locale a(locale); + std::locale::global(a); + + std::stringstream out_double; + out_double.imbue(a); + out_double << 1122.89; + + char buffer[64] {}; + std::memcpy(buffer, out_double.str().c_str(), out_double.str().size()); + convert_string_to_c_locale(buffer); + + const auto res = "1122.89"; + BOOST_TEST_CSTR_EQ(buffer, res); + } + // LCOV_EXCL_START + catch (...) + { + std::cerr << "Test not run" << std::endl; + } + // LCOV_EXCL_STOP +} + +void test_conversion_from_c_locale(const char* locale, const char* res) +{ + try + { + const std::locale a(locale); + std::locale::global(a); + + const auto str = "1122.89"; + char buffer[64] {}; + std::memcpy(buffer, str, strlen(str)); + char buffer2[64] {}; + std::memcpy(buffer2, str, strlen(str)); + + convert_pointer_pair_to_local_locale(buffer2, buffer2 + sizeof(buffer2)); + BOOST_TEST_CSTR_EQ(buffer2, res); + } + // LCOV_EXCL_START + catch (...) + { + std::cerr << "Test not run" << std::endl; + } + // LCOV_EXCL_STOP +} + +int main() +{ + test_conversion_to_c_locale("en_US.UTF-8"); // . decimal, , thousands + test_conversion_to_c_locale("de_DE.UTF-8"); // , decimal, . thousands + #if (defined(__clang__) && __clang_major__ > 9) || (defined(__GNUC__) && __GNUC__ > 9) + test_conversion_to_c_locale("fr_FR.UTF-8"); // , decimal, thousands + #endif + + test_conversion_from_c_locale("en_US.UTF-8", "1,122.89"); + + #if !defined(__APPLE__) || (defined(__APPLE__) && defined(__clang__) && __clang_major__ > 15) + test_conversion_from_c_locale("de_DE.UTF-8", "1.122,89"); + test_conversion_from_c_locale("fr_FR.UTF-8", "1 122,89"); + #endif + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} + +#endif diff --git a/test/test_strtod.cpp b/test/test_strtod.cpp index c54c07cdf..37558bcc4 100644 --- a/test/test_strtod.cpp +++ b/test/test_strtod.cpp @@ -2,6 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include "mini_to_chars.hpp" #include #include @@ -35,9 +36,9 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif template diff --git a/test/test_tan.cpp b/test/test_tan.cpp index 313fa7a35..48416cf61 100644 --- a/test/test_tan.cpp +++ b/test/test_tan.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -88,9 +89,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x400)); + constexpr auto count = UINT32_C(0x400); #else - constexpr auto count = static_cast(UINT32_C(0x40)); + constexpr auto count = UINT32_C(0x40); #endif for( ; trials < count; ++trials) diff --git a/test/test_tanh.cpp b/test/test_tanh.cpp index 4c36a81e2..8f3bb9b8d 100644 --- a/test/test_tanh.cpp +++ b/test/test_tanh.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -103,9 +104,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = static_cast(UINT32_C(0x800)); + constexpr auto count = UINT32_C(0x800); #else - constexpr auto count = static_cast(UINT32_C(0x80)); + constexpr auto count = UINT32_C(0x80); #endif for( ; trials < count; ++trials) diff --git a/test/test_tgamma.cpp b/test/test_tgamma.cpp index 239fab07a..04dad2006 100644 --- a/test/test_tgamma.cpp +++ b/test/test_tgamma.cpp @@ -3,6 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include "testing_config.hpp" #include #include #include @@ -84,7 +85,7 @@ namespace local } template - auto test_tgamma(const int tol_factor, const long double range_lo, const long double range_hi) -> bool + auto test_tgamma(const int tol_factor, const double range_lo, const double range_hi) -> bool { using decimal_type = DecimalType; using float_type = FloatType; @@ -106,9 +107,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x400)) : static_cast(UINT32_C(0x40)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x400) : UINT32_C(0x40); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x40)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x40) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) @@ -142,6 +143,7 @@ namespace local return result_is_ok; } +#if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) auto test_tgamma_neg32(const int tol_factor) -> bool { // Table[N[Gamma[-23/100 - n], 32], {n, 1, 7, 1}] @@ -150,13 +152,13 @@ namespace local constexpr auto ctrl_values = ctrl_as_long_double_array_type { - static_cast(+4.2406941452013198921659716327521L), - static_cast(-1.9016565673548519695811531985435L), - static_cast(+0.58874816326775602773410315744382L), - static_cast(-0.13918396294746005383784944620421L), - static_cast(+0.026612612418252400351405247840194L), - static_cast(-0.0042716873865573676326493174703360L), - static_cast(+0.00059082813092079773618939384098700L) + +4.2406941452013198921659716327521L, + -1.9016565673548519695811531985435L, + +0.58874816326775602773410315744382L, + -0.13918396294746005383784944620421L, + +0.026612612418252400351405247840194L, + -0.0042716873865573676326493174703360L, + +0.00059082813092079773618939384098700L }; auto result_is_ok = true; @@ -168,7 +170,7 @@ namespace local n < std::tuple_size::value; ++n) { - const auto ld_arg = static_cast(-0.23L - static_cast(n + 1U)); + const auto ld_arg = -0.23L - static_cast(n + 1U); const auto x_dec = static_cast(ld_arg); const auto x_flt = static_cast(ld_arg); @@ -196,6 +198,7 @@ namespace local return result_is_ok; } +#endif auto test_tgamma_small_ui32() -> bool { @@ -571,7 +574,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 0.01L, 0.9L); + const auto result_tgamma_is_ok = local::test_tgamma(768, 0.01, 0.9); BOOST_TEST(result_tgamma_is_ok); @@ -582,7 +585,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1L, 23.4L); + const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1, 23.4); BOOST_TEST(result_tgamma_is_ok); @@ -593,7 +596,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal_fast32_t; using float_type = float; - const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1L, 23.4L); + const auto result_tgamma_is_ok = local::test_tgamma(768, 2.1, 23.4); BOOST_TEST(result_tgamma_is_ok); @@ -604,7 +607,7 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_tgamma_is_ok = local::test_tgamma(4096, 0.001L, 0.9L); + const auto result_tgamma_is_ok = local::test_tgamma(4096, 0.001, 0.9); BOOST_TEST(result_tgamma_is_ok); @@ -615,13 +618,14 @@ auto main() -> int using decimal_type = boost::decimal::decimal64_t; using float_type = double; - const auto result_tgamma_is_ok = local::test_tgamma(4096, 2.1L, 78.9L); + const auto result_tgamma_is_ok = local::test_tgamma(4096, 2.1, 78.9); BOOST_TEST(result_tgamma_is_ok); result_is_ok = (result_tgamma_is_ok && result_is_ok); } + #if !defined(BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE) { const auto result_neg32_is_ok = local::test_tgamma_neg32(768); @@ -629,6 +633,7 @@ auto main() -> int result_is_ok = (result_neg32_is_ok && result_is_ok); } + #endif { const auto result_ui32_is_ok = local::test_tgamma_small_ui32(); @@ -665,6 +670,7 @@ auto main() -> int result_is_ok = (result_tgamma64_is_ok && result_is_ok); } + #ifndef BOOST_DECIMAL_UNSUPPORTED_LONG_DOUBLE { const auto result_tgamma128_lo_is_ok = local::test_tgamma_128_lo(4096); const auto result_tgamma128_hi_is_ok = local::test_tgamma_128_hi(0x30'000); @@ -684,6 +690,7 @@ auto main() -> int result_is_ok = (result_tgamma128_lo_is_ok && result_tgamma128_hi_is_ok && result_is_ok); } + #endif result_is_ok = ((boost::report_errors() == 0) && result_is_ok); diff --git a/test/test_to_chars.cpp b/test/test_to_chars.cpp index b841f04a5..52d1c2ca5 100644 --- a/test/test_to_chars.cpp +++ b/test/test_to_chars.cpp @@ -8,6 +8,7 @@ # pragma GCC diagnostic ignored "-Warray-bounds" #endif +#include "testing_config.hpp" #include "mini_to_chars.hpp" #include #include @@ -27,9 +28,9 @@ using namespace boost::decimal; static std::mt19937_64 rng(42); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) -static constexpr auto N = static_cast(1024U); // Number of trials +static constexpr auto N = static_cast(1024); // Number of trials #else -static constexpr auto N = static_cast(1024U >> 4U); // Number of trials +static constexpr auto N = static_cast(1024 >> 4U); // Number of trials #endif // stringop overflow errors from gcc-13 and on with x86 @@ -58,7 +59,7 @@ void test_value(T val, const char* result, chars_format fmt) template void test_value(T val, const char* result) { - char buffer[boost::decimal::limits::max_chars] {}; + char buffer[formatting_limits::max_chars] {}; auto r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::general); *r.ptr = '\0'; BOOST_TEST(r); @@ -87,8 +88,8 @@ void test_non_finite_values() { test_value(std::numeric_limits::quiet_NaN() * T {dist(rng)}, "nan", format); test_value(-std::numeric_limits::quiet_NaN() * T {dist(rng)}, "-nan(ind)", format); - test_value(std::numeric_limits::signaling_NaN() * T {dist(rng)}, "nan(snan)", format); - test_value(-std::numeric_limits::signaling_NaN() * T {dist(rng)}, "-nan(snan)", format); + test_value(std::numeric_limits::signaling_NaN(), "nan(snan)", format); + test_value(-std::numeric_limits::signaling_NaN(), "-nan(snan)", format); test_value(std::numeric_limits::infinity() * T {dist(rng)}, "inf", format); test_value(-std::numeric_limits::infinity() * T {dist(rng)}, "-inf", format); } @@ -228,6 +229,13 @@ void test_fixed_format() char buffer[1]; auto to_r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::fixed); BOOST_TEST(to_r.ec == std::errc::value_too_large); + + to_r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::fixed, 10); + BOOST_TEST(to_r.ec == std::errc::value_too_large); + + const auto new_val {val * 0}; + to_r = to_chars(buffer, buffer + sizeof(buffer), new_val, chars_format::fixed, 10); + BOOST_TEST(to_r.ec == std::errc::value_too_large); } template @@ -272,10 +280,21 @@ void test_hex_format() } // Now one with bad bounds - const T val {dist(rng)}; + T val {dist(rng)}; + if (val > 0) + { + val = -val; // LCOV_EXCL_LINE (might not be hit) + } + char buffer[1]; auto to_r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::hex); BOOST_TEST(to_r.ec == std::errc::value_too_large); + + to_r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::hex, 10); + BOOST_TEST(to_r.ec == std::errc::value_too_large); + + to_r = to_chars(buffer + sizeof(buffer), buffer, val, chars_format::hex, 16); + BOOST_TEST(to_r.ec == std::errc::invalid_argument); } #ifdef BOOST_DECIMAL_HAS_STD_CHARCONV @@ -997,8 +1016,77 @@ consteval int consteval_zero_test() #endif +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) +#endif + +template +void test_formatting_limits_max() +{ + constexpr auto maximum_value {std::numeric_limits::max()}; + + char scientific_buffer [formatting_limits::scientific_format_max_chars]; + char fixed_buffer [formatting_limits::fixed_format_max_chars]; + char hex_buffer [formatting_limits::hex_format_max_chars]; + + const auto r_sci_max {to_chars(scientific_buffer, scientific_buffer + sizeof(scientific_buffer), maximum_value, chars_format::scientific)}; + BOOST_TEST(r_sci_max); + + const auto r_fixed_max {to_chars(fixed_buffer, fixed_buffer + sizeof(fixed_buffer), maximum_value, chars_format::fixed)}; + BOOST_TEST(r_fixed_max); + + const auto r_hex_max {to_chars(hex_buffer, hex_buffer + sizeof(hex_buffer), maximum_value, chars_format::hex)}; + BOOST_TEST(r_hex_max); + + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_ieee_type_v) + { + char cohort_buffer [formatting_limits::cohort_preserving_scientific_max_chars]; + const auto r_cohort_max {to_chars(cohort_buffer, cohort_buffer + sizeof(cohort_buffer), maximum_value, chars_format::cohort_preserving_scientific)}; + BOOST_TEST(r_cohort_max); + } +} + +template +void test_formatting_limits_min() +{ + constexpr auto minimum_value {std::numeric_limits::lowest()}; + + char scientific_buffer [formatting_limits::scientific_format_max_chars]; + char fixed_buffer [formatting_limits::fixed_format_max_chars]; + char hex_buffer [formatting_limits::hex_format_max_chars]; + + const auto r_sci_max {to_chars(scientific_buffer, scientific_buffer + sizeof(scientific_buffer), minimum_value, chars_format::scientific)}; + BOOST_TEST(r_sci_max); + BOOST_TEST(r_sci_max.ptr + 1 == scientific_buffer + sizeof(scientific_buffer)); // +1 for null term + + const auto r_fixed_max {to_chars(fixed_buffer, fixed_buffer + sizeof(fixed_buffer), minimum_value, chars_format::fixed)}; + BOOST_TEST(r_fixed_max); + BOOST_TEST(r_fixed_max.ptr + 2 == fixed_buffer + sizeof(fixed_buffer)); // +2 for null term and decimal point + + const auto r_hex_max {to_chars(hex_buffer, hex_buffer + sizeof(hex_buffer), minimum_value, chars_format::hex)}; + BOOST_TEST(r_hex_max); + + BOOST_DECIMAL_IF_CONSTEXPR (detail::is_ieee_type_v) + { + char cohort_buffer [formatting_limits::cohort_preserving_scientific_max_chars]; + const auto r_cohort_max {to_chars(cohort_buffer, cohort_buffer + sizeof(cohort_buffer), minimum_value, chars_format::cohort_preserving_scientific)}; + BOOST_TEST(r_cohort_max); + BOOST_TEST(r_cohort_max.ptr + 1 == cohort_buffer + sizeof(cohort_buffer)); // +1 for null term + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + int main() { + #ifdef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION + return 0; + #else + fesetround(rounding_mode::fe_dec_to_nearest_from_zero); + test_non_finite_values(); test_non_finite_values(); @@ -1161,6 +1249,21 @@ int main() static_assert(consteval_zero_test() == 0); #endif + #endif + + test_formatting_limits_max(); + test_formatting_limits_max(); + test_formatting_limits_max(); + test_formatting_limits_max(); + test_formatting_limits_max(); + test_formatting_limits_max(); + + test_formatting_limits_min(); + test_formatting_limits_min(); + test_formatting_limits_min(); + test_formatting_limits_min(); + test_formatting_limits_min(); + test_formatting_limits_min(); return boost::report_errors(); } diff --git a/test/test_to_string.cpp b/test/test_to_string.cpp index b27a21e38..79fdc3c95 100644 --- a/test/test_to_string.cpp +++ b/test/test_to_string.cpp @@ -13,19 +13,34 @@ using namespace boost::decimal; #if !defined(BOOST_DECIMAL_DISABLE_CLIB) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + template void test() { - BOOST_TEST_EQ(to_string(T{1}), "1.000000"); - BOOST_TEST_EQ(to_string(T{10}), "10.000000"); - BOOST_TEST_EQ(to_string(T{100}), "100.000000"); - BOOST_TEST_EQ(to_string(T{1000}), "1000.000000"); - BOOST_TEST_EQ(to_string(T{10000}), "10000.000000"); - BOOST_TEST_EQ(to_string(T{210000}), "210000.000000"); - BOOST_TEST_EQ(to_string(T{2100000}), "2100000.000000"); - BOOST_TEST_EQ(to_string(T{21U, 6, true}), "-21000000.000000"); - BOOST_TEST_EQ(to_string(T{211U, 6, true}), "-211000000.000000"); - BOOST_TEST_EQ(to_string(T{2111U, 6, true}), "-2111000000.000000"); + BOOST_TEST_EQ(to_string(T{1}), "1"); + BOOST_TEST_EQ(to_string(T{10}), "10"); + BOOST_TEST_EQ(to_string(T{100}), "100"); + BOOST_TEST_EQ(to_string(T{1000}), "1000"); + BOOST_TEST_EQ(to_string(T{10000}), "10000"); + BOOST_TEST_EQ(to_string(T{210000}), "210000"); + BOOST_TEST_EQ(to_string(T{2100000}), "2100000"); + + BOOST_DECIMAL_IF_CONSTEXPR (detail::decimal_val_v > 32) + { + BOOST_TEST_EQ(to_string(T{21U, 6, true}), "-21000000"); + BOOST_TEST_EQ(to_string(T{211U, 6, true}), "-211000000"); + BOOST_TEST_EQ(to_string(T{2111U, 6, true}), "-2111000000"); + } + else + { + BOOST_TEST_EQ(to_string(T{21U, 6, true}), "-2.1e+07"); + BOOST_TEST_EQ(to_string(T{211U, 6, true}), "-2.11e+08"); + BOOST_TEST_EQ(to_string(T{2111U, 6, true}), "-2.111e+09"); + } BOOST_TEST_EQ(to_string(std::numeric_limits::infinity()), "inf"); BOOST_TEST_EQ(to_string(-std::numeric_limits::infinity()), "-inf"); @@ -35,6 +50,10 @@ void test() BOOST_TEST_EQ(to_string(-std::numeric_limits::signaling_NaN()), "-nan(snan)"); } +#ifdef _MSC_VER +#pragma warning(pop) +#endif + int main() { test(); diff --git a/test/test_total_ordering.cpp b/test/test_total_ordering.cpp new file mode 100644 index 000000000..a6a3b9d93 --- /dev/null +++ b/test/test_total_ordering.cpp @@ -0,0 +1,158 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include + +using namespace boost::decimal; + +static std::mt19937_64 rng(42); +static std::uniform_int_distribution dist(INT_MIN, INT_MAX); +static std::uniform_int_distribution payload_dist(0U, 10U); +static constexpr std::size_t N {1024}; + +template +void test_unequal() +{ + for (std::size_t i {}; i < N; ++i) + { + const auto lhs_int {dist(rng)}; + const auto rhs_int {dist(rng)}; + + const T lhs {lhs_int}; + const T rhs {rhs_int}; + + if (lhs_int < rhs_int) + { + BOOST_TEST(comparetotal(lhs, rhs)); + } + else if (lhs_int > rhs_int) + { + BOOST_TEST(!comparetotal(lhs, rhs)); + } + } +} + +template +void test_part_d12() +{ + for (std::size_t i {}; i < N / 2U; ++i) + { + const auto rhs_int {dist(rng)}; + + const auto lhs {-std::numeric_limits::quiet_NaN()}; + const T rhs {rhs_int}; + + BOOST_TEST(comparetotal(lhs, rhs)); + } + + for (std::size_t i {}; i < N / 2U; ++i) + { + const auto lhs_int {dist(rng)}; + + const T lhs {lhs_int}; + const auto rhs {std::numeric_limits::quiet_NaN()}; + + BOOST_TEST(comparetotal(lhs, rhs)); + } +} + +template +void test_part_d3() +{ + // d.3.i + for (std::size_t i {}; i < N / 3; ++i) + { + const auto lhs_int {dist(rng)}; + const auto rhs_int {dist(rng)}; + + const T lhs {lhs_int * -std::numeric_limits::quiet_NaN()}; + const T rhs {rhs_int * std::numeric_limits::quiet_NaN()}; + + BOOST_TEST(comparetotal(lhs, rhs)); + BOOST_TEST(!comparetotal(rhs, lhs)); + BOOST_TEST(!comparetotal(rhs, rhs)); + } + + // d.3.ii + for (std::size_t i {}; i < N / 3; ++i) + { + const auto rhs_int {dist(rng)}; + + const T lhs {std::numeric_limits::signaling_NaN()}; + const T rhs {rhs_int * std::numeric_limits::quiet_NaN()}; + + BOOST_TEST(comparetotal(lhs, rhs)); + BOOST_TEST(!comparetotal(rhs, lhs)); + BOOST_TEST(!comparetotal(rhs, rhs)); + + const T neg_lhs {-std::numeric_limits::signaling_NaN()}; + const T neg_rhs {rhs_int * -std::numeric_limits::quiet_NaN()}; + + BOOST_TEST(!comparetotal(neg_lhs, neg_rhs)); + BOOST_TEST(comparetotal(neg_rhs, neg_lhs)); + } + + // d.3.iii + for (std::size_t i {}; i < N / 3; ++i) + { + const auto lhs_int {payload_dist(rng)}; + const auto rhs_int {payload_dist(rng)}; + + const auto lhs_int_string {std::to_string(lhs_int)}; + const auto rhs_int_string {std::to_string(rhs_int)}; + + const auto lhs {nan(lhs_int_string.c_str())}; + const auto rhs {nan(rhs_int_string.c_str())}; + + if (lhs_int < rhs_int) + { + BOOST_TEST(comparetotal(lhs, rhs)); + BOOST_TEST(!comparetotal(rhs, lhs)); + } + else if (lhs_int > rhs_int) + { + BOOST_TEST(!comparetotal(lhs, rhs)); + BOOST_TEST(comparetotal(rhs, lhs)); + } + else + { + BOOST_TEST(!comparetotal(lhs, rhs)); + BOOST_TEST(!comparetotal(rhs, lhs)); + } + } +} + +int main() +{ + test_unequal(); + test_unequal(); + test_unequal(); + + test_unequal(); + test_unequal(); + test_unequal(); + + test_part_d12(); + test_part_d12(); + test_part_d12(); + + test_part_d12(); + test_part_d12(); + test_part_d12(); + + test_part_d3(); + test_part_d3(); + test_part_d3(); + + test_part_d3(); + test_part_d3(); + test_part_d3(); + + return boost::report_errors(); +} diff --git a/test/test_upward_rounding.cpp b/test/test_upward_rounding.cpp new file mode 100644 index 000000000..000350cd7 --- /dev/null +++ b/test/test_upward_rounding.cpp @@ -0,0 +1,141 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// Use compile-time rounding mode change so the test run on all platforms + +#define BOOST_DECIMAL_FE_DEC_UPWARD + +#include +#include +#include +#include +#include + +template +void test(const char* lhs_str, const char* rhs_str, const char* result_str, Func f) +{ + const T lhs {lhs_str}; + const T rhs {rhs_str}; + const T result {result_str}; + + const T func_result {f(lhs, rhs)}; + + BOOST_TEST_EQ(func_result, result); +} + +template +void test_add(const char* lhs, const char* rhs, const char* result) +{ + std::cerr << std::setprecision(std::numeric_limits::max_digits10); + test(lhs, rhs, result, std::plus<>()); + test(rhs, lhs, result, std::plus<>()); +} + +template +void test_sub(const char* lhs, const char* rhs, const char* result) +{ + std::cerr << std::setprecision(std::numeric_limits::max_digits10); + test(lhs, rhs, result, std::minus<>()); +} + +int main() +{ + using namespace boost::decimal; + + test_add("-1e+2", "+1e-383", "-99.99999999999999"); + test_add("-1e+1", "+1e-383", "-9.999999999999999"); + test_add("-1e+0", "+1e-383", "-0.9999999999999999"); + + test_add("+1e+2", "+1e-383", "100.0000000000001"); + test_add("+1e+1", "+1e-383", "10.00000000000001"); + test_add("+1e+0", "+1e-383", "1.000000000000001"); + test_add("+1e-1", "+1e-383", "0.1000000000000001"); + + test_add("+1e+2", "0", "100.0000000000000"); + test_add("+1e+1", "0", "10.00000000000000"); + test_add("+1e+0", "0", "1.000000000000000"); + test_add("+1e-1", "0", "0.1000000000000000"); + + test_add("-1e+2", "0", "-100.0000000000000"); + test_add("-1e+1", "0", "-10.00000000000000"); + test_add("-1e+0", "0", "-1.000000000000000"); + test_add("-1e-1", "0", "-0.1000000000000000"); + + test_sub("+1e+2", "0", "100.0000000000000"); + test_sub("+1e+1", "0", "10.00000000000000"); + test_sub("+1e+0", "0", "1.000000000000000"); + test_sub("+1e-1", "0", "0.1000000000000000"); + + test_sub("-1e+2", "0", "-100.0000000000000"); + test_sub("-1e+1", "0", "-10.00000000000000"); + test_sub("-1e+0", "0", "-1.000000000000000"); + test_sub("-1e-1", "0", "-0.1000000000000000"); + + test_add("-1e+2", "+1e-383", "-99.99999999999999"); + test_add("-1e+1", "+1e-383", "-9.999999999999999"); + test_add("-1e+0", "+1e-383", "-0.9999999999999999"); + + test_add("+1e+2", "+1e-383", "100.0000000000001"); + test_add("+1e+1", "+1e-383", "10.00000000000001"); + test_add("+1e+0", "+1e-383", "1.000000000000001"); + test_add("+1e-1", "+1e-383", "0.1000000000000001"); + + test_add("+1e+2", "0", "100.0000000000000"); + test_add("+1e+1", "0", "10.00000000000000"); + test_add("+1e+0", "0", "1.000000000000000"); + test_add("+1e-1", "0", "0.1000000000000000"); + + test_add("-1e+2", "0", "-100.0000000000000"); + test_add("-1e+1", "0", "-10.00000000000000"); + test_add("-1e+0", "0", "-1.000000000000000"); + test_add("-1e-1", "0", "-0.1000000000000000"); + + test_sub("+1e+2", "0", "100.0000000000000"); + test_sub("+1e+1", "0", "10.00000000000000"); + test_sub("+1e+0", "0", "1.000000000000000"); + test_sub("+1e-1", "0", "0.1000000000000000"); + + test_sub("-1e+2", "0", "-100.0000000000000"); + test_sub("-1e+1", "0", "-10.00000000000000"); + test_sub("-1e+0", "0", "-1.000000000000000"); + test_sub("-1e-1", "0", "-0.1000000000000000"); + + test_add("-1e+2", "+1e-20", "-99.99999"); + test_add("-1e+1", "+1e-20", "-9.999999"); + test_add("-1e+0", "+1e-20", "-0.9999999"); + + test_add("+1e+2", "+1e-20", "100.0001"); + test_add("+1e+1", "+1e-20", "10.00001"); + test_add("+1e+0", "+1e-20", "1.000001"); + test_add("+1e-1", "+1e-20", "0.10000001"); + + test_add("-1e+2", "+1e-20", "-99.99999"); + test_add("-1e+1", "+1e-20", "-9.999999"); + test_add("-1e+0", "+1e-20", "-0.9999999"); + + test_add("+1e+2", "+1e-20", "100.0001"); + test_add("+1e+1", "+1e-20", "10.00001"); + test_add("+1e+0", "+1e-20", "1.000001"); + test_add("+1e-1", "+1e-20", "0.10000001"); + + test_add("-1e+2", "+1e-383", "-99.99999999999999999999999999999999"); + test_add("-1e+1", "+1e-383", "-9.999999999999999999999999999999999"); + test_add("-1e+0", "+1e-383", "-0.9999999999999999999999999999999999"); + + test_add("+1e+2", "+1e-383", "100.00000000000000000000000000000001"); + test_add("+1e+1", "+1e-383", "10.000000000000000000000000000000001"); + test_add("+1e+0", "+1e-383", "1.0000000000000000000000000000000001"); + test_add("+1e-1", "+1e-383", "0.10000000000000000000000000000000001"); + + test_add("-1e+2", "+1e-383", "-99.99999999999999999999999999999999"); + test_add("-1e+1", "+1e-383", "-9.999999999999999999999999999999999"); + test_add("-1e+0", "+1e-383", "-0.9999999999999999999999999999999999"); + + test_add("+1e+2", "+1e-383", "100.00000000000000000000000000000001"); + test_add("+1e+1", "+1e-383", "10.000000000000000000000000000000001"); + test_add("+1e+0", "+1e-383", "1.0000000000000000000000000000000001"); + test_add("+1e-1", "+1e-383", "0.10000000000000000000000000000000001"); + + return boost::report_errors(); +} diff --git a/test/test_zeta.cpp b/test/test_zeta.cpp index 12bb1e9c7..9a9c4543a 100644 --- a/test/test_zeta.cpp +++ b/test/test_zeta.cpp @@ -6,6 +6,7 @@ // Propogates up from boost.math #define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING +#include "testing_config.hpp" #include #if defined(__clang__) @@ -25,6 +26,7 @@ # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic ignored "-Wfloat-equal" +# pragma GCC diagnostic ignored "-Wuseless-cast" #endif // Windows in Github actions has a broken chrono header @@ -129,9 +131,9 @@ namespace local auto trials = static_cast(UINT8_C(0)); #if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x80)) : static_cast(UINT32_C(0x20)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x80) : UINT32_C(0x20); #else - constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? static_cast(UINT32_C(0x10)) : static_cast(UINT32_C(0x4)); + constexpr auto count = (sizeof(decimal_type) == static_cast(UINT8_C(4))) ? UINT32_C(0x10) : UINT32_C(0x4); #endif for( ; trials < count; ++trials) diff --git a/test/testing_config.hpp b/test/testing_config.hpp new file mode 100644 index 000000000..769a95744 --- /dev/null +++ b/test/testing_config.hpp @@ -0,0 +1,28 @@ +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_DECIMAL_TESTING_CONFIG_HPP +#define BOOST_DECIMAL_TESTING_CONFIG_HPP + +#if defined(__clang__) +# if defined __has_feature +# if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) +# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +# endif +# endif +#elif defined(__GNUC__) +# if defined(__SANITIZE_THREAD__) || defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) +# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +# endif +#elif defined(_MSC_VER) +# if defined(_DEBUG) || defined(__SANITIZE_ADDRESS__) +# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +# endif +#endif + +#if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH) && ((defined(UBSAN) && (UBSAN == 1))) +# define BOOST_DECIMAL_REDUCE_TEST_DEPTH +#endif + +#endif // BOOST_DECIMAL_TESTING_CONFIG_HPP