Binary for Programmers

Binary is a bit more complex than just adding up powers of 2.  In Java, you can declare an int (integer) variable to store whole numbers.  But it can also store negative whole numbers.  

Java int stores a 32-bit signed integer.  It looks like this in binary:

     1010 1100 1111 1111 0000 0000 0101 1111 bin  =  AC FF 00 5F  hex

It is easier to read in hexadecimal, but that still doesn't explain the negative numbers.

That is pretty overwhelming, so we will work with byte values in the examples below.  A Java byte is like an int, but only 8 bits.  

Negative Numbers

Scientists need negative numbers as well as positive ones, so we need a way to store negative values. We need to make it possible to have both positive and negative values, probably equal amounts of each.  Realizing that 8 bits can be used to store 256 different bit patters (2^8), we'd like to have 128 positive numbers and 128 negative numbers.

Sign and Magnitude

The simplest way to represent negative numbers is to sacrifice one of the bits and use it to represent the sign (sign-bit).  That leaves 7 other bits to store the magnitude (size) of the number.  Here are some examples:

Binary

Decimal

0 000 1010

+ 10

1 000 1010

-10

1 111 1111

-127

1 010 1010

- 42

0 000 0000

0

1 000 0000

- 0

This is easy to understand, but unfortunately it has two different ways for writing zero (0).  That is a bit of a waste and rather confusing.  This system was used back in the 1950's and 1960's, but since then a different system has become popular.

Two's Complement

Modern computers all use the two's complement system for storing integers in binary.  This system is a bit mysterious from the human perspective, but it makes it quite easy to create circuits that do binary arithmetic correctly.  It works like this:

Here are some examples:

Bits

Calculation

Decimal

 0 000 1111

8 + 4 + 2 + 1

15

 1 000 1111

-128 + 8 + 4 + 2 + 1

 -113

 0 111 1111

64 + 32 + 16 + 8 + 4 + 2 + 1

 127

 1 000 0000

 -128 + 0

 -128

 1 111 1111

-128 + 64 + 32 + 16 + 8 + 4 + 2 + 1

 -1

10101010

-128 + 32 + 8 + 2

-86

 32 Bits

What happens with REAL int numbers, like the 32-bit int values in Java?  It works "the same" as 8 bit numbers, but the sign-bit is at the front (MSB = most significant bit), so it isn't worth -128 anymore. Instead, it has a BIG value of -(2^31), whatever that is!  But the same basic ideas apply:

Bits

Calculation

Decimal

 00000000 00000000 00000000 00001111

8 + 4 + 2 + 1

15

 01111111 11111111 11111111 11111111

1 + 2 + 4 + ..... + 2^30

Biggest positive num

10000000 00000000 00000000 00000000

-2^31

Biggest negative num

11111111 11111111 11111111 11111111

-2^31 + 2^30 + 2^ 29 ...

 -1

 00000000  00000000  00000000  00000000

 0

 0

What does that mean for programmers?

In a RandomAccessFile, an int value is stored in 4 bytes (32 bits).   The biggest possible positive int is 2^31-1.  After that comes 10000000000000000000000000000000.  That is a HUGE negative number.  So whenever you produce a really big positive int, it is likely to turn into a negative number, thus becoming useless.  And if a hacker tries to hex-edit a really big int into a bank account by typing:

                                FFFF

then that number will be interpreted as -1, because it's: 1111 1111 1111 1111 1111 1111 1111 1111.  Too bad for the hacker!