Вот решение, которое не опирается на реализацию C ++ с использованием типов IEEE-754.
Пусть s
будет первым битом набора битов.
Пусть e
будетследующие 8 или 11 бит для 32-битной или 64-битной версии соответственно.
Пусть f
будут оставшимися 23 или 52 битами соответственно.
Пусть Ebias
будет 127 или1023 соответственно.
Пусть Emax
будет 255 или 2047 соответственно.
Пусть Fscale
будет 0x1p-23 или 0x1p-52 соответственно.
Тогда этоcode возвращает значение набора битов, интерпретируемого как базовый двоичный объект IEEE-754 с плавающей запятой:
// Interpret the sign.
double S = s ? -1 : +1;
// Classify the exponent.
if (e == 0)
// The value is zero or subnormal.
return S * std::ldexp(f*Fscale, 1-Ebias);
else if (e < eMax)
// The value is normal.
return S * std::ldexp(1 + f*Fscale, e-Ebias);
else
// The value is NaN or infinite.
if (f == 0)
// The value is infinite.
return S * INFINITY;
else
// The value is a NaN.
return NAN;
Это не устанавливает все биты в NAN (включая бит знака) для соответствия точным битамв битах.Нет портативного способа сделать это;обычно это делается путем копирования битов в объект float
или double
с использованием memcpy
или другого копирования с использованием символьного типа, и для этого требуется, чтобы реализация C ++ использовала тип float
или double
это IEEE-754.И, конечно же, вышесказанное требует, чтобы реализация C ++ поддерживала NAN
и INFINITY
, и чтобы тип с плавающей точкой в реализации C ++ был способен представлять значение.