"How many digits has nine to the ninth to the ninth?", it is a question in the Internet's Math Forum (Ask Dr. Math). Doctor Ken replies (09/25/97, Subject: Re: 9 ^ 9 ^ 9) and ... his answer isn't right. We can't imagine numbers with a gigantic number of digits; we can't use these numbers. This article includes the complete explanation of the Rexx arithmetic. I would like to show us some unusuall facilities of the language having resulting in unusual reflections on solutions of tasks and in unusual algorithms and (maybe) some surprising results.


We can determine the time of an execution of a program by the TIME built-in function. The program DUEL compares of the time of an execution of the TEXTBOOK and MAN functions. The first call to TIME, it is called as a subroutine with the argument "R", resets time. This is an analogy with the pressing of a stop-watch in the start of a run. The second call to TIME, it is called as a function once again with the argument "R", returns time elapsed since last reset (an analogy with pressing of a stop-watch in the course of the crossing finish line).

/* DUEL program */
numeric digits 1000; Error = ""
do until DATATYPE(N, "Whole number") & N >= 0
  say Error || "Enter a nonnegative whole number, please"
  parse pull N
  Error = "[" || N || "] eh? "
call TIME "R"; Exp1 = TEXTBOOK(N); say TIME("R") "sec"
call TIME "R"; Exp2 =      MAN(N); say TIME("R") "sec"

The DATATYPE built-in function returns an indication of the class to which the data belongs. If N is a whole and nonnegative number (char & is the operator of the operation "logical and" in Rexx) then the DATATYPE function returns 1 (TRUE in Rexx) else returns 0 (FALSE in Rexx). For example the value 200 meets this conditions.

This value can be written 200 or 200.0 or 2E+2 (i.e. 2 . 102 in exponential notation) optionally with leading or trailing blanks.

Exercise 1

Create stop-watch in Rexx.

Rexx computes ... as we do

What value is 1/0! + 1/1! + 1/2! + ... + 1/N! for N >= 0? This task coheres with the calculation of the base of the natural logarithm, named in honor of Leonard Euler e. The TEXTBOOK function describes a recommendation from textbooks.

/* TEXTBOOK internal function */
TEXTBOOK: procedure
Sum = 1; Item = 1
do J = 1 to ARG(1)
  Item = Item / J; Sum = Sum + Item
return Sum

But man doesn't compute sums as TEXTBOOK. The value of the fourth item (i.e. 1/(3!)) is 0.166 ... 67 with thousand significant digits. This value can be written by the COPIES built-in function as the result of the expression 0.1 || COPIES(6, 998) || 7.
    We usually calculate this sum using the algorithm which the MAN function describes (B. Higman: A comparative study of programming languages, MacDonald & Co. Ltd. 1970).

/* MAN internal function */
MAN: procedure
Numerator = 1; Denominator = 1
do J = 1 to ARG(1)
  Numerator = Numerator * J + 1
  Denominator = Denominator * J
return Numerator / Denominator

For N = 100 the DUEL program writes (on PC, processor 6x86MX-PR233, 32MB RAM, demo of Quercus Systems' Personal REXX for Windows 95):

0.380000 sec
0.060000 sec

It is a good idea to consider in the course of a solution of a numeric task that "Rexx computes in the same way as we do". It holds for the basic arithmetic operators + (addition), - (subtraction), * (multiplication), / (division), % (integer division - the mnemonic: the operator of division has only one char, i.e. / or %), // (remainder, i.e. divide and return only the remainder). For any number A and any number B <> 0 it follows that

A + 0 = (A % B) * B + (A // B).

Numeric comparison

The numeric comparison operators are =, >, <, <> (synonymous with \= and ><), >= (synonymous with \<), <= (synonymous with \>). Throughout the language, the not character,¬, is synonymous with the backslash (\). Assume a execution of the numeric digit D instructions (the default value of the D expression is 9) and the numeric fuzz F instruction (the default of the F expression is 0). Expressions D, F must result in a nonnegative whole number D > F >= 0. A comparing of numeric values is effected by subtracting the two numbers under a precision of D - F and then comparing the result with 0.

If the result is then the comparison with the operators is
negative <, <=, <> TRUE
zero >=, <=, = TRUE
positive >, >=, <> TRUE

The comparison operators return the value 1 if the result of the comparison is TRUE, or 0 otherwise.

The values of Exp1 and Exp2 (see the DUEL program) are not equal.
The say Exp1 = Exp2 instruction displays 0 and say Exp1 - Exp2 displays 0.000 ... 04 (with 999 zeros). But the instructions: numeric fuzz 1; say Exp1 = Exp2 displays 1.

Another number system

Humans usually use decimal, or base 10, numbers. When dealing with computers, it is frequently convenient to use bases 2 or 16. The following expression can be used for building a trivial hexadecimal calculator:

D2X(X2D(Hex1) + X2D(Hex2))

It computes the sum of two hexadecimal numbers stored in the Hex1 and Hex2 variables. The X2D built-in function returns the decimal representation of a given hexadecimal string and the D2X returns the representation of a decimal number in hexadecimal form. Simirally the expression

X2B(D2X(X2D(B2X(Bin1)) + X2D(B2X(Bin2))))

computes the sum of two binary values in the Bin1, Bin2 variables. We can want to remove leading zeros in binary numbers. The STRIP(string, option, character) built-in function returns the input string with specified leading (option "L"), trailing (option "T") or leading and trailing (option "B") characters removed.

Exercise 2

Write the function R2D (Roman to decimal) allowing decryption of the following enigma: Edgar Allan Poe (Born: MDCCCIX - Died: MDCCCXLIX).


The ** (power) operator raises a number to a power, which may be positive, negative, or 0. The power must be a whole number. If negative, the absolute value of the power is used, and then the result is inverted (divided into 1) - for Z < 0 and X <> 0, XZ = 1 / XABS(Z). In Rexx the power is calculated by the process of left-to-right binary reduction:

/* Algorithm of exponentation (X ** Z) */
Power = 1
BinZ = STRIP(X2B(D2X(Z)), "L", 0)
do J = LENGTH(BinZ) to 1 by -1
  if SUBSTR(BinZ, J, 1) then Power = Power * X
  X = X * X
say "X ** Z =" Power

I programmed the internal POWER function that follows. For values: X = 15; Z = 959; numeric digits 1128; and AS/400 model 310 the interpretation of POWER(X, Z) was faster (13.673 sec) than the interpretation of X ** Z (26.945000 sec).

/* POWER internal procedure */
POWER: procedure
X = ARG(1); Z = ARG(2); Pwr = 1
do forever
  if Z // 2 then Pwr = Pwr * X
  Z = Z % 2
  if Z = 0 then return Pwr
  X = X * X

I presented this fact in my email to REXXLIST (the subject Surprise for REXXperts, 98/01/16 in Archive of REXXLIST). The corresponding thread (in the form of the table) from REXXLIST and comp.lang.rexx is very intreresting. You can compare time of the interpretation or run of the compiled programs in different implementations of Rexx and in different environments (computers - PC, workstation, midi and mainframe; systems - IBM, Microsoft, Sun).

Computer System Rexx ** POWER Thanks for information go to
mainframe IBM CMS REXX370 compiler 0.0013 0.0017 Plungjan M.
mainframe IBM TSO REXX370 compiler 0.0013 0.0018 Plungjan M.
PC Windows NT 4.0 Object REXX 6.0 0.2100 0.2800 Stuurman J.
mainframe IBM CMS REXX370 interpret 0.2349 0.1694 Plungjan M.
mainframe IBM TSO REXX370 interpret 0.2884 0.1520 Plungjan M.
PC Pentium 166 OS/2 Warp 4 Classic Rexx 0.3700 0.2500 Kazimirchik V.
PC Pentium 90 Linux REXX/imc 0.4583 0.5062 Gurski A.F.
PC 486/33 OS/2 Warp 4 Object REXX 1.3000 1.8600 Vermo B.
Sun Sparc 2 Solaris 2.5.1 REXX/imc 1.6d 1.8500 2.1000 Collier I.
PC Windows NT 4.0 Regina faster slower Saxton J.M.

Numeric giants and dwarfs

The mass of the Earth is about 6E+24 kg and the mass of an atom of hydrogen is about 2E-24 g. For both large and small numbers some form of exponential notation is useful, both to make numbers more readable, and to reduce execution time and storage requirements. Assume execution of the numeric digits D instruction. If the number of places needed before the decimal point exceeds D, or the number leading zeros after the point exceeds D and number of places after the point exceeds twice D, exponential form will be used.


Ian Collier demonstrates (read Exponential notation, with Ian Collier's reply) that there is no difference between this definition and the definition in manuals or textbooks (M. F. Cowlishaw: The REXX Language - A Practical Approach to Programming, 1985; REXX/400 Reference, SC24-5664-00, IBM Corp. 1994).

Now we return to program DUEL with

... Exp1 = TEXTBOOK(N); ... Exp2 = MAN(N); ...

The value of Exp1 - Exp2 is 0.000 ... 04 with 999 zeros. The say Exp1 - Exp2 instruction displays 4E-999 after a execution of the instructions:

Subtract = Exp1 - Exp2; D = 9
numeric digits D; say Subtract + 0

We must add zero (multiple by 1 etc.) for using new setting accuracy.

Exercise 3

What are values of D when numeric digits D; say Subtract + 0 displays 4E-999?


The exponent of a number expressed in exponential notation may have up to nine digits only. In 1728 Daniel Bernoulli proved that e is equal to the limit of
(1 + 1/N)N

as N goes to infinity. The program with the maximal value of N:

/* BERNOULLI computes e, 1. version */
numeric digits 50; N = 999999999
say "e =" (1 + 1/N) ** N

displays e = 2.7182818270... For larger N the program is terminated with "syntax" error (Invalid whole number). But the program:

/* BERNOULLI computes e, 2. version */
numeric digits 50; Z = 1E+40
X = 1 + 1 / Z; say "e =" POWER(X, Z)

displays e = 2.71828182845904523560287...

Exponential notation is useful for writing a giant number. Examples follow in exercises.

Exercise 4

Epocha (the old Czech journal, No. 3, 1905): By only three digits we can write the giant number: nine to the ninth to the ninth. Number digits in this number is between 369 690 000 and 369 790 000.
How many digits has 9 ** (9 ** 9)?

Exercise 5

Number of black and white photos 10 x 15 cm, created by black and white dots 0.1 x 0.1 mm is 21500000. This number is long 2.3 km. Well, but what things will in the photographs?

Solutions of the excercises

Exercise 1

/* STOP-WATCH program */
say "Enter = Start"; pull Enter
call TIME "R"; say "Go! ..."
say "Enter = Stop"; pull Enter
say "Time:" TIME("R") "sec"

Exercise 2

Function R2D (Roman to Decimal) can solve this enigma. For MDCCCIX (or mDccCIx) returns 1809 and for MDCCCXLIX returns 1849.

/* R2D - Roman to Decimal - internal function */
R2D: procedure
parse upper arg Roman .
RtoD.I = 1; RtoD.V = 5; RtoD.X = 10; RtoD.L = 50
RtoD.C = 100; RtoD.D = 500; RtoD.M = 1000
Decimal = 0; Rdigit = LEFT(Roman, 1)
Ddigit = RtoD.Rdigit
do J = 2 to LENGTH(Roman)
  Rdigit = SUBSTR(Roman, J, 1); Next = RtoD.Rdigit
  if Next > Ddigit then Decimal = Decimal - Ddigit
    else Decimal = Decimal + Ddigit
  Ddigit = Next
return Decimal + Ddigit

Exercise 3

From 2 * D + 1 <= 999 follows D <= 499. I.e. the minimal value of D is 1 and maximal is 499.

Exercise 4

say 9 ** (9 ** 9) displays 4.28124773...E+369693099 (i.e. 369693100 digits). But a predecessor of this instruction can't be the numeric digits D instruction, where D < 9.

Exercise 5

Eduard Fuchs answers in his textbook Set Theory (UJEP Brno 1974, in Czech):

There will portraits of all dead people and people who will born in the future, their photos during different stages of their life; all scientific works and all art productions and their translations into all languages; logarithmic table and photos which will be sent from space probes, scores of symphonies don't exist yet and long ago destroyed buildings, etc. The major part will a bare unknown noise.

Notes and Acknowledgments.

For translation this article I used my emails in Archive of REXXLIST (Surprise for REXXperts 98/01/16, Exponential notation 98/10/05, How many digits has 9**(9**9) 98/10/20 and 98/10/23) and

M. F. Cowlishaw: The REXX Language - A Practical Approach to Programming

Prentice-Hall, inc., Engelwood Cliffs, New Jersey 1985

REXX/400 Reference
SC24-5664-00, IBM Corp. 1994

Helps from Personal REXX for Windows(tm) Version 3.50, Quercus Systems

I would like to express deep appreciation to Gerard Schildberger. He was especially helpful in pointing out misprints and errors.

To be continued... main page czech

since 1st January 2000, last changed 13th April 2018
Copyright © 2000-2018 Vladimir Zabrodsky.