OTHERS 四月 04, 2021

二进制算术运算

文章字数 4.7k 阅读约需 4 mins. 阅读次数

总体来讲,二进制算术运算可以采用竖式计算的方式,与十进制竖式计算的区别是,逢十进一变为了逢二进一。

整数

以 8 和 4 为例,可参照 十进制整数与二进制数转换 中方法,分别计算出二进制形式:

8 (10) = 1000 (2)
4 (10) = 0100 (2)

  1000
+ 0100
------
  1100

1100 (2) = 12 (10)

  1000
- 0100
------
  0100

0100 (2) = 4 (10)

负数怎么表示

如果是 4 - 8 时会怎么样呢?

  0100
- 1000
------
  1100

因为第一位 0 - 1 时始终需要向前一位借一,故无论使用几位二进制数表示此负数,前面都会补 1,如 1111 1100

表示有符号的数时,二进制数的第一位用来表示符号位,0 代表正数,1 代表负数。

在计算机中,使用 补码 来表示负数。补码反码+ 1,而 反码 的意思是按位取反。

通过补码的逆运算(先减一,再取反),我们可以算出,1111 1100 即为 -4

1111 1100 - 1
= 1111 1011
再取反
=> 0000 0100
= 1 * 2^2 = 4

  1000
x 0100
------
  0000
 0000
1000
------
100000

100000 (2) = 32 (10)

       0010
     _______
0100 ) 1000
       100
      ------
         0

0010 (2) = 2 (10)

浮点数

浮点数运算时,可先参照 十进制浮点数与二进制数转换 中方式,将浮点数转换为二进制形式,未转换为 IEEE 754 形式时,可参照上述方式直接运算,如:

  0.1
+ 0.01
------
  0.11

0.1 (2) = 0.5 (10)
0.01 (2) = 0.25 (10)
0.11 (2) = 0.75 (10)

由浮点数转换二进制的方式可以知道,只有 m*2^-n(m、n 为整数),才能转换成有限位数的二进制数(如 0.5,0.25,0.125 ……);其余的小数表示成二进制时,都会因精度限制,仅能表示为近似值。

如果浮点数转换为了 IEEE 754 标准的形式,在计算时,需要注意两个二进制数的指数部分是否相同。

如果指数相同,同样可以按照上述方式,直接将小数部分进行运算。

如果指数不同,则需要先将指数调整为相同的情况,再进行计算。

以经典的 0.1 + 0.2 为例:

0.1 (10) = 0.0001 1001 1001 1001 ... (2)
0.2 (10) = 0.0011 0011 0011 0011 ... (2)

使用 IEEE 754 双精度浮点数方式表示时:

0.1 (10) => 0 01111111011 1001100110011001100110011001100110011001100110011010
0.2 (10) => 0 01111111100 1001100110011001100110011001100110011001100110011010

注意,因为精度限制,需截断小数位 52 位之后的 1001 ……,故小数位最后的 1001 发生进位,变成了 1010

对比可以发现,0.1 和 0.2 的双精度浮点数二进制表示中,仅指数位部分不同。

此时,在进行加法运算时,需先将指数部分转换为相同的值。

0.1 的指数部分为 01111111011 (2) = 1019 (10) = 1023 - 4,即指数为 2^(-4)

0.2 的指数部分为 01111111100 (2) = 1020 (10) = 1023 - 3,即指数位 2^(-3)

双精度指数偏移量为 2^10-1=1023

可将 0.1 的小数部分左移一位,使其与 0.2 的指数部分相同。因二进制科学计数法表示形式为 1.xxxx * 2^n,故左移后的 0.1 的小数部分变为

1.1001100110011001100110011001100110011001100110011010 * 2^(-4)
=>
0.11001100110011001100110011001100110011001100110011010 * 2^(-3)

保留 52 位,末位 0 可直接省略,故 0.1 + 0.2 可以按如下形式进行计算:

  0.1100110011001100110011001100110011001100110011001101 * 2^(-3)
+ 1.1001100110011001100110011001100110011001100110011010 * 2^(-3)
---------------------------------------------------------------------
 10.0110011001100110011001100110011001100110011001100111 * 2^(-3)

转换为科学计数法,可表示为:

10.0110011001100110011001100110011001100110011001100111 * 2^(-3)
=>
1.00110011001100110011001100110011001100110011001100111 * 2^(-2)

因双精度只能保留 52 位小数,舍弃末位 1 并进位,小数部分变为:

1.00110011001100110011001100110011001100110011001100111 * 2^(-2)
=>
1.0011001100110011001100110011001100110011001100110100 * 2^(-2)

小数部分左移一位,相当于指数部分加一,指数部分变为:

01111111100
=>
01111111101

故 0.1 + 0.2 最终的双精度二进制浮点数表示为:

0 01111111101 0011001100110011001100110011001100110011001100110100

转换为十进制:

2^-2+2^-5+2^-6+2^-9+2^-10+2^-13+2^-14+2^-17+2^-18+2^-21+2^-22+2^-25+2^-26+2^-29+2^-30+2^-33+2^-34+2^-37+2^-38+2^-41+2^-42+2^-45+2^-46+2^-49+2^-50+2^-52
=
0.3000000000000000444089209850062616169452667236328125

以上结果可通过 在线精度计算器 计算获得。

0%