# Two's complement

**Two's complement**

You are encouraged to solve this task according to the task description, using any language you may know.

Two's complement is an important concept in representing negative numbers. To turn a positive integer negative, flip the bits and add one.

- Task

Show how to calculate the two's complement of an integer. (It doesn't necessarily need to be a 32 bit integer.)

## 6502 Assembly[edit]

### 8-Bit[edit]

```
LDA #%01010101
EOR #255
CLC
ADC #1 ;result: #%10101011
```

### 16-bit[edit]

```
myVar equ $20
LDA #3
STA myVar
LDA #0
STA myVar+1 ;equivalent C: uint16_t myVar = 3;
negate:
LDA myVar+1
EOR #255
STA myVar+1
LDA myVar
EOR #255
STA myVar
CLC
ADC #1
STA myVar
;this handles the case if we started with something where the low byte was zero.
LDA myVar+1
ADC #0
STA myVar+1
```

## 68000 Assembly[edit]

```
MOVE.L #3,D0
NEG.L D0 ;D0 = #$FFFFFFFD
```

## 8086 Assembly[edit]

```
mov al,17
neg al ;8-bit
mov bx,4C00h
neg bx ;16-bit
```

## ALGOL 68[edit]

Algol 68 uses whatever representation the hardware the program is running on uses, which is almost certainly two's complement. So, as in C and most other languages, `-a`

two's complements `a`

. Using Algol 68's bit manipulation facilities, we can explicitely two's complement a positive integer, as shown in this example.

Note: BIN a converts a to a BITS (bit-string) value, the NOT operator will flip the bits and the ABS operator will convert back to an integer, so `1 + ABS NOT BIN a`

is a long-winded alternative to `-a`

. Note in Algol 68, the BIN operator cannot be applied to negative integers, so `1 + ABS NOT BIN -3`

won't work.

```
BEGIN
INT a := 3;
print( ( -a, " ", 1 + ABS NOT BIN a, newline ) )
END
```

- Output:

-3 -3

## ALGOL W[edit]

```
begin
integer a;
a := 3;
write( i_w := 1, s_w := 1, -a, 1 + number( not bitstring( a ) ) )
end.
```

- Output:

-3 -3

## ARM Assembly[edit]

```
MOV R0,#0x0000000F
MOV R1,#1
MVN R0,R0 ;flips the bits of R0, R0 = 0xFFFFFFF0
ADD R0,R0,R1 ;R0 = 0xFFFFFFF1
```

## C[edit]

```
int a = 3;
a = -a;
```

## Forth[edit]

Forth uses two's complement internally. One can use the 'base' variable to switch from one base to another.

```
: 2s'complement base @ swap dup negate swap 2 base ! u. u. base ! ;
25 2s'complement
```

- Output:

11001 1111111111111111111111111111111111111111111111111111111111100111 ok

## FreeBASIC[edit]

In FreeBASIC as in C, if a number n is any integer type, then -n is the two's complement of n, with type preserved.

```
Dim As Integer d1 = 2147483648, d2 = 2147483646
Dim As Integer b(1 To ...) = {-d1, -d1+1, -2, -1, 0, 1, 2, d1-2, d1-1}
For i As Integer = 1 To Ubound(b)
Print b(i); " -> "; -b(i)
Next i
Sleep
```

- Output:

0000000000000011 -> 1111111111111101

### inline assembly[edit]

```
Dim As Integer a = &b000011
Dim As Integer a2c, l
#ifdef __FB_64BIT__
l = 16
Asm
mov rax, [a]
neg rax
mov [a2c], rax
End Asm
#else
l = 8
Asm
mov eax, [a]
neg eax
mov [a2c], eax
End Asm
#endif
Print Bin(a, l); " -> "; Bin(a2c, l)
Sleep
```

- Output:

-2147483648 -> 2147483648 -2147483647 -> 2147483647 -2 -> 2 -1 -> 1 0 -> 0 1 -> -1 2 -> -2 2147483646 -> -2147483646 2147483647 -> -2147483647

## J[edit]

J uses twos complement natively:

```
-3
_3
```

We can see this by extracting bits representing the number. In this example, we limit ourselves to 8 bits:

```
(8#2)#:3
0 0 0 0 0 0 1 1
(8#2)#:-3
1 1 1 1 1 1 0 1
```

## Julia[edit]

In Julia as in C, if a number n is any integer type, then -n is the two's complement of n, with type preserved. This is true even if n is unsigned.

## Perl[edit]

```
use strict;
use warnings;
for ( -2**31, -2**31+1, -2, -1, 0, 1, 2, 2**31-2, 2**31-1 ) {
printf "$_ -> %d\n", $_ == 0 ? 0 : ~$_+1
}
```

Output is the same as the Wren entry.

## Phix[edit]

### inline assembly[edit]

without js integer a = 0b000011, a2c #ilASM{ [32] mov eax,[a] neg eax mov [a2c],eax [64] mov rax,[a] neg rax mov [a2c],rax } printf(1,"%032b -> %032b\n",{a,a2c})

- Output:

00000000000000000000000000000011 -> 11111111111111111111111111111101

### normal hll[edit]

with javascript_semantics integer a = 0b000011 printf(1,"%032b -> %032b\n",{a,-a})

Same output (naturally the rhs is twice as long under 64 bit, in both cases)

## PL/M[edit]

... under CP/M (or an emulator)

Even though the original PL/M 8080 compiler only handles unsigned integers, `-A`

two's complements `A`

.

```
100H: /* TWO'S COMPLEMENT *?
/* CP/M BDOS SYSTEM CALL */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;END;
/* CONSOLE OUTPUT ROUTINES */
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
PR$HEX: PROCEDURE( B ); /* PRINTS B AS A 2 DIGIT HEX NUMBER */
DECLARE B BYTE;
DECLARE D BYTE;
IF ( D := SHR( B, 4 ) ) > 9 THEN CALL PR$CHAR( ( D - 10 ) + 'A' );
ELSE CALL PR$CHAR( D + '0' );
IF ( D := B AND 0FH ) > 9 THEN CALL PR$CHAR( ( D - 10 ) + 'A' );
ELSE CALL PR$CHAR( D + '0' );
END PR$HEX ;
DECLARE A BYTE;
A = 1;
CALL PR$HEX( A );
CALL PR$CHAR( ' ' );
A = -A;
CALL PR$HEX( A );
CALL PR$NL;
EOF
```

- Output:

01 FF

## Quackery[edit]

Ways of calculating the two's complement of an integer in Quackery include `negate`

, `~ 1+`

, `-1 *`

, and `0 swap -`

.

These are demonstrated as a dialogue in the Quackery shell.

/O> 37 negate ... Stack: -37 /O> negate ... Stack: 37 /O> ~ 1+ ... Stack: -37 /O> ~ 1+ ... Stack: 37 /O> -1 * ... Stack: -37 /O> -1 * ... Stack: 37 /O> 0 swap - ... Stack: -37 /O> 0 swap - ... Stack: 37 /O>

## Raku[edit]

By default Rakus integers are arbitrary sized, theoretically of infinite length. You can't really take the twos complement of an infinitely long number; so, we need to specifically use fixed size integers.

There is a module available from the Raku ecosystem that provides fixed size integer support, named (appropriately enough.) FixedInt.

FixedInt supports fixed bit size integers, not only 8 bit, 16 bit, 32 bit or 64 bit, but *ANY* integer size. 22 bit, 35 bit, 191 bit, whatever.

Here we'll demonstrate twos complement on a 57 bit integer.

```
use FixedInt;
# Instantiate a new 57(!) bit fixed size integer
my \fixedint = FixedInt.new: :57bits;
fixedint = (2³⁷ / 72 - 5¹⁷); # Set it to a large value
say fixedint; # Echo the value to the console in decimal format
say fixedint.bin; # Echo the value to the console in binary format
fixedint.=C2; # Take the twos complement
say fixedint; # Echo the value to the console in decimal format
say fixedint.bin; # Echo the value to the console in binary format
```

- Output:

144114427045277101 0b111111111111111110100111011001111000010101110110110101101 761030578771 0b000000000000000001011000100110000111101010001001001010011

## RPL[edit]

RPL can handle integers whose size can be set from 1 to 64 bits. For this task, a 8-bit size is selected with `STWS`

.
RPL considers 'true' integers (i.e. declared by the prefix `#`

) to be positive, so the two's complement can not be done by the `NEG`

instruction.

8 STWS BIN #3d NOT 1 +

- Output:

1: #11111101b

## Wren[edit]

Strictly speaking, Wren doesn't have integers. Instead all numbers are 'IEEE 754' 64 bit floating point values (their underlying C type being *double*) and negative numbers are therefore represented using the *offset binary* method rather than *two's complement*.

This is illustrated by running the following code:

```
var a = 0
a = -a
System.print(a) // -0
```

which produces 'negative zero' rather than just 'zero'.

However, when using the bitwise operators, Wren's VM emulates the corresponding operation in C by first converting the operands to *unsigned* 32 bit values, performing the operation and then converting the result back to a double.

We can therefore emulate how two's complement works on *signed* 32 bit integers by using the bitwise complement operator **~** to flip the bits as follows:

```
var pow32 = 2.pow(32)
var pow31 = 2.pow(31)
var bs = [-pow31, -pow31+1, -2, -1, 0, 1, 2, pow31-2, pow31-1]
for (b in bs) {
var b2 = ~b + 1
if (b2 > pow31) b2 = b2 - pow32
System.print("%(b) -> %(b2)")
}
```

- Output:

-2147483648 -> 2147483648 -2147483647 -> 2147483647 -2 -> 2 -1 -> 1 0 -> 0 1 -> -1 2 -> -2 2147483646 -> -2147483646 2147483647 -> -2147483647

## XPL0[edit]

```
int I; char C;
[I:= 123;
I:= (~I) + 1;
IntOut(0, I); CrLf(0);
C:= -123;
C:= ~(C-1);
IntOut(0, C); CrLf(0);
]
```

- Output:

-123 123

## Z80 Assembly[edit]

### 8-Bit[edit]

**Zilog Z80**

```
ld a,%00001111
neg ;returns %11110001 in a
```

**Game Boy**

```
ld a,%00001111
cpl ;game boy doesn't have NEG but it has CPL which flips all the bits.
inc a ;returns %11110001 in a
```

### 16 Bit[edit]

`NEG`

and `CPL`

only work on the accumulator `A`

.
The following can be written to work with `BC`

, `DE`

, `HL`

, `IX`

, or `IY`

.

```
xor a ;ld a,0
sub c
ld c,a
sbc a ;loads &FF into A if "sub c" set the carry (borrow) flag. Otherwise, a remains zero.
sub b
ld b,a
```