假设A
和B
是有符号正整数,那么对于A-B
,它是使用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
是正确的。
如果我的分析是正确的,那么使用加法器来执行无符号整数减法不是错误的吗?
发布于 2011-11-09 16:12:10
在this answer中,对于一个相关的问题,有一个用C编写的示例代码,它展示了如何通过加法进行减法。该代码还设置进位和溢出标志,并包含一个简单的“测试”,该测试对一些数字进行加减运算,并打印结果。这些数字是8位的。
EDIT:正式证明,对于无符号整数,可以使用ADD而不是SUB。和发现无符号溢出/下溢,就好像来自SUB一样。
假设我们想要计算a - b
,其中a
和b
是4位无符号整数,我们想要通过加法执行减法,并在a < b时得到4位差和下溢/溢出指示。
A-b=a+ (-b)
因为我们使用的是模16运算,所以-b
= 16-b
。所以,
A-b=a+ (-b) =a+ (16 - b)
如果我们执行a
和16-b
的常规无符号加法,这个加法的溢出条件将是这样的(回想一下,我们正在处理的是4位整数):
A+ (16 - b) > 15
让我们简化这个溢出条件:
A+ 16 -b> 15
A+ 16 > 15 +b
A+1>b
A>b-1
现在让我们回想一下,我们正在处理整数。因此,上面的代码可以重写为:
a >= b.
这是在添加a
和(16)-b
之后,获取进位标志=1的条件。如果不等式不成立,我们得到进位= 0。
现在让我们回想一下,我们对减法(a - b)中的溢出/下溢感兴趣。这个条件是a < b。
好的,a >= b和a < b正好相反。
由此可以得出,您通过将a
和(16)-b
相加得到的carry
标志是减法溢出的逆,或者换句话说,是通过使用适当的减法指令(例如SUB)直接从a
中减去borrow
标志的逆而得到的。
只需颠倒进位或以相反的方式处理它。
发布于 2011-11-09 00:20:30
你的分析不正确。实际上,它依赖于CPU ALU单元。:)
在第一种情况下,您使用的是4位整数,但是您忘记了4位符号整数的最高位是符号!因此,您只检查进位和溢出状态,而不检查负状态位。
在一般的二进制算术运算中,对于有符号整数和无符号整数,加上和sub是相同的。只有受影响的标志是不同的。
实际上你必须考虑:
在有符号整数算术上,
H117仅携带E219标志。H220F221
详细说明:
补码函数的挖掘是否定的,所以从正到正,从负到正,都是相反的负数。我们可以通过两种方式实现二进制补码。让我们看看3号的两种情况。
无符号算术时的进位
在第一种情况下,函数补码也对进位位进行补充,我们还有第二种对进位标志的解释,称为borrow。
在第二种情况下,一切都很清楚。如果我们在补码处有进位(溢出),这意味着我们需要另一个溢出来规范化减法结果。
发布于 2011-11-08 23:50:08
这有点难理解但是..。我在做这个的时候用了一些VHDL。我有一个CPU,它的内存位置是无符号的,而偏移值是有符号的。
architecture Behavioral of adder16 is
signal temp: std_logic_vector (16 downto 0);
begin
eval: process(vectA,vectB,temp)
begin
temp <=(('0'& vectB) + (vectA(15) & vectA));
output <= temp( 15 downto 0);
end process;
end Behavioral;
https://stackoverflow.com/questions/8053053
复制相似问题