A recent post in GQ by Chronos got me to thinking about large numbers. Not a million or a billion or a trillion, but really large numbers, the type that aren’t even comprehensible. Allow to me to ramble on for a few paragraphs and share some thoughts with you.
There’s a certain constant in mathematics known as Graham’s number. We don’t know exactly what it is, but we do know that it’s below a certain number (or, as us geeks like to say, it has an upper bound).
I need some special notation to talk about this. In what follows, the | symbol should be an arrow pointing upwards, but I can’t seem to make that on this computer (not even using the character map!). Let’s define a|b to be a[sup]b[/sup]. Let’s also call that a|[sup]1[/sup]b.
Now we’ll define a|[sup]n+1[/sup]b as a|(a|[sup]n[/sup]b). With me so far? In case you’re not familiar with definitions like this, I’ll give an example.
Let’s take 2|[sup]2[/sup]2. By the definition above, that’s equal to 2|(2|2). 2|2 is 2[sup]2[/sup], which is 4. And 2|4 is 2[sup]4[/sup], which is 16. I hope it’s clear how I got that.
How about 2|[sup]3[/sup]2? Well, that’s 2|(2|[sup]2[/sup]2), which we know is 2|16, or 65536. Pretty clearly, the | symbol lets you write large numbers compactly.
But not compactly enough. Let’s introduce a function f. f(1) is 3|3. f(n+1) will be given by 3|[sup]f(n)[/sup]3. I’m not going to calculate any values of f, other than f(1), which is 27. It gets too big too quick.
Anyways, that’s what we need to explain the upper bound on Graham’s number. Graham’s number is known to be no bigger than f(64).
Stop, and think about that for a while. Can you really even comprehend how large a number that is? I can’t. It’s just unintelligible.
Remember the logarithm function from high school? Roughly speaking, the logarithm base n of x is the number of times you can divide x by n and still be larger than 1. We’re going to use the logarithm base 3, or log[sub]3[/sub]. log[sub]3/sub = 1, log[sub]3/sub = 2, log[sub]3/sub = 3, and so on and so forth. In general, log[sub]3/sub = log[sub]3/sub + 1. It’s all coming back now, right?
We’re going to introduce a new function, log[sup][/sup], or the iterated logarithm. If x is less than or equal to 1, log[sup]/sup = 0. Otherwise, log[sup]/sup = log[sup]/sup + 1.
This function gets big very slowly. Let me place it in perspective.
Scientists estimate that the universe is 1.5 * 10[sup]10[/sup] years old. log[sup]*[/sup](1.5 * 10[sup]10[/sup]) is equal to 3.
Scientists also estimate that there are 10[sup]79[/sup] atoms in the universe (or electrons, I can’t remember which). log[sup]*/sup is equal to 4.
Finally, scientists estimate that the universe will be completely disorganized in 10[sup]2000[/sup] years. log[sup]*/sup is equal to 4.
That’s right. It’s still 4, even though we went up by roughly 2000 orders of magnitude.
Just for fun, I tried 10[sup]80000[/sup]. Guess what? It’s still 4.
FYI, if x is smaller than y, then log[sup]/sup is no larger than log[sup]/sup. Our function isn’t getting bigger and then going down.
By the way, most experts believe that Graham’s number is actually equal to 6. We just don’t have a very good upper bound.
Here’s someting interesting: log[sup]/sup is equal to n. Remembering the definition of f, we see that log[sup]/sup is equal to f(63). It’s still not comprehensible. In fact, you have to apply the iterated logarithm 64 times to get to a comprehensible answer. Remember, f(2) is 3[sup]27[/sup]. That’s too large to be really comprehensible.
Now you appreciate large numbers. Or do you?
That’s only f(64). And 64 is so small!
Let’s introduce a new function, g. Let’s define g(1) to be f(1). And let’s define g(n+1) to be f(g(n)). So g(2) is f(f(1)), or f(27).
f(64) is somewhere between g(1) and g(2). Nothing at all compared to g(64).
Is that big enough for you? Not for me.
Let’s introduce a function h. Define h(1) as g(1), and h(n+1) to be g(h(n)).
This is just getting silly. And there’s no reason to stop yet.
Rewrite f as f[sub]1[/sub], g as f[sub]2[/sub], and h as f[sub]3[/sub]. See where this is going?
In general, we can define f[sub]k+1[/sub] as follows: f[sub]k+1/sub = f[sub]k/sub, and f[sub]k+1/sub = f[sub]k/sub.
These are some large numbers, folks. We left the iterated logarithm in the dust as soon as we introduced f[sub]2[/sub]. It’s just not useful any more.
An interesting fact: none of these numbers are infinite. They’re all finite, but large.
Now I’m going to tell you about a function that gets big so quickly that it eventually leaves f[sub]n[/sub] in the dust, no matter what n is. But I need a little more explanation.
A Turing machine is a very simple computer. It has a tape divided into cells. The tape is infinite in both directions, just so that we don’t have to worry about how much memory we have. I wish my computer were like that…
The machine also has a read/write head that allows it to read from and write to the current cell. The head can move right or left.
A Turing machine has one variable, the state. We’re interested in how many possible states there are for a given machine. We’ll call a machine with n possible states an n-state machine. We’re not always very creative.
The machine computes by reading the value in the current cell, adjusting its state, writing a new value, and moving its head right or left. It could also leave its head in the current position, but that’s redundant–whatever you do by looking at that cell twice you could’ve done by looking at it once.
What we’re interested in is called the busy beaver function, or B(n). There are multiple variations on this, but the simplest version is that B(n) is the maximum number of 1’s that an n-state Turing machine can write on its tape and still halt. Any more than that, and it just writes 1’s forever.
It turns out that B gets bigger faster than any plain, old, boring f[sub]k[/sub].
Read that again. These functions that we painstakingly defined, which produce insanely large numbers, are nothing compared to B. Nothing.
And yet, B still only produces finite numbers.
In fact, B gets so big, so fast, that it’s not possible to compute with a Turing machine. And no one knows of anything more powerful than a Turing machine, so as far as we know, no theoretical computer can compute B.
Turing machines can compute f[sub]k[/sub], though, so they’re not completely useless. In fact, there’s enough information in this post for a computer to design a Turing machine to compute f[sub]k[/sub].
Those are my thoughts on large numbers. I’m glad you stuck it out, and I hope this was at least a little bit clear.