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.
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
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
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:
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 are0,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:
Thus, in hexadecimal arithmetic, we could write
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.
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
Sian Mountbatten 2012-01-19