1#ifndef SANISIZER_FLOAT_HPP
2#define SANISIZER_FLOAT_HPP
30template<
typename Float_>
32 static_assert(std::is_floating_point<Float_>::value);
34 assert(std::isfinite(x));
35 assert(std::trunc(x) == x);
37#ifndef SANISIZER_FLOAT_FORCE_FREXP
38 if constexpr(std::numeric_limits<Float_>::radix == 2) {
43 return std::ilogb(x) + 1;
52#ifndef SANISIZER_FLOAT_FORCE_FREXP
69template<
typename Integer_,
typename Float_>
71 static_assert(std::is_floating_point<Float_>::value);
72 static_assert(std::is_integral<Integer_>::value);
74 if (!std::isfinite(x)) {
75 throw std::range_error(
"invalid conversion of non-finite value in sanisizer::from_float");
78 throw std::out_of_range(
"negative input value in sanisizer::from_float");
82 constexpr auto output_precision = std::numeric_limits<Integer_>::digits;
84 throw std::overflow_error(
"overflow detected in sanisizer::from_float");
107template<
typename Float_,
typename Integer_>
112 constexpr auto xmax =
get_max<I<
decltype(x)> >();
113 if constexpr(xmax == 0) {
115 }
else if (val == 0) {
119 constexpr auto frad = std::numeric_limits<Float_>::radix;
120 constexpr auto fdig = std::numeric_limits<Float_>::digits;
124 static_assert(frad == 2);
125 static_assert(std::numeric_limits<Float_>::is_iec559);
128 if constexpr(std::numeric_limits<I<
decltype(val)> >::digits > fdig) {
131 if constexpr((xmax - 1) >> fdig) {
132 const auto y = (val - 1) >> fdig;
134 throw std::overflow_error(
"overflow detected in sanisizer::to_float");
Create compile-time attestations.
Sanitize sizes to avoid integer overflow.
Definition arithmetic.hpp:16
constexpr auto get_value(Value_ x)
Definition attest.hpp:105
Float_ to_float(Integer_ x)
Definition float.hpp:108
Integer_ from_float(Float_ x)
Definition float.hpp:70
int required_bits_for_float(Float_ x)
Definition float.hpp:31
constexpr auto get_max()
Definition attest.hpp:119