денормализовать произведение 2 чисел с плавающей запятой или нет
Я пытаюсь умножить 2 числа с плавающей запятой без использования инструкций с плавающей запятой. Все шло хорошо, пока я не наткнулся на денормализованные числа. Как мне узнать, следует ли мне нормализовать или денормализовать продукт? Эта неопределенность затрудняет округление продукта. Моя интуиция подсказывает мне, что продукт следует денормализовать, если оба фактора являются денормализованными числами.
2 ответа
Субнормальные числа очень близки к нулю. Для субнормальногоx
, x^2
имеет примерно половину несмещенной экспоненты, а это слишком мало для представления даже субнормального. (Даже еслиx
был самым большим субнормальным, т.е. nextafter(FLT_MIN, -INF)
. То же самое для любых двух субнормальных чисел.
Произведение двух субнормальных чисел всегда полностью меньше нуля до + или -0,0.
Результат любой операции всегда следует по возможности нормализовать. Единственный раз, когда это невозможно, - это когда показатель будет слишком мал, тогда у вас есть субнормальные (также известные как денормальные) числа, которые дадут вам постепенное истощение, оставив начальные биты мантиссы равными нулю для минимального значения показателя. https://en.wikipedia.org/wiki/Single-precision_floating-point_format в целом довольно хорошо объясняет субнормальные числа.
Это общее правило для чисел с плавающей запятой, всегда: форматы IEEE754, такие как binary32 и binary64, не оставляют выбора в том, как представлять любое заданное конечное значение. Кодирование ненулевой экспоненты подразумевает начало1
в мантиссе, поэтому у вас не может быть денормализованного float
или double
кроме субнормального. В 80-битном формате расширенной точности x87 все биты мантиссы хранятся явно, поэтому можно закодировать число с ненулевой экспонентой, но с ведущими нулями в мантиссе. Однако оборудование может даже считать это недействительным, и вам определенно никогда не следует этого делать, потому что это означает выброс большего количества бит мантиссы, чем необходимо (если это было умножение).
Сложение или вычитание также могут давать субнормальные числа, если знаки различаются / совпадают соответственно. напримерnextafter(FLT_MIN, +INFINITY) - FLT_MIN
отменяет все, кроме самого младшего бита мантиссы (пример "катастрофической отмены"), оставляя число слишком маленьким для представления в виде нормализованного числа с плавающей запятой.
Как мне узнать, следует ли мне нормализовать или денормализовать продукт?
Когда произведение настолько мало, что его экспонента со смещением меньше 1, результатом является ненормальное денормальное значение или 0,0, когда смещенная экспонента меньше 1 - количество значащих битов.
Для binary64:
Когда продукт меньше чем DBL_MIN
....
DBL_MIN 2.225...E-308 or 0X1P-1022
Но такой большой, как DBL_TRUE_MIN
DBL_TRUE_MIN 4.940...E-324 or 0X1P-1074
Моя интуиция подсказывает мне, что продукт следует денормализовать, если оба фактора являются денормализованными числами.
Произведение двух столь малых чисел само по себе настолько мало, что обычно произведение округляется до нуля.
Товар находится в субнормальном диапазоне даже при нормальных аргументах. Пример:
DBL_MIN * 0.5 --> subnormal