I wanted to make an algorithm that is a counter-example of Cantor's diagonalization argument. Given an integer, this Python code will produce a unique rational number. Fed the sequence of positive and negative integers as inputs, it will eventually produce all the floats.
Given infinitely long integers, I speculate that it produces infinitely long fractional numbers, forming a bijection with the real numbers. In my unpopular question on math.stackexchange, I learned that this is not a demonstration of the reals being countable (failing to be a counter-example to Cantor's argument) because the infinitely-long integers aren't integers. I won't pretend to fully understand that. Nevertheless, here's my code that produces a sequence of fractional numbers.
Try it: https://www.online-python.com/UGLMlWjy8v
import math
def r_impl(i):
if i == 0:
return 1
x = (int(math.log(i, 2)) >> 1) + 1
r = 1 << (x << 1) - 1
if i < r:
i <<= 1
i -= r
i += 1
return i / (1 << x)
def r(i):
if i == 0:
return 0
if i > 0:
return r_impl(i - 1)
return -r_impl(-i - 1)
for i in range(-65, 65):
print(f"int: {i} -> real: {r(i)}")
The size of the printed table can be configured in the last part of the code.
As the input integer increases, the algorithm walks increasingly large regions of the real number line with increasingly fine steps. The int
math.log
portion determines the pass that the input belongs to. The pass x has a region from (0 to 2ˣ], and 4ˣ steps. The steps count increases faster than the region so that the magnitude and precision can both grow. There are other ways to produce floats from integers, for instance setting the mantissa and exponent of a float directly, or this, but this is a method I hadn't seen before.
Finally, here are the notes from my design process using (mostly) binary notation.
s(d) = {1/(10^d) ... (10^(10d))/(10^d)} - s(d - 1)
1/1 | 1/10 ... 100/10 | 1/100 ... 10000/100 | 1/1000 ... 1000000/1000 | 1/10000 ... 100000000/10000
d is the number of divisor zeros (number of digits - 1)
x denominator number of fractions number of unique fractions fractions
0 1 1 (1) 1 (1) 1/1
1 10 100 (4) 11 (3) 1/10 (10/10) 11/10 100/10
2 100 10000 (16) 1100 (12) 1/100 (10/100) 11/100 ((100/100)) 101/100 (110/100) 111/100 (1000/100) 1001/100 1010/100 1011/100 1100/100 1101/100 1110/100 1111/100 10000/100
3 1000 1000000 (64) 110000 (48)
4 10000 100000000 (256) 11000000 (192)
x 10^x 10^(10x) u(0) = 1, u(x) = 100^x - 100^(x - 1)