Representasi tipe floating point

Aug 24 2020

Apakah std::numeric_limits<float>::is_iec559+ std::numeric_limits<float>::digits == 24cukup untuk memastikan (1) bahwa floatbinary32 (2) di IEEE 754? Sama untuk ganda dengan ... digit == 53?

  1. Bagaimanapun juga termasuk implementasi paling aneh yang masih menghormati standar C ++.
  2. "binary32" adalah representasi spesifik dari floating point dalam standar IEEE 754, maksud saya "disimpan dalam 32 bit".

Edit: + std::numeric_limits<float>::max_exponent - 1 == 127

Edit: Apakah ada cara lain? Jika ya, mana yang "terbaik"?

Jawaban

nop666 Aug 24 2020 at 14:24

Anda dapat menggunakan kelas sifat untuk memeriksa representasi Anda sesuai dengan beberapa harapan.

Berikut adalah ciri-ciri yang digunakan untuk menguji representasi Anda:

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);
    }
}

Kemudian, Anda dapat memeriksa representasi Anda:

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");
1 MSalters Aug 24 2020 at 15:11

Jika saya memahami pertanyaan Anda dengan benar, intinya adalah "apakah ada format IEC559 / IEEE754 lain binary32yang juga memiliki mantissa 24 bit"? Jawabannya adalah Tidak.

Anda memerlukan iec559bagian karena itulah yang menghubungkan standar C ++ ke standar IEC. Tanpa itu, apapun itu. Mengetahui bahwa ini adalah IEC559, digitspengujiannya sangat mudah.

Tetapi Anda ingin memastikan bahwa "24" benar-benar dihitung dalam bit, jadi Anda juga ingin memeriksanya radix==2. Itulah biner dalam binary32. Atau, Anda dapat memeriksa apakah sizeof(float)*CHAR_BIT==32. Jika radixlebih besar dari dua, Anda tidak dapat memasukkan 24 digit dalam 32 bit.