添加 32 位浮点数. [英] Adding 32 bit floating point numbers.

查看:49
本文介绍了添加 32 位浮点数.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学到的比我想知道的浮点数还要多.

I'm learning more then I ever wanted to know about Floating point numbers.

假设我需要添加:

1 10000000 00000000000000000000000

1 10000000 00000000000000000000000

1 01111000 11111000000000000000000

1 01111000 11111000000000000000000

2 的补码形式.

第一位是符号,接下来的 8 位是指数,最后 23 位是尾数.

The first bit is the sign, the next 8 bits are the exponent and the last 23 bits are the mantisa.

不转换为科学记数法,如何将这两个数字相加?你能一步一步地走过去吗?

Without doing a conversion to scientific notation, how do I add these two numbers? Can you walk through it step by step?

这些东西有什么好的资源吗?视频和练习示例会很棒.

any good resources for this stuff? Videos and practice examples would be great.

推荐答案

您必须缩放数字,使它们具有相同的指数.然后添加尾数字段,并在必要时对结果进行标准化.

You have to scale the numbers so that they have the same exponent. Then you add the mantissa fields and, if necessary, normalise the result.

哦,是的,如果它们是不同的符号,你只需调用减法函数:-)

Oh, yes, and if they're different signs, you just call your subtraction function instead :-)

让我们用十进制做一个例子,因为它更容易理解.让我们进一步假设它们仅以小数点右侧的八位数字存储(并且数字介于 0 和 1 之间).

Let's do an example in decimal since it's easier to understand. Let's further assume they're stored with only eight digits to the right of the decimal (and the numbers are between 0 inclusive and 1 exclusive).

将两个数字相加:

sign  exponent  mantissa  value
   1        42  18453284  + 0.18453284 x 10^42
   1        38  17654321  + 0.17654321 x 10^38

将这些数字缩放到最高指数可以为您添加尾数字段.:

Scaling these numbers to the highest exponent gives something where you can add the mantissa fields.:

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 单精度浮点数将具有:

And there you have your number. This also illustrates how accuracy can be lost due to the shifting. For example, IEEE754 single precision floats will have:

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
", f4);
    return 0;
}

<小时>

就溢出发生的情况而言,这是我提到的规范化的一部分.让我们将 99999.9999 添加到 99999.9993.由于它们已经具有相同的指数,因此无需缩放,因此我们只需添加:


In terms of what happens with overflow, that's part of the normalisation I mentioned. Let's add 99999.9999 to 99999.9993. Since they already have the same exponent, no need to scale, so we just add:

sign  exponent  mantissa  value
   1         5  99999999  + 0.99999999 x 10^5
   1         5  99999993  + 0.99999999 x 10^5
   =        ==  ========
   1         5 199999992  ???

你可以在这里看到我们有一个进位情况,所以我们不能把进位放入数字中,限制为八位数字.然后我们要做的是将数字向右移动,以便我们可以插入进位.由于这种转变实际上是除以 10,因此我们必须增加指数以抵消这一点.

You can see here that we have a carry situation so we can't put that carry into the number, being limited to eight digits. What we do then is to shift the number to the right so that we can insert the carry. Since that shift is effectively a divide-by-ten, we have to increment the exponent to counter that.

所以:

sign  exponent  mantissa  value
   1         5 199999992  ???

变成:

sign  exponent  mantissa  value
   1         6  19999999  + 0.19999999 x 10^6

实际上,这不仅仅是简单的右移,因为您需要四舍五入到最接近的数字.如果您要移出的数字是五或更多,则需要在左边的数字上加一.这就是我选择 99999.9993 作为第二个数字的原因.如果我将 99999.9999 添加到自身,我会得到:

In reality, it's not just a simple right-shift since you need to round to the nearest number. If the number you're shifting out is five or more, you need to add one to the digit on the left. That's why I chose 99999.9993 as the second number. If I had added 99999.9999 to itself, I would have ended up with:

sign  exponent  mantissa  value
   1         5 199999998  ???

在右移时,会触发很多向左进位:

which, on right shift, would have triggered quite a few carries towards the left:

sign  exponent  mantissa  value
   1         6  20000000  + 0.2 x 10^6

这篇关于添加 32 位浮点数.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆