【问题标题】:Is this two's complement calculation overflow error?这是二进制补码计算溢出错误吗?
【发布时间】:2021-02-24 14:14:29
【问题描述】:

假设 8 位二进制补码表示有两个数, 当我计算 A-B 时,是否溢出?

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

这是我的计算:

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

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

自从 131 != -1

因此,发生了溢出。

【问题讨论】:

  • 是的,这是签名溢出。

标签: assembly binary numbers twos-complement


【解决方案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)

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

【讨论】:

    【解决方案2】:

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

    实际上 -77 是 10110011

    所以

    a - -b = a + b

    设置

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

    然后填写

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

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

    虽然是减法,但更正确

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

    所以你在逻辑中真正看到的是 b 操作数和倒置的进位。

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

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

    你当然可以像在小学时用 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。

    如果你解决了

    操作数的msbits和msbit的进位加在一起 a 操作数 a 的 msbit,b 操作数 b 的 msbit,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
       ^   ^
    

    或者你可以使用如果操作数的msbits匹配而结果不匹配的定义是有符号溢出

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

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

    有些人通过 msbit 方法记住它(您可以评估它而无需计算进位和执行),有些人记得进位和执行匹配与否。因此,您将看到逻辑操作数根据作者以一种或另一种方式计算它。

    一些架构文档在谈论进位位和溢出位时会产生误导/混淆,而在每次使用溢出确实是有符号溢出位的术语时都没有经过打磨。他们中没有人每次提到它时都将进位位称为无符号溢出/有符号借位/进位位......有些人甚至可能会使用溢出位进行乘法和加法,所以所有这些只会增加混乱。

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

    【讨论】:

    • 非常感谢!我理解这个概念:)
    • 请注意这里的拼写,尤其是包含撇号的单词。以下是一些正确的拼写,以及您的帖子历史记录中的拼写错误数量:不要 (765)、不要 (488)、不会 (217)、不能 (306)。对于没有英语作为第一语言的人,这里有一些宽容,但文体和故意拼写错误违背了网站的目标。您的浏览器中有拼写检查器吗?
    • 我记得之前得到您的保证,您会付出更多的努力,我希望您能坚持这一承诺。不幸的是,“Wont”是另一个(完全不相关的)单词的正确拼写。来自字典:习惯做法;用法。同义词:习惯。 示例:星期六,他像往常一样去纸店散步。这个词现在被认为是相当古老的。
    • “有一天,这个世界将不再有转移性癌症、自恋的骗子和撇号。” “该语言不会因为它的废除而变得更糟”。
    猜你喜欢
    • 2015-06-09
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 2018-03-25
    • 2017-07-17
    • 1970-01-01
    相关资源
    最近更新 更多