From 09ffd2195f78e8ad39641e5a7bd3b731c7603ba5 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 17 Feb 2026 23:49:48 -0500 Subject: [PATCH] Add bool to_integer(Integer& out, Float value). --- include/bitcoin/system/impl/math/cast.ipp | 25 +++++++++++++++++++++++ include/bitcoin/system/math/cast.hpp | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/include/bitcoin/system/impl/math/cast.ipp b/include/bitcoin/system/impl/math/cast.ipp index 0051011eac..e627e9aac7 100644 --- a/include/bitcoin/system/impl/math/cast.ipp +++ b/include/bitcoin/system/impl/math/cast.ipp @@ -19,6 +19,7 @@ #ifndef LIBBITCOIN_SYSTEM_MATH_CAST_IPP #define LIBBITCOIN_SYSTEM_MATH_CAST_IPP +#include #include namespace libbitcoin { @@ -209,6 +210,30 @@ constexpr Unsigned to_unsigned(Unsigned value) NOEXCEPT // Floating point casts. // ---------------------------------------------------------------------------- +template , + if_floating_point> +constexpr bool to_integer(Integer& out, Float value) NOEXCEPT +{ + if (!std::isfinite(value)) + return false; + + Float integer{}; + const Float fractional = std::modf(value, &integer); + if (fractional != 0.0) + return false; + + if (integer > static_cast(std::numeric_limits::max()) || + integer < static_cast(std::numeric_limits::min())) + return false; + + // Floating point conversion in c++ requires explicit or implicit cast. + BC_PUSH_WARNING(NO_CASTS_FOR_ARITHMETIC_CONVERSION) + out = static_cast(integer); + BC_POP_WARNING() + return true; +} + template , if_floating_point> diff --git a/include/bitcoin/system/math/cast.hpp b/include/bitcoin/system/math/cast.hpp index 5b7df76219..4e44d64747 100644 --- a/include/bitcoin/system/math/cast.hpp +++ b/include/bitcoin/system/math/cast.hpp @@ -142,6 +142,12 @@ constexpr Unsigned to_unsigned(Unsigned value) NOEXCEPT; /// Floating point casts. /// --------------------------------------------------------------------------- +/// Cast floating point to integral integer, overflow guarded. +template = true, + if_floating_point = true> +constexpr bool to_integer(Integer& out, Float value) NOEXCEPT; + /// Cast floating point to integral integer, overflow unguarded. template = true,