денормализовать произведение двух чисел с плавающей запятой или нет - PullRequest
1 голос
/ 12 июля 2020

Я пытаюсь умножить 2 числа с плавающей запятой без использования инструкций с плавающей запятой. Все шло хорошо, пока я не наткнулся на денормализованные числа. Как мне узнать, следует ли мне нормализовать или денормализовать продукт? Эта неопределенность затрудняет округление продукта. Моя интуиция подсказывает мне, что произведение следует денормализовать, если оба фактора являются денормализованными числами.

Ответы [ 2 ]

4 голосов
/ 12 июля 2020

Ненормальные числа очень близки к нулю. Для субнормального 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 отменяет все, кроме самого младшего бита мантиссы (пример «catastrophi c cancellation»), оставляя число слишком маленьким, чтобы его можно было представить как нормализованное число с плавающей запятой.

1 голос
/ 12 июля 2020

Как мне узнать, следует ли мне нормализовать или денормализовать произведение?

Когда продукт такой маленький, его смещенный показатель степени меньше 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
...