微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这是二进制补码计算溢出错误吗?

如何解决这是二进制补码计算溢出错误吗?

假设8位二进制补码中有两个数字, 当我计算A-B时,会溢出吗?

A = 54 = 00110110; B = -77 = 10110111

这是我的计算:

      00110110
-     10110111
--------------
   (1)11111111 = -1

十进制计算:54-(-77)= 131

因为131!= -1

因此,发生了溢出。

解决方法

确实发生了正负号整数溢出。但是,您的数学不正确。 -77的8位二进制补码值为0b10110*0*11,而不是0b10110*1*11

  00110110    (+54)
- 10110011  - (-77)
----------
  00110110    (+54)
+ 01001101  + (+77)
----------
  10000011    (u131 or -125)

由于很难直观地看到二进制数字的减法,因此通常更容易取反该数字。但是,这是相同的过程,但没有这样做,一次只能做一次:

  00110110
- 10110011
----------
  00110101
- 10110010
----------
  00110011
- 10110000
----------
  00100011
- 10100000
----------
  00000011
- 10000000
----------
  10000011   (borrow over MSb occurred)

这给出了相同的结果,但是工作量更大,并且更有可能导致错误。主要区别在于发生了一点点借用。

,

A = 54 = 00110110; B = -77 = 10110111

实际上-77是10110011

如此

a--b = a + b

设置

        0
 00110110
+01001101
=========

并填写

011111000
 00110110
+01001101
=========
 10000011

msbit的进位和进位不匹配。操作数的msbit也匹配,结果的msbit不匹配。两者都表示签名溢出。 msbit的进位为零表示没有无符号的溢出(如果将其视为加法,则不是)。

虽然是减法,但更正确

a-b = a +(-b)和-b =〜b + 1

所以您在逻辑上真正看到的是b操作数和进位求反。

         1
  00110110
 +01001100
==========

与给出的结果当然相同,但这是减法运算而不是加法运算。

您肯定可以像在小学10年级的10年级中那样轻松地进行二进制减法。

 00110110
-10110011
==========

与小学不同,我们将较大的数字放在首位,然后取反,但在这里我们需要从头开始借用...

1       0
 00110110
-10110011
==========

借用

1       2
 00110100
-10110011
==========
        1

另一个借钱

1      22
 00110000
-10110011
==========
  0000011

另一个借钱

02     22
 00110000
-10110011
==========
 10000011

这里是多余的位,并且是使用加法器时的进位,不是借位。当未发生借位时,进位为1;当发生借位时,进位为0。某些体系结构将减法的进位进位取反,并使其成为借位。有些人不会将其取反,您必须知道,“不进位”是借来的。

二进制补码的优点在于加法和减法没有无符号与有符号的概念。因此,从逻辑角度看,位54-(-77)也与54-179相同,这肯定是借来的。是用户认为位模式为-77或+179。除法和乘法可以在乎,取决于您是否需要填充,并且对有符号的填充进行符号扩展,而对无符号的扩展进行符号扩展。如果操作数的大小正确,则可以使用有符号和无符号乘法来执行或。但是很大一部分操作数溢出。适当的乘法(结果是操作数的位数是2倍)对符号敏感。

54--77 = 131大于127,因此从有符号操作的角度来看,该结果不能适合8位。所以这是一个有符号的溢出。

例如,

54 + 205是259,大于256,因此将是无符号溢出(进位将被设置为加法运算)。但这也是-51,54-51 = 3,它不会借用,因此两种视图在这里也适用。 54 + 205 = 0x103,表示0x03,进位为1。

如果您能解决

个操作数的msbit和msbit的进位全部加在一起 a操作数的a位,b b操作数的b位,i包含msbit,c包含msbit,r包含msbit的结果。 i!= c是有符号的溢出

ab i   cr
00 0 = 00
00 1 = 01 signed overflow
01 0 = 01
01 1 = 10
10 0 = 01
10 1 = 10
11 0 = 10 signed overflow
11 1 = 11

因此,如果msbit的进位与进位不匹配是有符号的溢出,则可以使用该定义。

00 1 = 01 signed overflow
   ^   ^
11 0 = 10 signed overflow
   ^   ^

或者您可以使用以下定义来定义操作数的位是否匹配并且结果不匹配,这是有符号溢出

00 1 = 01 signed overflow
^^      ^
11 0 = 10 signed overflow
^^      ^


00 0 = 00 not a signed overflow
^^      ^ 
11 1 = 11 not a signed overflow
^^      ^

如果操作数的msbit不匹配,则不能有符号溢出。用程序或手工完成3位或4位操作数的整个组合,从带符号的角度检查它们,您可以看到这是一个真实的陈述,您不必相信我。

有些人记得使用msbit方法(无需计算进位和进位即可进行评估),有些人记得进位和进行匹配。结果,您将看到逻辑操作数根据作者的一种或多种方式进行计算。

一些体系结构文档在对进位和溢出位进行误导/混淆时,对术语“溢出实际上是带符号的溢出位”的每次使用都没有打磨。他们中的任何一个都没有在每次提及进位时将其称为无符号溢出/有符号借位/进位位...甚至有些人甚至可能会将溢出位用于乘法和加法运算,因此所有这些只会增加混乱。

最好的练习之一是编写一个小程序(只需要20到30行代码)就为每个16 * 16操作将4位操作数0x0到0xF的所有组合提供给它。因为这些标志在大多数情况下都用于比较,所以要进行减法,然后进行减法(求反,并使用加法器)。并计算所有标志CNVZ。通过该表,您可以了解为什么仅C标志可以用作大于或小于N == V,N!= V等。 Z或C集合与未设置的C集合相同,因此,如果翻转操作数,则可以减少大于/小于或等于的反数的指令数。取反操作数,您无需使用z标志,只需简单地使用jc或jnc。但是,此练习还显示了带符号大于无符号,依此类推。加上明显的有符号和无符号溢出。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。