Keywords: pame

Subsections

- Radix arithmetic
- Exercises

# Bits, bytes and words

In our discussion of plain values (values of modes `CHAR`, `INT`, `REAL`, and `BOOL`), we have omitted saying how these values are stored in computer memory for one important reason: Algol 68 is a high-level programming language. A high-level programming language is one in which the concepts of computer programming are not expressed in terms of a computer, its instructions and its memory, but in terms of high-level concepts such as values and modes. Basically, the manner in which integers and characters and so on are stored in the computer are not our business. However, since programs written in Algol 68 need to access the operating system, it is useful to know something about memory, whether the main memory of the computer or the storage memory found on hard disks and other devices.

Computer memory consists of millions of bits (short for binary digits) which are grouped together as bytes or words. A bit can take two values: 0 and 1. A word is 16, 24, 32, 36, 60, 64 or 72 bits "wide", and a byte is 6, 8 or 9 bits "wide". Almost all microcomputers use 8-bit bytes. Microcomputers using the Intel Pentium processor (or compatibles) or later chips, use a 32-bit word and an 8-bit byte. Generally speaking, a byte is used to store a character and a word is used to store an integer. Real numbers are much more complicated than integers and we shall not describe how they are stored in memory. Before we can understand about the equivalences of values of mode `CHAR` and bytes, and values of mode `INT` and words, we need to say something about radix arithmetic. If this is something you already know, please skip the next section.

## Radix arithmetic

Our ordinary arithmetic uses the ten digits 0, 1, ..., 9 and expresses numbers in powers of ten. Thus the number 1896 consists of 1 thousand, 8 hundreds, 9 tens and 6 units. This could be written

1896 = 1×1000 + 8×100 + 9×10 + 6×1

Remembering that 100 is ten squared (102) and 1000 is ten cubed (103), we could rewrite this equation as

    1896=1×103+8×102+9×101+6×100

As you can see, the powers of ten involved are 3, 2, 1 and 0. When we write whole numbers, we understand that the digits we use represent powers of ten. We say that the base, or radix , of our arithmetic is ten, which is why it is frequently referred to as "decimal arithmetic" (decimal is derived from the Latin word for ten).

Now it is quite meaningful to develop an arithmetic having a different radix. For example, suppose we use two as the radix. We should express our numbers in terms of powers of two and they would be written using the digits 0 and 1 only. In an arithmetic of radix two, when we write a number, each digit would represent a power of two. For example, the number 101 would mean

101 = 1×22 +0×21 +1×20

in an exactly analogous way to the number 1896 in decimal arithmetic. In fact, the decimal equivalent of 101 would be 4 + 0 + 1 = 5 (in decimal). Here is another example:

1101=1×23+1×22+0×21+1×20
=8+4+0+1
=13 (`thirteen, in decimal`)

We could then construct addition and multiplication tables as follows:

+ | 0 | 1
0 | 0 | 1
1 | 1 | 10

× | 0 | 1
0 | 0 | 0
1 | 0 | 1

As you can see from the addition table, 1 + 1 = 10 (take row 2 and column 2). When you read this equation, you must say "one-zero" for the number after the equals symbol. "Ten" means ten+zero units which this number definitely is not. The number 10 in radix 2 means "two+0 units" which is what you would expect for the sum of 1 and 1.

Two radices of particular use with computers are sixteen and two. Arithmetic with a radix of sixteen is called hexadecimal and arithmetic with a radix of two is called binary.

In hexadecimal arithmetic, the digits 0 to 9 are used, but digits are also required for the numbers ten to fifteen. The first six letters of the alphabet are used for the latter six numbers. They are commonly written in upper-case, but in Algol 68 they are written in lower-case for a reason which will become apparent in a later section. Thus the "digits" used for hexadecimal arithmetic are
`0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f`

Addition and multiplication tables could be constructed for hexadecimal arithmetic on the same lines as those for radix two arithmetic. You should note that when writing a number containing more than one digit with a radix other than ten, the radix is commonly written (in decimal) as follows:

2×3 = 124

Thus, in hexadecimal arithmetic, we could write

7×9 = 3f16

and there are some exercises at the end of this section in which you can try your hand at hexadecimal and other arithmetics. Writing numbers in hexadecimal is sometimes called "hexadecimal notation".

A byte consists of eight binary digits and can take any value from 000000002 to 111111112. The equivalent decimal value can be obtained by rewriting it as the sum of descending powers of two:

100110112 | = | 1×27 +1×24 +1×23 +1×21 +1×20 |
| = | 128 + 16 + 8 + 2 + 1 (indecimal ) |
| = | 15510 |

The exercises at the end of this section will give you some practice in this kind of conversion.

If you compare the number of digits used to express the same number, you will find that hexadecimal arithmetic uses the least. For example, the decimal number 135 can be written

135 | = | 8716 |
| = | 20134 |
| = | 100001112 |

When converting numbers written in binary to hexadecimal, the simplest way is to split the binary number into two groups of 4 bits and then convert each group into one hexadecimal digit. Thus `00101011` can be split into `0010` and `1011`, and their hexadecimal equivalents are `2` and `b`. If you intend accessing machine words, it would certainly be a good idea to learn the binary equivalents of the 16 hexadecimal digits `0-f`. To help you, here is the procedure `itostr` which converts a positive value of mode `INT` to a value of mode `STRING` (with minimum width) using any radix from 2 to 16:

       []CHAR digits="0123456789abcdef"[@0];

       PROC itostr=(INT n#umber#,r#adix#)STRING:
       IF n < r
       THEN digits[n]
       ELSE itostr(n%r,r)+digits[n MOD r]
       FI

Notice how its recursive definition simplifies the code.

## Exercises

11.1
  Using the procedure `itostr`, write a program which will display the 16 integers between 0 and 15 (decimal) in decimal, hexadecimal and binary (the binary equivalent should be displayed as 4 bits) in three columns. Ans
11.2
  For each of the following, rewrite the number in the given radix: Ans
  (a)
    9410 => 16

  (b)
    1310 => 2

  (c)
    1111 10012 => 16

  (d)
    3e116 => 10

  (e)
    2c16 => 2

  (f)
    101012 => 10

11.3
  Express the value of each of the following using the radix of that exercise: Ans
  (a)
    1012+1102

  (b)
    3516 + ae16

  (c)
    178 +378