ZetCode

Algol 68 bits

last modified November 13, 2026

The mode BITS holds a fixed-width pattern of bits. A program uses it for flags, masks, and the low-level representation of numbers, and the language provides the boolean operations, the shifts, and the conversions between a pattern and an integer. This article describes those operations and a procedure that prints a number in binary.

Bit patterns and based denotations

A based denotation writes a number in a base other than ten, and its value has mode BITS. 2r1010 is a binary pattern, 16rff a hexadecimal one, and 8r777 an octal one. ABS converts a pattern to the integer it represents.

denot.a68
BEGIN
  BITS a = 2r1010;
  BITS b = 16rff;
  BITS c = 8r777;
  print((whole(ABS a, 0), " ", whole(ABS b, 0), " ", whole(ABS c, 0), newline));
  print((BIN 12, newline))
END

The three patterns represent 10, 255, and 511. BIN goes the other way and converts an integer to a pattern, and printing that pattern shows one character per bit: F for a zero and T for a one. The width belongs to the implementation, and this build prints 32 characters.

$ a68g denot.a68
10 255 511
FFFFFFFFFFFFFFFFFFFFFFFFFFFFTTFF

Printing binary digits

The F and T form is exact but hard to read. A procedure that divides by two and collects the remainders produces the familiar binary notation, without leading zeros.

binary.a68
PROC binary = (INT n) STRING:
  ( STRING s := "";
    INT v := n;
    WHILE v > 0 DO
      s := (IF ODD v THEN "1" ELSE "0" FI) + s;
      v OVERAB 2
    OD;
    IF s = "" THEN "0" ELSE s FI );

BEGIN
  print((binary(10), " ", binary(255), " ", binary(0), newline))
END

ODD tests the last bit, the character is added in front of the result so far, and OVERAB 2 shifts the value right by one place. The loop ends when the value becomes zero, and the special case prints 0 for the input zero. The function is used in the rest of the article to show bit patterns in a readable form.

$ a68g binary.a68
1010 11111111 0

Boolean operations on bits

AND, OR, XOR, and NOT work on bit patterns bit by bit. The result of the first three has mode BITS, so ABS turns it into an integer for printing.

logic.a68
PROC binary = (INT n) STRING:
  ( STRING s := "";
    INT v := n;
    WHILE v > 0 DO
      s := (IF ODD v THEN "1" ELSE "0" FI) + s;
      v OVERAB 2
    OD;
    IF s = "" THEN "0" ELSE s FI );

BEGIN
  BITS a = 2r1100, b = 2r1010;
  print(("and ", binary(ABS (a AND b)), newline));
  print(("or  ", binary(ABS (a OR b)), newline));
  print(("xor ", binary(ABS (a XOR b)), newline))
END

The two patterns share the third bit only, so the conjunction is 1000. The disjunction has every bit that either operand has, and the exclusive or has the bits that differ. The printed values drop leading zeros, which is why the last line shows 110 instead of 0110.

$ a68g logic.a68
and 1000
or  1110
xor 110

Masks

A mask is a pattern with ones in the positions of interest. AND with a mask tests or extracts bits, OR with a mask sets bits, and AND NOT with a mask clears them.

flags.a68
PROC binary = (INT n) STRING:
  ( STRING s := "";
    INT v := n;
    WHILE v > 0 DO
      s := (IF ODD v THEN "1" ELSE "0" FI) + s;
      v OVERAB 2
    OD;
    IF s = "" THEN "0" ELSE s FI );

BEGIN
  BITS flags := 2r0000;
  flags := flags OR 2r0100;
  flags := flags OR 2r0001;
  print((binary(ABS flags), newline));
  IF ABS (flags AND 2r0100) > 0 THEN
    print(("read bit set", newline))
  FI;
  flags := flags AND NOT 2r0100;
  print((binary(ABS flags), newline))
END

Two bits are set one at a time, and the pattern becomes 101. The test isolates the middle bit and compares the result with zero, which is the usual way to ask whether a flag is on. The last assignment clears that bit with a mask that has ones everywhere except at the tested position, so only the lowest bit remains.

$ a68g flags.a68
101
read bit set
1

Shifts

SHL moves the bits of a pattern to the left and SHR moves them to the right. Both take an integer count and yield a pattern, and the vacated positions are filled with zeros.

shifts.a68
BEGIN
  BITS b = 2r0001;
  print((whole(ABS (b SHL 1), 0), " ", whole(ABS (b SHL 4), 0), newline));
  print((whole(ABS (2r1000 SHR 2), 0), newline));
  BITS c := 2r0011;
  c := c SHL 2;
  print((whole(ABS c, 0), newline))
END

One shifted left once is 2 and shifted left four times is 16, which is the same as multiplying by a power of two. Shifting 8 right twice gives 2, the integer division by four. The last part applies the shift to a variable and stores the result back into it.

$ a68g shifts.a68
2 16
2
12

Bits and integers

The bit operations are often used alongside integer arithmetic rather than instead of it. ODD reads the lowest bit of an integer, and the binary procedure turns the result into readable output.

odd.a68
PROC binary = (INT n) STRING:
  ( STRING s := "";
    INT v := n;
    WHILE v > 0 DO
      s := (IF ODD v THEN "1" ELSE "0" FI) + s;
      v OVERAB 2
    OD;
    IF s = "" THEN "0" ELSE s FI );

BEGIN
  []INT numbers = (5, 12, 7, 20);
  FOR i TO UPB numbers DO
    IF ODD numbers[i] THEN
      print((whole(numbers[i], 0), " ", binary(numbers[i]), " odd", newline))
    ELSE
      print((whole(numbers[i], 0), " ", binary(numbers[i]), " even", newline))
    FI
  OD
END

An odd number has a one in its lowest bit, and ODD reports that directly. The same test could be written as ABS (BIN 1 AND BIN n) > 0, but ODD states the intent without a conversion. The four values alternate between the two cases, and the binary text shows the lowest bit that decides them.

$ a68g odd.a68
5 101 odd
12 1100 even
7 111 odd
20 10100 even

Next steps

The literals article covers the based denotations, and operators explains the priorities of AND, OR, and the shifts. The complex numbers article continues with the other numeric mode that has operations of its own.

Source

Revised Report on the Algorithmic Language Algol 68

The Algol 68 Genie project

In this article we have written bit patterns in binary, hexadecimal, and octal, converted them to integers and back, printed numbers in binary, applied AND, OR, XOR, and NOT, used masks to test, set, and clear bits, shifted patterns left and right, and tested integers for oddness. The complex numbers article continues with the arithmetic of the complex mode.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Algol 68 tutorials.