Rappresentazione di tipi in virgola mobile
std::numeric_limits<float>::is_iec559
+ è std::numeric_limits<float>::digits == 24
sufficiente per garantire (1) che float
sia binary32(2) in IEEE 754? Lo stesso per double con ... cifre == 53 ?
- In ogni caso comprese le implementazioni più strane pur rispettando lo standard C++.
- "binary32" è una rappresentazione specifica di virgola mobile nello standard IEEE 754, non intendo "memorizzata a 32 bit".
Modifica: +std::numeric_limits<float>::max_exponent - 1 == 127
Modifica: ci sono altri modi? Se sì, qual è "il migliore"?
Risposte
Puoi usare la classe dei tratti per verificare che la tua rappresentazione corrisponda ad alcune aspettative.
Ecco i tratti utilizzati per testare la tua rappresentazione:
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);
}
}
Quindi, puoi controllare la tua rappresentazione:
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");
Se capisco correttamente la tua domanda, si riduce a "ci sono altri formati IEC559/IEEE754 oltre ai binary32
quali hanno anche una mantissa a 24 bit"? La risposta è no.
Hai bisogno della iec559
parte in quanto è ciò che collega lo standard C ++ allo standard IEC. Senza di esso, tutto va bene. Sapendo che è IEC559, il digits
test è semplice.
Ma vuoi assicurarti che il "24" sia effettivamente contato in bit, quindi dovresti controllare radix==2
anche tu. Questo è il binario in binary32
. In alternativa, puoi controllare se sizeof(float)*CHAR_BIT==32
. Se radix
è maggiore di due, non puoi inserire 24 cifre in 32 bit.