Сообщение Re[3]: сконвертировать unsigned int в float без потери точно от 02.12.2015 16:52
Изменено 02.12.2015 16:56 watchmaker
Здравствуйте, B0FEE664, Вы писали:
BFE>Из вашего комментария я понимаю, что этот интервал определяется размером мантиссы, т.е. assert должен быть таким:
BFE>assert(n <= (1U << FLT_MANT_DIG) — 1);
BFE>Верно?
Нет, если FLT_MANT_DIG = 24 и FLT_RADIX = 2, то такое условие сводится к assert(n ≤ 16777215). То есть число 16777216 не удовлетворяет ему, хотя оно и точно представимо в IEEE754-float, и непосредственно прилегает к отрезку [0, 16777215] — то есть этот отрезок может быть увеличен.
А так практически всё верно.
Но, конечно, формально это не переносимо. FLT_RADIX не всегда равен 2. А в мантиссе не всегда присутствует неявный старший бит.
Если же исправить ошибку с числом 16777216, и добавить проверку
BFE>Из вашего комментария я понимаю, что этот интервал определяется размером мантиссы, т.е. assert должен быть таким:
BFE>assert(n <= (1U << FLT_MANT_DIG) — 1);
BFE>Верно?
Нет, если FLT_MANT_DIG = 24 и FLT_RADIX = 2, то такое условие сводится к assert(n ≤ 16777215). То есть число 16777216 не удовлетворяет ему, хотя оно и точно представимо в IEEE754-float, и непосредственно прилегает к отрезку [0, 16777215] — то есть этот отрезок может быть увеличен.
А так практически всё верно.
Но, конечно, формально это не переносимо. FLT_RADIX не всегда равен 2. А в мантиссе не всегда присутствует неявный старший бит.
Если же исправить ошибку с числом 16777216, и добавить проверку
static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 floating point");
то будет вполне надёжно.Re[3]: сконвертировать unsigned int в float без потери точно
Здравствуйте, B0FEE664, Вы писали:
BFE>Из вашего комментария я понимаю, что этот интервал определяется размером мантиссы, т.е. assert должен быть таким:
BFE>assert(n <= (1U << FLT_MANT_DIG) — 1);
BFE>Верно?
Нет, не учтено разложение на произведение чётного и нечётного чисел. Так если FLT_MANT_DIG = 24 и FLT_RADIX = 2, то твоё условие сводится к assert(n ≤ 16777215). То есть число 16777216 не удовлетворяет ему, хотя оно и точно представимо в IEEE754-float, и непосредственно прилегает к отрезку [0, 16777215] — то есть этот отрезок на самом деле может быть увеличен.
В остальном практически всё верно.
Но формально это не переносимо. FLT_RADIX не всегда равен 2. А в мантиссе не всегда присутствует неявный старший бит.
Если же исправить ошибку с числом 16777216, и добавить проверку
BFE>Из вашего комментария я понимаю, что этот интервал определяется размером мантиссы, т.е. assert должен быть таким:
BFE>assert(n <= (1U << FLT_MANT_DIG) — 1);
BFE>Верно?
Нет, не учтено разложение на произведение чётного и нечётного чисел. Так если FLT_MANT_DIG = 24 и FLT_RADIX = 2, то твоё условие сводится к assert(n ≤ 16777215). То есть число 16777216 не удовлетворяет ему, хотя оно и точно представимо в IEEE754-float, и непосредственно прилегает к отрезку [0, 16777215] — то есть этот отрезок на самом деле может быть увеличен.
В остальном практически всё верно.
Но формально это не переносимо. FLT_RADIX не всегда равен 2. А в мантиссе не всегда присутствует неявный старший бит.
Если же исправить ошибку с числом 16777216, и добавить проверку
static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 floating point");
то будет вполне надёжно.