ZetCode

Algol 68 complex numbers

last modified November 13, 2026

The mode COMPL holds a complex number, a pair of reals that the language treats as one value. The arithmetic operators are defined for it, and the prelude adds the procedures that read the two parts and the properties of the number. This article describes how a complex value is built, printed, and used in calculations.

Building a complex value

A complex value is written as a display of two reals, in the order real part and imaginary part. The display may be prefixed with COMPL, and a plain real widens to a complex number with a zero imaginary part.

basic.a68
BEGIN
  COMPL z = COMPL(3.0, 4.0);
  print((z, newline));
  print((fixed(re OF z, 0, 1), " ", fixed(im OF z, 0, 1), newline));
  print((fixed(ABS z, 0, 1), newline));
  print((fixed(ARG z, 0, 3), newline))
END

The first line shows the default output of a complex value, which prints each part in the default real format, so the article uses the parts instead. re OF and im OF select the real and imaginary parts, ABS gives the modulus, and ARG gives the argument in radians. For 3 and 4 the modulus is 5 and the argument is about 0.927.

$ a68g basic.a68
+3.00000000000000e  +0+4.00000000000000e  +0
3.0 4.0
5.0
.927

A printing procedure

Because the default form is hard to read, a program that prints complex numbers usually writes a small procedure. The parts are printed with fixed, which gives a uniform number of decimals.

show.a68
PROC show = (COMPL z) VOID:
  print(("(", fixed(re OF z, 0, 2), ", ", fixed(im OF z, 0, 2), ")", newline));

BEGIN
  show(COMPL(3.0, 4.0));
  show(COMPL(0.0, -1.5))
END

The procedure prints the pair in parentheses, in the same order in which the display is written. The second call shows a negative imaginary part, and the zero real part is printed as .00, because a field of zero characters before the point drops the leading zero.

$ a68g show.a68
(3.00, 4.00)
(.00, -1.50)

Arithmetic

The four operators +, -, *, and / work on complex numbers with the usual rules, and a real operand may be mixed with a complex one. The result always has mode COMPL.

arith.a68
PROC show = (COMPL z) VOID:
  print(("(", fixed(re OF z, 0, 2), ", ", fixed(im OF z, 0, 2), ")", newline));

BEGIN
  COMPL a = COMPL(1.0, 2.0), b = COMPL(3.0, -1.0);
  show(a + b);
  show(a - b);
  show(a * b);
  show(a / b)
END

Addition and subtraction work on the two parts separately, giving (4, 1) and (-2, 3). Multiplication multiplies the parts in the way that produces -1 from i * i, and the product here is (5, 5). Division multiplies both parts by the conjugate of the divisor, which gives (0.1, 0.7).

$ a68g arith.a68
(4.00, 1.00)
(-2.00, 3.00)
(5.00, 5.00)
(.10, .70)

Powers and real operands

The power operator accepts an integer exponent, and a real may take part in a formula with a complex value. The real is widened before the operation, so the imaginary part of the result follows from the arithmetic.

pow.a68
PROC show = (COMPL z) VOID:
  print(("(", fixed(re OF z, 0, 2), ", ", fixed(im OF z, 0, 2), ")", newline));

BEGIN
  COMPL z = COMPL(1.0, 1.0);
  show(z ** 2);
  show(z + 1.0)
END

Squaring 1 + i gives 2i, because the two imaginary products contribute -1 and the real parts contribute 1. Adding the real 1 changes only the real part, which becomes 2. The same widening happens in a comparison, in an argument, and in an initialiser.

$ a68g pow.a68
(.00, 2.00)
(2.00, 1.00)

The conjugate

CONJ returns the complex conjugate, which has the same real part and the negated imaginary part. Multiplying a number by its conjugate gives a real value, the square of the modulus.

conj.a68
PROC show = (COMPL z) VOID:
  print(("(", fixed(re OF z, 0, 2), ", ", fixed(im OF z, 0, 2), ")", newline));

BEGIN
  COMPL z = COMPL(3.0, 4.0);
  show(CONJ z);
  show(z * CONJ z)
END

The conjugate of 3 + 4i is 3 - 4i, and the product is 25 with no imaginary part. CONJ is a monadic operator, so it applies to the following operand; the call passes the whole result to show. The modulus printed earlier was the square root of this product.

$ a68g conj.a68
(3.00, -4.00)
(25.00, .00)

Equality

Complex numbers compare with = and /=, and both parts have to be equal. There is no ordering, because the complex numbers have no natural order that the comparison could follow.

equal.a68
BEGIN
  COMPL a = COMPL(1.0, 2.0), b = COMPL(1.0, 2.0), c = COMPL(2.0, 1.0);
  print((a = b, " ", a = c, " ", a /= c, newline))
END

The first two values have the same parts in the same order and compare equal, while c has them swapped and compares different. Writing a < c is a compile error about an undeclared operator, which is how the language keeps the comparison honest.

$ a68g equal.a68
T F T

Rows of complex numbers

COMPL is an ordinary mode for a row, so a row may hold a sequence of complex values. The elements are multiplied and printed with the procedure from the previous sections.

row.a68
PROC show = (COMPL z) VOID:
  print(("(", fixed(re OF z, 0, 2), ", ", fixed(im OF z, 0, 2), ")", newline));

BEGIN
  []COMPL corners = (COMPL(1.0, 1.0), COMPL(-1.0, 1.0), COMPL(-1.0, -1.0), COMPL(1.0, -1.0));
  FOR i TO UPB corners DO
    show(corners[i] * corners[i])
  OD
END

The four values are the corners of the unit square in the complex plane, and squaring each one gives a value on the imaginary axis. The loop walks the row with the bounds read from the row itself, so the same code works for a longer sequence.

$ a68g row.a68
(.00, 2.00)
(.00, -2.00)
(.00, 2.00)
(.00, -2.00)

Next steps

The modes article lists COMPL with the other numeric modes, and coercions explains the widening from REAL to COMPL. The bits article describes the other non-decimal mode, and strings shows how numbers become text.

Source

Revised Report on the Algorithmic Language Algol 68

The Algol 68 Genie project

In this article we have built complex values from two reals, read their parts with re OF and im OF, computed the modulus and the argument, printed the values with a procedure, added, subtracted, multiplied and divided them, raised one to a power, mixed a real into the arithmetic, taken a conjugate, compared complex values, and stored them in a row. The bits article continues with bit patterns.

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.