# Why does “\$(( ~33 ))” produce -34?

``````\$ echo \$(( 255 ))
255
\$ echo \$(( 33 ))
33
\$ echo \$(( ~33 ))
-34
\$ echo \$(( ~255 ))
-256
\$
``````

and my kernel is:

``````\$ uname -a
Linux HOSTNAME 3.2.0-40-generic-pae #64-Ubuntu SMP Mon Mar 25 21:44:41 UTC 2013 i686 i686 i386 GNU/Linux
``````

QUESTION: `~` is for negating the number AFAIK. But why does `~33` produce `-34` and why does `~255` produce `-256`?

-
Bitwise negation, not to be confused with arithmetic negation (-x) – chepner May 10 '13 at 19:31

The man page of bash says:

``````   ! ~    logical and bitwise negation
``````

Signed numbers are usually stored in Two's complement representation:

``````...
-4 = 1100
-3 = 1101
-2 = 1110
-1 = 1111
0 = 0000
1 = 0001
2 = 0010
3 = 0011
...
``````

This means if you take a number like 2 it is bitwise interpreted as 0010. After bitwise negation this becomes 1101, which is the representation of -3.

-

This is the result of two's complement arithmetic.

`~` is a bitwise negation that inverts all of the bits being operated upon. Two's complement arithmetic works by inverting all of the bits and adding 1. Since you have only flipped the bits, but not added one, you get the same number, inverted, minus one.

Wikipedia has a good article on two's complement here.

As an example:

• 3 in binary is `0011`
• -3 in (two's complement) binary is `1101`
• Inverting `0011` gives you `1100`, which is -4, since you haven't added 1.
-
this one is a good answer too, Thanks! – gasko peter May 9 '13 at 6:47

The ~ operator is the bitwise NOT operator. Using it is not the same as negating a number.

From wikipedia, a bitwise NOT operation is equal to taking the two's complement of the value minus one:

NOT x = −x − 1

Negating a number => take its two-complement value.

Using the ~ NOT operator = take its one-complement value.

In simpler terms, ~ just flips all the bits of the binary representation.

33 (decimal) = 0x00100001 (8-bit binary)

~33 = ~0x00100001 = 0x11011110 = -34 (decimal)

Or in decimal arithmetics, using the ~x = x - 1 formula:

~33 = -33 - 1 = -34

and

~255 = -255 - 1 = -256

-

You can convert the answer back into something sensible

result_in_hex=\$(printf "%x" \$(( ~ 0x33 )))

-