浮点类型表示

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 ?

相同
  1. 无论如何,包括最奇怪的实现仍然遵守 C++ 标准。
  2. “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位。