我试图在不使用浮点指令的情况下将 2 个浮点数相乘。在我遇到非规范化数字之前,一切都很顺利。我如何知道我应该对产品进行规范化还是非规范化?这种不确定性使得对产品进行四舍五入变得困难。我的直觉告诉我,如果两个因素都是非规范化的数字,则产品应该是非规范化的。
2 回答
次正规数非常接近于零。对于 subnormal x
,x^2
大约有一半的无偏指数,这对于甚至 subnormal 来说都太小了。(即使x
是最大的次正规数,即nextafter(FLT_MIN, -INF)
。对于任何两个次正规数,事情都是相似的。
两个次正规数的乘积总是完全下溢到 + 或 -0.0。
如果可能,任何操作的结果都应该被归一化。唯一不可能的情况是指数太小,然后你有次正规(又名非正规)数字通过将尾数的前导位保留为零来逐渐下溢,以获得最小指数值。 https://en.wikipedia.org/wiki/Single-precision_floating-point_format通常很好地解释了次正规数。
这是浮点的一般规则,总是:像 binary32 和 binary64 这样的 IEEE754 格式在如何表示任何给定的有限值方面别无选择。 非零指数编码意味着1
尾数中的前导,因此您不能有非规范化float
或double
除次规范外。x87 80 位扩展精度格式的所有尾数位都显式存储,因此可以使用非零指数对尾数中前导零的数字进行编码。然而,硬件甚至可能认为这是无效的,你绝对不应该这样做,因为这意味着丢弃比必要更多的尾数位(如果这是一个乘法)。
如果符号分别不同/匹配,加法或减法也可以产生次正规数。egnextafter(FLT_MIN, +INFINITY) - FLT_MIN
取消除最低尾数位之外的所有位(“灾难性取消”的示例),留下一个太小而无法表示为规范化浮点数的数字。
我如何知道我应该对产品进行规范化还是非规范化?
当乘积非常小,其偏置指数小于 1时,当偏置指数小于1 个有效位时,结果是次正规非正规或 0.0 。
对于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