[英]Floating point types representation
Is std::numeric_limits<float>::is_iec559
+ std::numeric_limits<float>::digits == 24
enough to ensure(1) that float
is binary32(2) in IEEE 754 ? std::numeric_limits<float>::is_iec559
+ std::numeric_limits<float>::digits == 24
足以确保(1) float
是 IEEE 754 中的 binary32(2) ? Same for double with ... digits == 53 ?与 ... 数字 == 53 相同的 double ?
Edit : + std::numeric_limits<float>::max_exponent - 1 == 127
编辑:+ std::numeric_limits<float>::max_exponent - 1 == 127
Edit : Are there any other ways ?编辑:还有其他方法吗? If yes, which one is "the best" ?如果是,哪一个是“最好的”?
If I understand your question correctly, it boils down to "are there other IEC559/IEEE754 formats besides binary32
which also have a 24 bits mantissa"?如果我正确理解你的问题,它归结为“除了binary32
之外还有其他 IEC559/IEEE754 格式,它们也有 24 位尾数”? The answer to that is No.答案是否定的。
You need the iec559
part as that's what connects the C++ standard to the IEC standard.您需要iec559
部分,因为它将 C++ 标准连接到 IEC 标准。 Without it, anything goes.没有它,一切都会过去。 Knowing it's IEC559, the digits
test is straightforward.知道它是 IEC559, digits
测试很简单。
But you want to make sure that the "24" is actually counted in bits, so you would want to check radix==2
as well.但是您想确保“24”实际上是按位计算的,因此您还需要检查radix==2
。 That's the binary in binary32
.那是binary32
的二进制binary32
。 Alternatively, you can check if sizeof(float)*CHAR_BIT==32
.或者,您可以检查sizeof(float)*CHAR_BIT==32
。 If radix
is larger than two, you can't fit 24 digits in 32 bits.如果radix
大于 2,则 32 位不能容纳 24 位。
You can use traits class to check your representation matches some expectations.您可以使用特征类来检查您的表示是否符合某些期望。
Here are the traits used to test your representation:以下是用于测试您的表示的特征:
namespace num {
template <std::size_t N> struct ieee754_traits;
template <> struct ieee754_traits<4> {
using unsigned_type = uint32_t;
static constexpr std::size_t sign_size = 1;
static constexpr std::size_t exp_size = 8;
static constexpr std::size_t mant_size = 23;
static constexpr std::size_t exp_shift = 127;
static constexpr int32_t exp_mask = 0xFF;
static constexpr unsigned_type mant_mask = 0x7FFFFF;
};
template <> struct ieee754_traits<8> {
using unsigned_type = uint64_t;
static constexpr std::size_t sign_size = 1;
static constexpr std::size_t exp_size = 11;
static constexpr std::size_t mant_size = 52;
static constexpr std::size_t exp_shift = 1023;
static constexpr int32_t exp_mask = 0x7FF;
static constexpr unsigned_type mant_mask = 0xFFFFFFFFFFFFF;
};
template<typename T>
constexpr bool check_ieee754() {
// add more check here
return std::numeric_limits<T>::digits == (num::ieee754_traits<sizeof(T)>::mant_size + 1) &&
std::numeric_limits<T>::max_exponent == (num::ieee754_traits<sizeof(T)>::exp_mask - num::ieee754_traits<sizeof(T)>::exp_shift);
}
}
Then, you can check your representation:然后,您可以检查您的表示:
static_assert(sizeof(float) == 4 && sizeof(double) == 8);
static_assert(num::check_ieee754<float>(), "does not match ieee754");
static_assert(num::check_ieee754<double>(), "does not match ieee754");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.