简体   繁体   English

浮点类型表示

[英]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 ?

  1. In any case including the weirdest implementations still respecting the C++ standard.在任何情况下,包括仍然尊重 C++ 标准的最奇怪的实现。
  2. "binary32" is a specific representation of floating points in the IEEE 754 standard, I don't mean "stored in 32 bits". “binary32”是 IEEE 754 标准中浮点的特定表示,我的意思不是“以 32 位存储”。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM