我正在学习更多,然后我想了解浮点数。
让我们说我需要添加:
1 10000000 00000000000000000000000
1 01111000 11111000000000000000000
2的补充形式。
第一位是符号,接下来的8位是指数,最后23位是mantisa。
如果不转换为科学记数法,我该如何添加这两个数字?你能一步一步走吗?
这些东西的任何好资源?视频和练习示例会很棒。
答案 0 :(得分:6)
您必须缩放数字,使它们具有相同的指数。然后添加尾数字段,并在必要时对结果进行标准化。
哦,是的,如果它们是不同的标志,你只需要调用你的减法功能: - )
让我们以十进制为例,因为它更容易理解。让我们进一步假设它们只存储在十进制右边的八位数字(数字介于0和0之间)。
添加两个数字:
sign exponent mantissa value
1 42 18453284 + 0.18453284 x 10^42
1 38 17654321 + 0.17654321 x 10^38
将这些数字缩放到最高指数可以添加尾数字段。
sign exponent mantissa value
1 42 18453284 + 0.18453284 x 10^42
1 42 1765 + 0.00001765 x 10^42
= == ========
1 42 18455049 + 0.18455049 x 10^42
你有你的号码。这也说明了由于移位导致精度损失的方式。例如,IEEE754单精度浮点数将具有:
1e38 + 1e-38 = 1e38
例如:
#include <stdio.h>
int main (void) {
float f1 = 1e38;
float f2 = 1e-38;
float f3 = f1 + f2;
float f4 = f1 - f3;
printf ("%.50f\n", f4);
return 0;
}
就溢出发生的情况而言,这是我提到的规范化的一部分。我们将99999.9999
添加到99999.9993
。由于它们已经具有相同的指数,因此无需扩展,因此我们只需添加:
sign exponent mantissa value
1 5 99999999 + 0.99999999 x 10^5
1 5 99999993 + 0.99999999 x 10^5
= == ========
1 5 199999992 ???
你可以在这里看到我们有一个随身携带的情况,所以我们不能把这个随身携带的数字限制在八位数。我们所做的是将数字向右移动,以便我们可以插入进位。由于这种转变实际上是十分之一,我们必须增加指数来反击。
所以:
sign exponent mantissa value
1 5 199999992 ???
变为:
sign exponent mantissa value
1 6 19999999 + 0.19999999 x 10^6
实际上,这不仅仅是一个简单的右移,因为你需要四舍五入到最接近的数字。如果您要移出的数字是五个或更多,则需要在左侧的数字中添加一个。这就是我选择99999.9993
作为第二个数字的原因。如果我已将99999.9999
添加到自身,我最终会得到:
sign exponent mantissa value
1 5 199999998 ???
在右移的情况下,它会向左侧触发相当多的进位:
sign exponent mantissa value
1 6 20000000 + 0.2 x 10^6