可以存储在浮点数中的最大连续整数的定义常量?
Defined constant for max sequential integer that can be stored in a float?
C++ 标准中是否有定义的常量,用于可以存储在浮点数中而无需近似的最大连续整数?
(还有 double 和 long double?)
这是否与尾数 bits/significand 位数直接相关?
如果是这样,最大顺序整数是否正好是 (1 << mantissaBitCount) - 1
?
对于 float、double 和 long double 的尾数位数,C++ 标准中是否有定义的常量?
Is there a defined constant in the C++ standard, for the mantissa bit count for float, double, and long double?
是的。它们位于 std::numeric_limits
模板中。这些也有从 C 标准库继承的宏。
Is [max sequential integer] directly related to the number of mantissa bits/significand bits?
是的。
If so, would the max sequential integer be exactly (1 << mantissaBitCount) - 1
?
不完全是。删除 -1,对于使用基数 2(这很常见)的表示,这将是正确的。请注意,假定 mantissaBitCount
是真正有效位数中的位数,而不是内存中的位数,即在 IEEE-754 的情况下,它包括隐式前导位。
Defined constant for max sequential integer that can be stored in a float?
没有这样的常量,但可以使用提供的常量计算:
using T = float; // as an example; works with other types too (even integers)
using limits = std::numeric_limits<T>;
constexpr int digits = limits::digits;
constexpr int radix = limits::radix;
constexpr T max_conseq = std::pow(radix, T(digits));
类型 T
中第一个无法表示的整数之前的整数可以计算为:
std::numeric_limits<T>::radix / std::numeric_limits<T>::epsilon()
,或
std::scalbn(1, std::numeric_limits<T>::digits)
.
这是因为整数是 b p,其中 b 是用于浮点格式的基数,p 是精度,即有效位数中的位数。这是因为如果有效数的所有数字都处于最大值 (b−1),并且指数只是将有效数缩放为整数,则表示的值为b p−1(例如 999 表示十进制的三位数)。下一个整数 b p 也显然是可表示的,尾数为 1,指数为 p。之后的整数不是,因为在基数 b 中,它会有一个 1 后跟 p−1 0s 后跟一个 1,这不适合 p 位的有效数字。
关于第二个表达式: scalbn
函数,在 <cmath>
中声明,将其第一个操作数乘以 b 的第二个操作数的幂。 std::numeric_limits<T>::digits
就是上面描述的p,所以scalbn
表达式产生bp.
关于第一个表达式:std::numeric_limits<T>::radix
是b,std::numeric_limits<T>::epsilon()
是浮点数中最低位的位置值数字 1,所以它是 b p−1,所以除以这些会产生 b p.
这是我使用递归模板元编程编写的解决方案。
这使用了 中基于 pow
的公式,同时希望避免因 pow
.
的实施不当而导致的潜在问题
递归模板元编程是explained here。
此解决方案很有价值,因为它保证了 constexpr
结果。
//recursive template, which references itself
template <class result_T, result_T B, uint64_t E>
constexpr result_T const pow_ = B * pow_<result_T, B, E - 1>;
//"base case" template (partial specialization),
//which ends the recursion so it doesn't loop forever
template <class result_T, result_T B>
constexpr result_T const pow_<result_T, B, 0> = static_cast<result_T>(1);
//friendly constants for max sequential integer values, for floating-point types
constexpr uint32_t const FLOAT_MAX_SEQ_INT =
pow_<uint32_t, numeric_limits<float>::radix, numeric_limits<float>::digits>;
constexpr uint64_t const DOUBLE_MAX_SEQ_INT =
pow_<uint64_t, numeric_limits<double>::radix, numeric_limits<double>::digits>;
constexpr long double const LONG_DOUBLE_MAX_SEQ_INT =
pow_<long double, numeric_limits<long double>::radix, numeric_limits<long double>::digits>;
C++ 标准中是否有定义的常量,用于可以存储在浮点数中而无需近似的最大连续整数?
(还有 double 和 long double?)
这是否与尾数 bits/significand 位数直接相关?
如果是这样,最大顺序整数是否正好是 (1 << mantissaBitCount) - 1
?
对于 float、double 和 long double 的尾数位数,C++ 标准中是否有定义的常量?
Is there a defined constant in the C++ standard, for the mantissa bit count for float, double, and long double?
是的。它们位于 std::numeric_limits
模板中。这些也有从 C 标准库继承的宏。
Is [max sequential integer] directly related to the number of mantissa bits/significand bits?
是的。
If so, would the max sequential integer be exactly
(1 << mantissaBitCount) - 1
?
不完全是。删除 -1,对于使用基数 2(这很常见)的表示,这将是正确的。请注意,假定 mantissaBitCount
是真正有效位数中的位数,而不是内存中的位数,即在 IEEE-754 的情况下,它包括隐式前导位。
Defined constant for max sequential integer that can be stored in a float?
没有这样的常量,但可以使用提供的常量计算:
using T = float; // as an example; works with other types too (even integers)
using limits = std::numeric_limits<T>;
constexpr int digits = limits::digits;
constexpr int radix = limits::radix;
constexpr T max_conseq = std::pow(radix, T(digits));
类型 T
中第一个无法表示的整数之前的整数可以计算为:
std::numeric_limits<T>::radix / std::numeric_limits<T>::epsilon()
,或std::scalbn(1, std::numeric_limits<T>::digits)
.
这是因为整数是 b p,其中 b 是用于浮点格式的基数,p 是精度,即有效位数中的位数。这是因为如果有效数的所有数字都处于最大值 (b−1),并且指数只是将有效数缩放为整数,则表示的值为b p−1(例如 999 表示十进制的三位数)。下一个整数 b p 也显然是可表示的,尾数为 1,指数为 p。之后的整数不是,因为在基数 b 中,它会有一个 1 后跟 p−1 0s 后跟一个 1,这不适合 p 位的有效数字。
关于第二个表达式: scalbn
函数,在 <cmath>
中声明,将其第一个操作数乘以 b 的第二个操作数的幂。 std::numeric_limits<T>::digits
就是上面描述的p,所以scalbn
表达式产生bp.
关于第一个表达式:std::numeric_limits<T>::radix
是b,std::numeric_limits<T>::epsilon()
是浮点数中最低位的位置值数字 1,所以它是 b p−1,所以除以这些会产生 b p.
这是我使用递归模板元编程编写的解决方案。
这使用了 pow
的公式,同时希望避免因 pow
.
递归模板元编程是explained here。
此解决方案很有价值,因为它保证了 constexpr
结果。
//recursive template, which references itself
template <class result_T, result_T B, uint64_t E>
constexpr result_T const pow_ = B * pow_<result_T, B, E - 1>;
//"base case" template (partial specialization),
//which ends the recursion so it doesn't loop forever
template <class result_T, result_T B>
constexpr result_T const pow_<result_T, B, 0> = static_cast<result_T>(1);
//friendly constants for max sequential integer values, for floating-point types
constexpr uint32_t const FLOAT_MAX_SEQ_INT =
pow_<uint32_t, numeric_limits<float>::radix, numeric_limits<float>::digits>;
constexpr uint64_t const DOUBLE_MAX_SEQ_INT =
pow_<uint64_t, numeric_limits<double>::radix, numeric_limits<double>::digits>;
constexpr long double const LONG_DOUBLE_MAX_SEQ_INT =
pow_<long double, numeric_limits<long double>::radix, numeric_limits<long double>::digits>;