# How to implement Donald Knuth's up-arrow notation

How does one enter very large numbers in up-arrow notation? Up-arrow notation was created by Donald Knuth to write very large numbers in it iterated exponentiation form, for example 6↑↑3 = 6^6^6.

-
Should that not be 6↑↑3 = 6^6^6? – Teake Nutma Jun 27 '14 at 16:15
@TeakeNutma is correct, the question should be edited. Unfortunately I can't do it myself because "[e]dits must be at least 6 characters" and there is only a single character to be added. – gilberto.agostinho.f Jun 27 '14 at 20:52

UpArrow[a_, n_Integer] := Nest[a^# &, 1, n]


then

UpArrow[4, 3]


or

4 \[UpArrow] 3


To complete this method you may wish to add an input alias:

AppendTo[CurrentValue[$FrontEndSession, InputAliases], "up" -> "\[UpArrow]"];  Now EscupEsc will enter \[UpArrow]. Change $FrontEndSession to \$FrontEnd and run it only once to make the change persist between sessions.

-
UpArrow can be used directly. Hope you do not mind the edit. – Mike Honeychurch Jun 27 '14 at 4:02
This isn't correct, a single up arrow is power, two is tetration, etc... see Teake Nutma answer. – alan2here Jun 28 '15 at 11:22

Here's a more general variant a(↑...↑)b with any given number of up-arrows, as defined on MathWorld:

(* Short-hand for single arrow. *)
UpArrow[a_, b_]    := UpArrow[1][a, b];
(* Trivial case of a(↑...↑)1. *)
UpArrow[_][a_, 1]  := a;
(* Single arrow: exponentation. *)
UpArrow[1][a_, b_] := a^b;
(* Generic case: do a recursion. *)
UpArrow[n_Integer][a_, b_Integer] /; n > 1 :=
Nest[UpArrow[n - 1][a, #] &, a, b - 1];

(* And some nice formatting. *)
MakeBoxes[UpArrow[n_][a_, b_], StandardForm] :=
RowBox@{
MakeBoxes[a],
SuperscriptBox["\[UpArrow]", MakeBoxes[n]],
MakeBoxes[b]
};


The UpArrow[n][a,b] notation may look a bit clumsy (as opposed to say UpArrow[a,b,n]), but it makes the use of Infix notation much more natural:

-

You can use the Notation package to make the input of Knuth-style numbers very easy.

Load the notation package, which will make a Notation palette appear at the top-right of your screen.

<< Notation


Use the second entry in the Notation palette (you have to do it this way) to define a new input notation.

Notation[a_\[UpArrow]n_ \[DoubleLongRightArrow] Nest[a_^#&,1,n_]]


This uses a pattern that is inspired by the UpArrow function defined in the answer given by Szabolcs.

Test that this new input notation works.

6\[UpArrow]3 == 6^6^6

(* True *)


You can define an input alias for entering \[UpArrow] in order to make things even more user-friendly.

-
Is there any reason to do this? Using the built-in associated Symbol UpArrow seems like a much better option. – Mr.Wizard Jun 27 '14 at 18:38
As you say, ↑ is already associated with UpArrow, so you don't actually need to associate it again using Notation — my suggested use of Notation is thus redundant in this case. However, I never pass up the opportunity to fly the flag for the wonderful but underused Notation package — more people need to know about it. – Stephen Luttrell Jun 28 '14 at 8:44

Here is a Fold equivalent of Szabolcs' answer:

UpArrow[a_, n_Integer] := Fold[#2^#1 &, 1, ConstantArray[a, n]]


Then

UpArrow[4, 3]
`

1340780792994259709957402499820584612747936582059239337772356144372176\ 4030073546976801874298166903427690031858186486050853753882811946569946\ 433649006084096

-