加法器如何执行无符号整数减法?
假设A
和B
是有符号正整数,那么对于AB
,它是使用A+2
计算的B
的补集。
例如,在 4 位二进制系统中,对于有符号整数,我们有 7-3=0111-0011=0111+1101=(1)0100
, 括号中的1是进位位。根据有符号整数的溢出规则,我们知道没有溢出,因此结果是正确的。
然而,对于无符号整数,如果我们计算7-3
会发生什么?如果我们用上面提到的同样的方式:
7-3=0111-0011=0111+1101=(1)0100
那么,根据无符号整数的溢出规则,由于进位而导致溢出。换句话说,0100
是错误的,因为存在溢出。但事实上,我们知道结果 0100
是正确的。
如果我的分析是正确的,那么用加法器进行无符号整数减法不是错误的吗?
Suppose that A
and B
are signed positive integers, then for A-B
, it's calculated using A+2
's complement of B
.
For example, in a 4-bit binary system, for signed integers, we have7-3=0111-0011=0111+1101=(1)0100
,
the 1 in the bracket is the carry bit. According to the overflow rule for signed integer, we know there is no overflow and the result is therefore correct.
However, for unsigned integers, what will happen if we calculate 7-3
? If we use the same way we mentioned above:
7-3=0111-0011=0111+1101=(1)0100
then, according to the overflow rule for unsigned integers, there is an overflow because of the carry out. In another word, 0100
is wrong because there is an overflow. But in fact, we know the result 0100
is correct.
If my analysis is correct, isn't it wrong to use adder to perform unsigned integer subtraction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在相关问题的此答案中,有 C 语言的示例代码这展示了如何通过加法进行减法。该代码还设置进位和溢出标志,并包含一个简单的“测试”,用于添加和减去一些数字并打印结果。这些数字是 8 位的。
编辑:正式证明,可以对无符号整数使用 ADD 而不是 SUB AND 发现无符号上溢/下溢,就像来自 SUB 一样。
假设我们要计算
a - b
,其中a
和b
是 4 位无符号整数,我们希望通过加法和减法来执行减法当 a < 时,获得 4 位差异和下溢/溢出指示b.a - b = a + (-b)
由于我们采用模 16 算术运算,因此
-b
=16-b
。所以,a - b = a + (-b) = a + (16 - b)
如果我们执行
a
和16-b
的常规无符号加法,则此加法的溢出条件,通常由 CPU 在其carry
标志中指示,将是这样的(回想一下,我们正在处理 4 位整数):a + (16 - b) > 15
让我们简化这个溢出情况:
a+16-b> 15
a+16> 15 + b
a+1> b
a> b - 1
现在让我们回想一下我们正在处理整数。因此上面可以重写为:
a >= b。
这是添加
a
和(16)-b
后得到进位flag = 1的条件。如果不等式不成立,我们得到进位 = 0。现在让我们回想一下,我们对减法 (a - b) 的上溢/下溢感兴趣。该条件是a < b.
嗯,a >= b 与 a <= b 完全相反。 b.
由此可见,通过添加
a
和(16)-b
得到的carry
标志是减法溢出的逆运算,或者,换句话说,通过直接从a
中减去b
得到的borrow
标志的逆适当的减法指令(例如SUB)。只需颠倒进位或以相反的方式处理即可。
In this answer to a related question there's sample code in C that shows how to do subtraction via addition. The code sets the carry and overflow flags as well and contains a simple "test" that adds and subtracts a few numbers and prints the results. The numbers are 8-bit.
EDIT: Formal proof that one can use ADD instead of SUB for unsigned integers AND spot unsigned overflow/underflow as if from SUB.
Let's say we want to calculate
a - b
, wherea
andb
are 4-bit unsigned integers and we want to perform subtraction via addition and get a 4-bit difference and an underflow/overflow indication when a < b.a - b = a + (-b)
Since we're operating in modulo-16 arithmetic,
-b
=16-b
. So,a - b = a + (-b) = a + (16 - b)
If we perform regular unsigned addition of
a
and16-b
the overflow condition for this addition, which is often indicated by the CPU in itscarry
flag, will be this (recall that we're dealing with 4-bit integers):a + (16 - b) > 15
Let's simplify this overflow condition:
a + 16 - b > 15
a + 16 > 15 + b
a + 1 > b
a > b - 1
Let's now recall that we're dealing with integers. Therefore the above can be rewritten as:
a >= b.
This is the condition for getting carry flag = 1 after adding
a
and(16)-b
. If the inequality doesn't hold, we get carry = 0.Let's now recall that we were interested in overflow/underflow from subtraction (a - b). That condition is a < b.
Well, a >= b is the exact opposite of a < b.
From this it follows that the
carry
flag that you get from addinga
and(16)-b
is the inverse of the subtraction overflow, or, in other words, the inverse of theborrow
flag you'd get by subtractingb
directly froma
using the appropriate subtraction instruction (e.g. SUB).Just invert the carry or treat it in the opposite way.
你的分析不正确。实际上是 CPU ALU 单元相关的。 :)
在第一种情况下,您使用的是 4 位整数,但您忘记了 4 位符号整数的最高位是 sign!因此,您仅检查进位和溢出状态,而不检查负状态位。
一般来说,二进制算术运算对于有符号整数和无符号整数来说,add 和 sub 是相同的。只有受影响的标志不同。
实际上你必须考虑:
详细说明:
补函数的挖掘是求反,即从正数中得到相反的负数,从负数中得到正数。我们可以通过两种方式进行二进制补码。让我们看看数字 3 的两种情况
b'1101' + 进位(仅在 compl (0) 时设置进位)
等于 b'0000' - b'0011' = b'1101' + 进位(进位仅在以下情况下清除)
compl (0))
在第一种情况下,函数补码也对进位位进行补码,我们还有进位标志的第二种解释,名为 借用。
在第二种情况下,一切都清楚了。如果我们在补码处有进位(溢出),则意味着我们需要另一个溢出来标准化减法结果。
Your analysis is not correct. Actually is CPU ALU unit dependent. :)
In first case you are using 4 bit integer but you forgotten that the highest bit of 4 bit sign integer is sign! So you are checking only the Carry and Overflow status and not also Negative status bit.
In generally binary arithmetic operations add and sub are the same for signed integers and unsigned integers. Only affected flags are different.
Actually you must consider:
Detail explanation:
The mining of complement function is negation, so to get opposite negative number from positive and positive from negative. We can make binary complement on two ways. Lets see both cases for number 3.
b'1101' + Carry (Carry is set only at compl (0))
is equal b'0000' - b'0011' = b'1101' + Carry (Carry is clear only at
compl (0))
In first case function complement also complement the carry bit and we have also the second interpretation of carry flag named borrow.
In second case everything is clear. If we have got carry (overflow) at complement that mean that we need another overflow to normalize the result of subtraction.
这有点难以理解,但是......我有一些 VHDL 来完成这个任务。我的 CPU 的内存位置是无符号的,偏移值是有符号的。
This is a bit hard to understand but... I had some VHDL where I did this. I had a CPU with a memory location that was unsigned and an offset value that was signed.
你的分析是正确的。
使用
确定单解释的无符号加法和无符号减法(使用 2 的补码加法)的溢出。
在无符号加法中,溢出表示为
正确结果由下式表示
但是
用于加法
因此无论如何溢出由 1 表示。
类似地
在无符号减法中溢出由
正确结果由下式表示
但是
用于减法
因此无论如何溢出都由 1 表示。
因此,我们可以对无符号加法和无符号减法中的溢出进行单一解释。
Your analysis is correct.
Use
to determine overflow for both unsigned addition and unsigned subtraction( using 2's Complement addition ) for single interpretation.
In unsigned addition overflow is indicated by
Correct result is indicated by
But
is for addition
So anyway overflow is indicated by 1.
Similarly
In unsigned subtraction overflow is indicated by
Correct result is indicated by
But
is for subtraction
So anyway overflow is indicated by 1.
Thus we can have single interpretation for overflow in both unsigned addition and unsigned subtraction.