繁体   English   中英

如何减去IEEE 754数字?

[英]How to subtract IEEE 754 numbers?

如何减去IEEE 754数字?

例如:0,546875-32.875 ...

-> 0,546875在IEEE-754中为0 01111110 10001100000000000000000

-> -32.875在IEEE-754中为1 10000111 01000101111000000000000

那我怎么做减法呢? 我知道我必须使两个指数相等,但是之后该怎么办? 2'-32.875的尾数的补码,加上0.546875的尾数?

真的和您用铅笔和纸做的没什么不同。 好吧有点不同

123400 - 5432 = 1.234*10^5 - 5.432*10^3

较大的数字占优势,将较小数字的尾数移到位桶中,直到指数匹配

1.234*10^5 - 0.05432*10^5

然后用尾数进行减法

1.234 - 0.05432 = 1.17968
1.17968 * 10^5

然后规范化(在这种情况下是)

那是基数为10的数字。

在IEEE float中,单精度

123400 = 0x1E208 = 0b11110001000001000
11110001000001000.000...

规范化我们必须将小数位向左移动16位,因此

1.1110001000001000 * 2^16

指数是有偏的,因此我们将127加到16并得到143 = 0x8F。 它是一个正数,所以符号位是0,我们开始构建IEEE浮点数,即隐含小数点前的前导1,并且不以单精度使用它,我们将其删除并保留小数

符号位,指数,尾数

0 10001111 1110001000001000...
0100011111110001000001000...
0100 0111 1111 0001 0000 0100 0...
0x47F10400

并且,如果您编写程序来查看什么是123400,那么您会得到相同的结果:

0x47F10400 123400.000000

所以我们知道第一个操作数的指数和尾数

现在第二个操作数

5432 = 0x1538 = 0b0001010100111000

规范化,将小数点后移12位

1010100111000.000
1.010100111000000 * 2^12

指数偏置加127并得到139 = 0x8B = 0b10001011

放在一起

0 10001011 010100111000000
010001011010100111000000
0100 0101 1010 1001 1100 0000...
0x45A9C00

并且计算机程序/编译器提供了相同的

0x45A9C000 5432.000000

现在回答您的问题。 使用浮点数的组成部分,我在这里恢复了隐含的1,因为我们需要它

0 10001111 111100010000010000000000 -  0 10001011 101010011100000000000000

在减去之前,我们必须像在小学时一样将小数位对齐,因此在这种情况下,您必须向右移动较小的指数,将尾数尾移开直到指数匹配

0 10001111 111100010000010000000000 -  0 10001011 101010011100000000000000
0 10001111 111100010000010000000000 -  0 10001100 010101001110000000000000
0 10001111 111100010000010000000000 -  0 10001101 001010100111000000000000
0 10001111 111100010000010000000000 -  0 10001110 000101010011100000000000
0 10001111 111100010000010000000000 -  0 10001111 000010101001110000000000

现在我们可以减去尾数。 如果符号位匹配,那么如果它们不匹配,我们将实际减去,然后加。 他们匹配这将是一个减法。

计算机通过使用加法逻辑执行减法运算,将第二个运算符转换为加法器,并声明进位位,如下所示:

                         1
  111100010000010000000000
+ 111101010110001111111111
==========================

现在,就像使用纸和铅笔一样,让我们​​执行添加

 1111000100000111111111111
  111100010000010000000000
+ 111101010110001111111111
==========================
  111001100110100000000000 

或用计算器上的十六进制完成

111100010000010000000000 = 1111 0001 0000 0100 0000 0000 = 0xF10400
111101010110001111111111 = 1111 0101 0110 0011 1111 1111 = 0xF563FF
0xF10400 + 0xF563FF + 1 = 0x1E66800
1111001100110100000000000 =1 1110 0110 0110 1000 0000 0000 = 0x1E66800

关于硬件的工作原理,因为这实际上是使用加法器的减法运算,所以我们还反转了进位位(或者在某些计算机上,它们保持原样)。 因此,执行1是一件好事,我们基本上将其丢弃。 如果它是零的进位,我们将需要更多的工作。 我们没有进位,所以我们的答案确实是0xE66800。

很快,让我们看到另一种方式,而不是反转和添加一个,只需使用计算器

111100010000010000000000 -  000010101001110000000000 = 
0xF10400 - 0x0A9C00 = 
0xE66800

通过尝试使其形象化,我也许使情况变得更糟。 尾数相减的结果是111001100110100000000000(0xE66800),最高有效位没有移动,在这种情况下,我们以24位数字结尾,msbit为1。没有归一化。 为了规范化,您需要向左或向右移动尾数,直到24位与最左端的最高有效位1对齐,并为每个位移调整指数。

现在从答案中剥离1.位,然后将零件放在一起

0 10001111 11001100110100000000000
01000111111001100110100000000000
0100 0111 1110 0110 0110 1000 0000 0000
0x47E66800

如果您一直通过编写程序来做到这一点,那么我也做到了。 该程序以不当方式使用联合会违反C标准。 我在计算机上使用编译器放弃了它,不要期望它一直都能工作。

#include <stdio.h>

union
{
    float f;
    unsigned int u;
} myun;


int main ( void )
{
    float a,b,c;

    a=123400;
    b=  5432;

    c=a-b;

    myun.f=a; printf("0x%08X %f\n",myun.u,myun.f);
    myun.f=b; printf("0x%08X %f\n",myun.u,myun.f);
    myun.f=c; printf("0x%08X %f\n",myun.u,myun.f);

    return(0);
}

我们的结果与上述程序的输出匹配,我们手工完成了一个0x47E66800

0x47F10400 123400.000000
0x45A9C000 5432.000000
0x47E66800 117968.000000

如果您正在编写一个程序来综合您的程序可以执行减法的浮点数学运算,则不必进行求反和加一件事,而使运算复杂化,如上所述。 如果您需要用符号位来获得负结果,请反转结果,然后归一化。

所以:

1)提取零件,符号,指数,尾数。

2)通过从最小指数的数字中减去尾数位来对齐小数位,将尾数向右移动直到指数匹配

3)如果符号位相同,则为减法运算,然后执行减法;如果符号位不同,则对尾数进行加法。

4)如果结果为零,则答案为零,将IEEE值编码为零,否则:

5)归一化数字,将答案向右或向左移动(答案可以是24位加/减的25位,加/减可以有很大的偏移以归一化,可以向右或向左移很多位)直到您有一个24位数字,其中最重要的一位左对齐。 24位用于单精度浮点。 定义规范化的更正确方法是向左或向右移动,直到数字类似于1.something。 如果您有0.001,则将向左移动3;如果您有11.10,则将向右移动1。向左移动将增大指数,向右移动将减小指数。 与从整数转换为浮点数时没有什么不同。

6)对于单精度,从尾数中删除前导1.如果指数溢出,则可以开始构建信号南。 如果符号位不同而您执行了加法运算,则必须处理找出结果符号位。 如果上述一切都很好,您只需将符号位,指数和尾数放在结果中

您询问乘积,乘和除是不同的,所以这就是我所介绍的全部。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM