# 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.

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

## 6502 Assembly

### 8-Bit

```LDA #%01010101
EOR #255
CLC

### 16-bit

```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
STA myVar
;this handles the case if we started with something where the low byte was zero.
LDA myVar+1
STA myVar+1```

## 68000 Assembly

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

## 8086 Assembly

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

## ALGOL 68

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

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

## ARM Assembly

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

## C

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

## Delphi

Works with: Delphi version 6.0

```procedure TwosCompliment(Memo: TMemo);
var N: integer;
begin
N:=123456789;
N:=(N xor \$FFFFFFFF)+1;
end;
```
Output:
```N= 123456789 \$075BCD15

N:=(N xor \$FFFFFFFF)+1

N=-123456789 \$F8A432EB
Elapsed Time: 5.206 ms.
```

## Forth

Works with: gforth version 0.7.3

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

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

```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

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
```

## Jakt

```fn main() {
let n = 0xabcdeabcdeu64
println("{:064b}", n)
println("{:064b}", ~n + 1)
println("{:064b}", -n) // Same result
}```
Output:
```0000000000000000000000001010101111001101111010101011110011011110
1111111111111111111111110101010000110010000101010100001100100010
1111111111111111111111110101010000110010000101010100001100100010
```

## Julia

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.

## Nim

We define a function to compute the two’s complement by taking the logical complement and adding one. As Nim uses the native complement of the computer, which is two’s complement, the result should be equal to the arithmetic negation.

```import std/[strformat, strutils]

func twosComplement[T: SomeSignedInt](n: T): T =
## Compute the two's complement of "n".
not n + 1

echo &"""{"n":^15}{"2's complement":^15}{"-n":^15}"""
for n in [0i32, 1i32, -1i32]:
echo &"{n.toHex:^15}{twosComplement(n).toHex:^15}{(-n).toHex:^15}"
for n in [-50i8, 50i8]:
echo &"{n.toHex:^15}{twosComplement(n).toHex:^15}{(-n).toHex:^15}"
```
Output:
```       n       2's complement       -n
────────    ──────────────    ────────
00000000       00000000       00000000
00000001       FFFFFFFF       FFFFFFFF
FFFFFFFF       00000001       00000001
CE             32             32
32             CE             CE
```

## Perl

```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

### inline assembly

```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

```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

Works with: 8080 PL/M Compiler
... 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

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

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

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

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

```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

### 8-Bit

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

`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
```