加法器如何执行无符号整数减法?

发布于 2024-12-14 07:51:18 字数 500 浏览 4 评论 0原文

假设AB是有符号正整数,那么对于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 have
7-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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

缱倦旧时光 2024-12-21 07:51:18

在相关问题的此答案中,有 C 语言的示例代码这展示了如何通过加法进行减法。该代码还设置进位和溢出标志,并包含一个简单的“测试”,用于添加和减去一些数字并打印结果。这些数字是 8 位的。

编辑:正式证明,可以对无符号整数使用 ADD 而不是 SUB AND 发现无符号上溢/下溢,就像来自 SUB 一样。

假设我们要计算 a - b,其中 ab 是 4 位无符号整数,我们希望通过加法和减法来执行减法当 a < 时,获得 4 位差异和下溢/溢出指示b.

a - b = a + (-b)
由于我们采用模 16 算术运算,因此 -b = 16-b。所以,
a - b = a + (-b) = a + (16 - b)

如果我们执行 a16-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 >= ba <= 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, where a and b 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 and 16-b the overflow condition for this addition, which is often indicated by the CPU in its carry 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 adding a and (16)-b is the inverse of the subtraction overflow, or, in other words, the inverse of the borrow flag you'd get by subtracting b directly from a using the appropriate subtraction instruction (e.g. SUB).

Just invert the carry or treat it in the opposite way.

╰◇生如夏花灿烂 2024-12-21 07:51:18

你的分析不正确。实际上是 CPU ALU 单元相关的。 :)

在第一种情况下,您使用的是 4 位整数,但您忘记了 4 位符号整数的最高位是 sign!因此,您仅检查进位和溢出状态,而不检查状态位。

一般来说,二进制算术运算对于有符号整数和无符号整数来说,addsub 是相同的。只有受影响的标志不同。

实际上你必须考虑:

  • 在有符号整数算术中进位溢出标志。
  • 在无符号整数算术中仅进位标志。

详细说明:

补函数的挖掘是求反,即从正数中得到相反的负数,从负数中得到正数。我们可以通过两种方式进行二进制补码。让我们看看数字 3 的两种情况

  1. 。无符号算术是 compl (3) = b'0011' xor b'1111' + b'0001' =
    b'1101' + 进位(仅在 compl (0) 时设置进位)
  2. 对于有符号算术数,符合 (3) = b'10000' - b'0011' = b'1101'什么
    等于 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:

  • at signed integer arithmetic Carry, Overflow and Negative flags.
  • at unsigned integer arithmetic only Carry flags.

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.

  1. At unsigned arithmetic is compl (3) = b'0011' xor b'1111' + b'0001' =
    b'1101' + Carry (Carry is set only at compl (0))
  2. At signed arithmetic numbers is comply (3) = b'10000' - b'0011' = b'1101' what
    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.

傾城如夢未必闌珊 2024-12-21 07:51:18

这有点难以理解,但是......我有一些 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;

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.

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;
韵柒 2024-12-21 07:51:18

你的分析是正确的。

使用

溢出 = EXOR(执行,添加'/SUB)

确定单解释的无符号加法和无符号减法(使用 2 的补码加法)的溢出。

在无符号加法中,溢出表示为

执行 = 1

正确结果由下式表示

执行 = 0

但是

添加'/SUB = 0

用于加法

因此无论如何溢出由 1 表示。

类似地

在无符号减法中溢出由

执行 = 0

正确结果由下式表示

执行 = 1

但是

添加'/SUB = 1

用于减法

因此无论如何溢出都由 1 表示。

因此,我们可以对无符号加法和无符号减法中的溢出进行单一解释。

Your analysis is correct.

Use

OVERFLOW = EXOR ( CARRY OUT , ADD'/SUB )

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

CARRY OUT = 1

Correct result is indicated by

CARRY OUT = 0

But

ADD'/SUB = 0

is for addition

So anyway overflow is indicated by 1.

Similarly

In unsigned subtraction overflow is indicated by

CARRY OUT = 0

Correct result is indicated by

CARRY OUT = 1

But

ADD'/SUB = 1

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文