Algol 68 big integers
last modified November 14, 2026
An INT in Algol 68 Genie is a 32-bit signed integer, so the
largest value it holds is 2147483647. Factorials, powers, and counts of
combinatorial objects pass that limit quickly. The language answers with the
long modes: LONG INT, LONG LONG INT, and longer
modes still, whose precision is chosen by the program.
This article shows where an ordinary integer stops, how a
LONG LONG INT is declared and printed, how the
PR precision=... PR pragma gives the long modes hundreds of
digits, and how to compute 100 factorial in full.
The limit of an INT
max int is the largest value of the mode INT. One
more than that value cannot be represented, and the interpreter reports an
arithmetic overflow instead of wrapping around to a negative number.
BEGIN
print(("max int = ", whole(max int, 0), newline));
INT n := max int;
print(("one more = ", whole(n + 1, 0), newline))
END
The first line prints, and the second raises
INT math error (numerical result out of range). The running
program stops at that point with exit status 1; the statements after the
failing expression never run. Above the message the interpreter prints the
offending source line and a caret under the expression, which the transcript
below leaves out.
$ a68g overflow.a68
max int = 2147483647
a68g: runtime error: 1: INT math error (numerical result out of range) (detected in [] "SIMPLOUT" collateral-clause starting at "(" in this line).
Long long integers
A LONG LONG INT is a value of a different mode, not a wider
INT variable. Arithmetic between the two modes is allowed through
the widening coercion, but a long result cannot be narrowed back to an
INT or a REAL. The conversion in the other direction
is written LONG LONG INT(i).
BEGIN
LONG LONG INT f := 1;
FOR i TO 25 DO f *:= LONG LONG INT(i) OD;
print(("25! = ", whole(f, 0), newline));
print(("2^100 = ", whole(LONG LONG INT(2) ** 100, 0), newline));
print(("fits in INT: ", f < LONG LONG INT(max int), newline))
END
The loop multiplies by a converted loop counter, because *:=
between a long integer and an INT is not declared; the ordinary
* does accept the mixture through widening. The comparison shows
that 25 factorial is far beyond max int. The values are printed
with whole(..., 0), because the default field of a long integer
is very wide and would bury the digits in spaces.
$ a68g long.a68 25! = 15511210043330985984000000 2^100 = 1267650600228229401496703205376 fits in INT: F
Setting the precision
The number of significant digits of the long modes is set by a pragma at the
top of the program: PR precision=200 PR. The default in this
build is 70 digits, which holds 53 factorial but not 100 factorial, whose 158
digits need a larger precision.
PR precision=200 PR
BEGIN
LONG LONG INT f := 1;
FOR i TO 100 DO f *:= LONG LONG INT(i) OD;
print(("100! = ", whole(f, 0), newline));
print(("digits: ", whole(UPB whole(f, 0), 0), newline))
END
The pragma precedes the block, so every long value in the program is created
with the new precision. The result is exact, including the long run of
trailing zeros that comes from the factors of 2 and 5. The upper bound of the
string returned by whole is the number of digits, which is 158.
$ a68g factorial100.a68 100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 digits: 158
Fibonacci numbers in long modes
The iterative Fibonacci procedure needs only two long integers, and it reaches
values that an INT overflowed long before. The 200th Fibonacci
number has 42 digits, so a precision of 100 leaves room for the intermediate
sums as well.
PR precision=100 PR
BEGIN
LONG LONG INT a := 0, b := 1;
FOR i TO 200 DO
LONG LONG INT t := a + b;
a := b;
b := t
OD;
print(("fib(200) = ", whole(a, 0), newline))
END
After each step a holds the previous number and b
the current one, so after 200 steps a is the 200th Fibonacci
number when the sequence starts at 0. The temporary t is
necessary because the assignment to a would otherwise destroy the
value needed by b.
$ a68g fib200.a68 fib(200) = 280571172992510140037611932413038677189525
The --precision option
A program that does not contain the pragma uses the precision given on the command line. This program computes 100 factorial and prints only the number of digits and the first twenty of them, which keeps the output short.
BEGIN LONG LONG INT f := 1; FOR i TO 100 DO f *:= LONG LONG INT(i) OD; STRING s = whole(f, 0); print((whole(UPB s, 0), " digits, starts with ", s[1:20], newline)) END
Run without options, the program stops with a long integer overflow, because
the default precision is too small for the intermediate product.
--precision 200 raises the limit before the program is
elaborated, and the same file then succeeds. A pragma in the source takes
precedence over the option, so publishing a program with its precision in the
source makes the result independent of the command line.
$ a68g fact100.a68 a68g: runtime error: 1: LONG LONG INT value out of bounds (numerical result out of range) (detected in VOID loop-clause starting at "FOR" in this line). $ a68g --precision 200 fact100.a68 158 digits, starts with 93326215443944152681
Division, remainder, and comparisons
Long integers support the same operators as INT:
OVER for integer division, MOD for the remainder,
** for a power, and the usual comparisons. A comparison between
a long integer and an INT widens the short operand, so no explicit
conversion is needed.
BEGIN
LONG LONG INT n := 1;
FOR i TO 30 DO n *:= 2 OD;
print(("n = ", whole(n, 0), newline));
print(("n over 3 = ", whole(n OVER 3, 0), newline));
print(("n mod 7 = ", whole(n MOD 7, 0), newline));
print(("n > 10^9 = ", n > 1000000000, newline))
END
The value is 2 to the 30th, which still fits in an INT, but it is
kept in a long variable throughout. Division truncates towards zero, the
remainder is 1, and the comparison yields T, the way a
BOOL prints. A boolean result can be used directly in an
IF or stored in a variable of mode BOOL.
$ a68g mixed.a68 n = 1073741824 n over 3 = 357913941 n mod 7 = 1 n > 10^9 = T
Next steps
The number formatting article shows how to print these values in columns, and the operators article explains the priorities of the arithmetic used here. The error handling article describes what a program can do when a runtime check such as an overflow fails.
Source
Revised Report on the Algorithmic Language Algol 68
In this article we have seen the limit of an INT, declared long
integers, raised their precision with a pragma and with a command-line option,
and computed 100 factorial and the 200th Fibonacci number exactly.
Author
List all Algol 68 tutorials.