Représentation des types à virgule flottante
Est- ce que std::numeric_limits<float>::is_iec559+ est std::numeric_limits<float>::digits == 24suffisant pour garantir (1) qu'il floats'agit de binary32(2) dans IEEE 754 ? Idem pour le double avec ... chiffres == 53 ?
- En tout cas y compris les implémentations les plus bizarres respectant toujours le standard C++.
- "binary32" est une représentation spécifique des virgules flottantes dans la norme IEEE 754, je ne veux pas dire "stocké en 32 bits".
Édit : +std::numeric_limits<float>::max_exponent - 1 == 127
Edit : Y a-t-il d'autres moyens ? Si oui, lequel est "le meilleur" ?
Réponses
Vous pouvez utiliser la classe de traits pour vérifier que votre représentation correspond à certaines attentes.
Voici les traits utilisés pour tester votre représentation :
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);
}
}
Ensuite, vous pouvez vérifier votre représentation :
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");
Si je comprends bien votre question, cela se résume à "y a-t-il d'autres formats IEC559/IEEE754 binary32qui ont également une mantisse 24 bits" ? La réponse à cela est Non.
Vous avez besoin de la iec559pièce car c'est ce qui relie la norme C++ à la norme CEI. Sans elle, tout est permis. Sachant que c'est IEC559, le digitstest est simple.
Mais vous voulez vous assurer que le "24" est réellement compté en bits, vous voudrez donc radix==2également vérifier. C'est le binaire dans binary32. Alternativement, vous pouvez vérifier si sizeof(float)*CHAR_BIT==32. Si radixest supérieur à deux, vous ne pouvez pas faire tenir 24 chiffres sur 32 bits.