Which arithmetic operations are the same on unsigned and two's complement signed numbers?
Asked Answered
T

3

7

I'm designing a simple toy instruction set and accompanying emulator, and I'm trying to figure out what instructions to support. In the way of arithmetic, I currently have unsigned add, subtract, multiply, and divide. However, I can't seem to find a definitive answer to the following question: Which of the arithmetic operators need signed versions, and for which are the unsigned and two's complement signed versions equivalent?

So, for example, 1111 in two's complement is equal to -1. If you add 1 to it and pretend that it's an unsigned number , you get 0000, which is correct even when thinking of it as -1. However, does that hold for all numbers? And what about for the other three operations (subtraction, multiplication, division)?

Theological answered 31/1, 2014 at 8:16 Comment(1)
C
2

Add and subtract are the same for signed and unsigned 2s complement, assuming you're going to handle overflow/underflow in the normal way for most CPUs, i.e. just wrap around. Multiply and divide are different. So you only need one addition routine and one subtraction routine regardless of signedness, but you need separate signed and unsigned multiply and divide.

Convertite answered 31/1, 2014 at 8:19 Comment(3)
Non-widening multiplication result is the same for both signed and unsigned typesAnaleptic
The idea of non-widening multiplication is very foreign to me (with an FPGA/hardware background). So this answer is more relevant to my normal uses than the other answers.Insalubrious
Most regular compiled programming languages don't have a "widening multiply" per-se, if you want a widening multiply you have to widen first and than multiply and hope the optimiser optimises that to a widening multiply.Dispraise
D
6

Addition, subtraction and multiplication are the same provided:

  1. Your inputs and outputs are the same size
  2. Your behaviour on overflow is wraparound modulo 2n

Division is different.

Many instruction sets offer multiplication operations where the output is larger than the input, again these are different for signed and unsigned.

Furthermore if you are writing your emulator in C there are some misfeatures of the language that you need to be aware of.

  1. Overflow of signed arithmetic in C is undefined behaviour. To get reliable modulo 2n behaviour arithmetic must be performed using unsigned types.
  2. C will promote types smaller than int to int. Great care is needed to avoid such promotions (adding 0u or multiplying by 1u at the start of your calculation is one way).
  3. Conversion from unsigned types to signed types is implementation defined, the implementations i've seen do the sensible thing but there may be some that don't.
Dispraise answered 2/3, 2018 at 13:37 Comment(0)
C
2

Add and subtract are the same for signed and unsigned 2s complement, assuming you're going to handle overflow/underflow in the normal way for most CPUs, i.e. just wrap around. Multiply and divide are different. So you only need one addition routine and one subtraction routine regardless of signedness, but you need separate signed and unsigned multiply and divide.

Convertite answered 31/1, 2014 at 8:19 Comment(3)
Non-widening multiplication result is the same for both signed and unsigned typesAnaleptic
The idea of non-widening multiplication is very foreign to me (with an FPGA/hardware background). So this answer is more relevant to my normal uses than the other answers.Insalubrious
Most regular compiled programming languages don't have a "widening multiply" per-se, if you want a widening multiply you have to widen first and than multiply and hope the optimiser optimises that to a widening multiply.Dispraise
U
-1

All your operations need overflow checks, or they will return incorrect values in some cases. The unsigned versions of these checks are different from the signed ones, so you'll need to implement each routine separately.

Ultramicroscope answered 31/1, 2014 at 8:20 Comment(2)
Since this is an instruction set emulator I would expect that integer overflow/underflow would behave in the usual way, i.e. wrap around modulo 2^N, so addition and subtraction would be the same for both signed and unsigned.Convertite
The way real instruction sets usually handle this is by having multiple flags that can be used to detect different types of overflow.Dispraise

© 2022 - 2024 — McMap. All rights reserved.