浮点类型表示
Floating point types representation
std::numeric_limits<float>::is_iec559
+ std::numeric_limits<float>::digits == 24
是否足以确保(1) float
是 IEEE 754 中的 binary32(2)? double 与 ... digits == 53 ?
相同
- 无论如何,包括最奇怪的实现仍然遵守 C++ 标准。
- “binary32”是IEEE 754标准中浮点数的具体表示,我不是说“以32位存储”。
编辑:+ std::numeric_limits<float>::max_exponent - 1 == 127
编辑:还有其他方法吗?如果是,哪一个是“最好的”?
您可以使用特征 class 来检查您的表现是否符合某些期望。
以下是用于测试您的表现的特征:
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);
}
}
然后,您可以检查您的表示:
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");
如果我对你的问题的理解正确,它可以归结为“除了 binary32
之外还有其他 IEC559/IEEE754 格式也有 24 位尾数吗”?答案是否定的。
您需要 iec559
部分,因为它连接了 C++ 标准和 IEC 标准。没有它,一切都会发生。知道它是 IEC559,digits
测试就很简单了。
但是你想确保“24”实际上是以位计算的,所以你也想检查 radix==2
。那是 binary32
中的二进制文件。或者,您可以检查是否 sizeof(float)*CHAR_BIT==32
。如果radix
大于2,则32位放不下24位。
std::numeric_limits<float>::is_iec559
+ std::numeric_limits<float>::digits == 24
是否足以确保(1) float
是 IEEE 754 中的 binary32(2)? double 与 ... digits == 53 ?
- 无论如何,包括最奇怪的实现仍然遵守 C++ 标准。
- “binary32”是IEEE 754标准中浮点数的具体表示,我不是说“以32位存储”。
编辑:+ std::numeric_limits<float>::max_exponent - 1 == 127
编辑:还有其他方法吗?如果是,哪一个是“最好的”?
您可以使用特征 class 来检查您的表现是否符合某些期望。
以下是用于测试您的表现的特征:
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);
}
}
然后,您可以检查您的表示:
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");
如果我对你的问题的理解正确,它可以归结为“除了 binary32
之外还有其他 IEC559/IEEE754 格式也有 24 位尾数吗”?答案是否定的。
您需要 iec559
部分,因为它连接了 C++ 标准和 IEC 标准。没有它,一切都会发生。知道它是 IEC559,digits
测试就很简单了。
但是你想确保“24”实际上是以位计算的,所以你也想检查 radix==2
。那是 binary32
中的二进制文件。或者,您可以检查是否 sizeof(float)*CHAR_BIT==32
。如果radix
大于2,则32位放不下24位。