I was teaching a Java programming course recently, and I found that a few delegates didn’t know how numbers are represented internally in computer memory.

Depending on where you work, you may or may not need to know much about the bits and bytes that make up the numbers you use in your program. However, the more knowledge you have, the better your code will be. And that knowledge will be especially useful during debugging when you’re trying to figure out why you’re getting those unexpectedly odd results.

So in the next few posts, we’ll look at numbering systems, as well as integral and floating point number representations, and a few of the surprising problems with numbers in computer programs.

Let’s review numbering systems in general.

## Positional and Non-positional Numbering Systems

We need a system to represent numbers. This is done by using numeric symbols (*digits*) in various ways. We can categorise numbering systems in two ways:

### Positional numbering systems

In a positional numbering system, the actual value of any digit depends on its position within the number. For example, the 2 in 20 has a different value to the 2 in 2000. All positional numbering systems work on the same principle. The *base* (or radix) of a numbering system determines the range of digits that are allowed in each position. A digit is carried over to the next column (position) on the left as soon as the value is equal to or greater than the base of the numbering system. The decimal numbering system that we use every day uses a base of 10. Computer science uses base 2 (binary), base 8 (octal) and base 16 (hexadecimal).

### Non-positional numbering systems

Non-positional numbering systems are not very common. These systems use a character to specify a value. That character always has the same value regardless of where it occurs in the number. The best known example is Roman numbering. An I always means 1, a V means 5, an X means 10, an L 50, a C 100, a D 500 and an M 1000. So the Roman number `MDLXVII`

has the value of `1567`

.

## Decimal Numbering System

We already understand the decimal number system, because we use it every day. The decimal number system uses base 10, and consists of the digits `0`

, `1`

, `2`

, `3`

, `4`

, `5`

, `6`

, `7`

, `8`

and `9`

.

The decimal number `5289`

can be used to illustrate the concept of positional notation.

`5289 = (5 x 10`^{3}) + (2 x 10^{2}) + (8 x 10^{1}) + (9 x 10^{0})

For each position, the digit is multiplied by the base of the system to a particular power. The power is determined by the position, starting from 0 on the extreme right.

## Binary Numbering System

Remember that the components of a computer can be in one of two states: `ON`

or `OFF`

. This is why the binary number system is used in computer science: `1`

represents `ON`

, and `0`

represents `OFF`

. Each binary digit (`0`

or `1`

) is referred to as a *bit*. All data, whether numbers, alphabetical characters or instructions, is represented in the computer in terms of bits.

The binary number system uses base 2, and consists only of the digits `0`

and `1`

.

We can calculate the decimal value of the binary number `1011`

as follows:

`101011`_{2} = (1 x 2^{5}) + (0 x 2^{4}) + (1 x 2^{3}) + (0 x 2^{2}) + (1 x 2^{1}) + (1 x 2^{0})
= (1 x 32) + (0 x 16) + (1 x 8) + (0 x 4) + (1 x 2) + (1 x 1)
= 32 + 0 + 8 + 0 + 2 + 1
= 43

We can convert from decimal to binary by repeatedly dividing by the base of `2`

until the answer is `0`

or `1`

, and keeping the remainder each time. These remainders, in inverse order, give the binary digits of the number.

## Octal Numbering System

The octal number system works with base 8. It uses the digits `0`

, `1`

, `2`

, `3`

, `4`

, `5`

, `6`

, and `7`

.

We can calculate the decimal value of the octal number `234`

as follows:

`234`^{8} = (2 x 8^{2}) + (3 x 8^{1}) + (4 x 8^{0})
= (2 x 64) + (3 x 8) + (4 x 1)
= 128 + 24 + 4
= 156

We can convert from decimal to octal by repeatedly dividing by `8`

until the answer is an allowed digit, and keep the remainder each time. These remainders, in inverse order, give the octal digits of the number.

## Hexadecimal Numbering System

The hexadecimal number system works with base 16. It uses the digits `0`

, `1`

, `2`

, `3`

, `4`

, `5`

, `6`

, `7`

, `8`

, `9`

, `A`

, `B`

, `C`

, `D`

, `E`

and `F`

. The letter `A`

represents the decimal value `10`

, `B`

represents the decimal value `11`

and so on to `F`

, which represents the decimal value of `15`

.

We can calculate the decimal value of the hexadecimal number `1AD`

as follows:

`1AD`_{16} = (1 x 16^{2}) + (10 x 16^{1}) + (13 x 16^{0})
= (1 x 256) + (10 x 16) + (13 x 1)
= 256 + 160 + 13
= 429

We can convert from decimal to hexadecimal by repeatedly dividing by `16`

until the answer is an allowed digit, and keeping the remainder each time. These remainders, in inverse order, give the digits of the number.

## Converting Between Binary, Octal and Hexadecimal

There is a natural relationship between binary, octal and hex: `2`

and ^{3} = 8`2`

.^{4} = 16

This makes it easy to convert between these numbers.

### Converting Between Binary and Octal

Each octal digit can be represented by 3 binary digits: `23 = 8`

.

We can easily convert from binary to octal by grouping the binary digits in threes, beginning at the extreme right.

Example:

`10001001`_{2} = 010 001 001 = 2 1 1 = 211_{8}

To convert from octal to binary, write down the binary equivalent (using 3 positions) for each octal digit:

Example:

`253`_{8} = 010 101 011 = 10101011_{2}

### Converting Between Binary and Hexadecimal

Each hexadecimal digit can be represented by 4 binary digits: `2`

.^{4} = 16

We can easily convert from binary to hexadecimal by grouping the binary digits in fours, beginning at the extreme right.

Example:

`10001001`_{2} = 1000 1001 = 8 9 = 89_{16}

To convert from hexadecimal to binary, write down the binary equivalent (using 4 positions) for each hexadecimal digit:

Example:

`F3`_{16} = 1111 0011 = 11110011_{2}

To convert between octal and hexadecimal, use the binary system as an intermediary, i.e. first convert to binary and then regroup to convert to the other number system.

## Signing Off

In the next post we’ll look into how whole (integral) numbers are represented in computer memory. We’ll review how negative numbers are represented in one’s complement and two’s complement arithmetic.

Was this useful? Please share your comments, and as always, stay safe and keep learning!