Base Conversion Algorithm

Table of Contents

1. Introductory Code and Results

I wonder if there might be some interesting properties between numbers in a base and numbers in the square of that base, so I decided to quickly write a base conversion program that treats numbers as tuples so I don't have to create a bunch of unique symbols to weigh numbers.

def base10toN(x, n=10):
    new_x = x
    baseNnum = []
    while new_x >= n:
        baseNnum.append(int(new_x % n))
        new_x = int(new_x // n)
    baseNnum.append(new_x)
    baseNnum.reverse()
    return baseNnum

Basically all this does is take a number in base 10 and a proposed base, and repeatedly divide it by that base to get the various powers of the number and append it to an array so I can see the "digits" in base n, but without any unique symbols. However, it does this process backwards, so I need to reverse the list before outputting it.

Here, we convert 144 to base 16, which should have a result of 90

base10toN(144,16)

[9, 0]

In a more interesting demonstration, consider converting 254 to base 16, which should be FE, or a list that reads [15,14]

base10toN(254,16)

[15, 14]

Okay, investigation time now that we know it works - how do numbers change when we do powers of bases.

for i in range(5):
  power = i+1
  print(10**power)
  print(base10toN(117,10**power))

10 [1, 1, 7] 100 [1, 17] 1000 [117] 10000 [117] 100000 [117]

This hung for a while at first, and I didn't realize that at first it would start with a power of 0 and try and represent a number in base 1, which is not great. But, once I changed it to add 1 to the powers it ensures that the powers start at 1.

Now, I want to consider how we can compare two numbers assuming they are in the same base - essentially creating a less than or greater than for these vectors that represent the numbers.

def baseNcomp(x, y):
    if len(x) > len(y):
        return True
    elif len(y) > len(x):
        return False
    else:
        for i in range(len(x)):
            if x[i] > y[i]:
                return True
            elif y[i] > x[i]:
                return False
        return False

Notably this only works as a strict inequality, as I wanted to ensure it returned only booleans. Ah well. Let's test this baby.

x = base10toN(456,16) # should be 1, 12, 8
print(x)
y = base10toN(489,16) # should be 1, 14, 9
print(y)
print(baseNcomp(x,y)) # should be False

a = base10toN(489,16) # should be 1, 14, 9
print(a)
b = base10toN(456,16) # should be 1, 12, 8
print(b)
print(baseNcomp(a,b)) # should be True

c = base10toN(217,16) # should be 13, 9
print(c)
d = base10toN(456,16) # should be 1, 12, 8
print(d)
print(baseNcomp(c,d)) # should be False

[1, 12, 8] [1, 14, 9] False [1, 14, 9] [1, 12, 8] True [13, 9] [1, 12, 8] False

HELL YEAH Well, that's certainly some useful tools out of the way. I need to start thinking about problems I can do with this.

for i in range(5):
    power = i+1
    print(10**power)
    print(base10toN(198891,10**power))

10 [1, 9, 8, 8, 9, 1] 100 [19, 88, 91] 1000 [198, 891] 10000 [19, 8891] 100000 [1, 98891]

You know, I'm not really sure what I was expecting. This is cool though - a number that is a palindrome in base 10 may not be in base 100 or 1000 or whatever, because we're basically lumping different numbers of digits together to form "megadigits" or "extended digits" or whatever the hell someone would call them. Interesting question - can a number be a palindrome in two different power bases - say, 100 and 1000 which are both powers of 10? My initial conjecture says no because of the way that they split into different blocks, but I'm not sure.

Actually, it's definitely true, I can think of an example right now - 9000009 is naturally a palindrome in base 10, but also:

for i in range(5):
    power = i+1
    print(10**power)
    print(base10toN(9000009,10**power))

10 [9, 0, 0, 0, 0, 0, 9] 100 [9, 0, 0, 9] 1000 [9, 0, 9] 10000 [900, 9] 100000 [90, 9]

So we see that the number 9000009 is a palindrome in base 10, 100, and 1000 - and repeating this pattern with more zeros should just allow us to create arbitrarily high base palindromes, provided that the number of zeros in the base - that is, the power of 10 for the base - doesn't perfectly divide the length of the number itself in base 10. For example, suppose we want a number that is a palindrome in base 10, 100, 1000, and 10000 - that is, in powers 2, 3, and 4. What is the LCM of 2, 3, and 4? 12. So we need a number of length 13 to make it work. Observe.

for i in range(5):
    power = i+1
    print(10**power)
    print(base10toN(9000000000009,10**power))

10 [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9] 100 [9, 0, 0, 0, 0, 0, 9] 1000 [9, 0, 0, 0, 9] 10000 [9, 0, 0, 9] 100000 [900, 0, 9]

We may even be able to expand this further to make palindromes out of numbers that aren't just one digit on each end with zeros in between, by repeating units within the number. Here's one that can be done by just changing one or two numbers in the center.

for i in range(5):
    power = i+1
    print(10**power)
    print(base10toN(9000002000009,10**power))

10 [9, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 9] 100 [9, 0, 0, 2, 0, 0, 9] 1000 [9, 0, 2, 0, 9] 10000 [9, 0, 200, 9] 100000 [900, 20, 9]

There's probably a better way to think or formalize this with break lines on where transitions between the "megadigits".

Something I just thought of is that converting numbers from arbitrary bases to base 10 might also be handy, so I should probably write a function for that.

def baseNto10(x, n):
    baseNnum = x.copy()
    base10num = 0
    baseNnum.reverse()
    for i in range(len(baseNnum)):
        base10num += baseNnum[i] * (n**(i))
    return base10num

Nothing super special here, just creates a copy of the tuple number and iterates on it to add up a base 10 number. Test time!

print(baseNto10([1,3,1],8)) # should be 89

print(baseNto10([5,9],16)) # should be 89

print(baseNto10([15,14],16)) # should be 254

89 89 254

Well, shit! This could also be another way to compare the sizes of two different numbers, which is nifty.

2. Conjectures and Questions

I can find some different questions and conjectures about representations of numbers in different bases.

2.1. Palindromes

2.1.1. Powers of bases

These are the questions that prompted me to start working on the base functions in the first place - what numbers are palindromes in powers of bases and how do powers of bases affect whether or not a number is a palindrome?

I already have some basic results and answers to some questions that I have had:

  • Can numbers be palindromes in multiple bases - specifically a second base that is a power of the first base? Yes - 9009 is a palindrome in base 10 and base 103 = 1000

    for i in range(4):
      power = i+1
      print(10**power)
      print(base10toN(9009,10**power))
    

10 [9, 0, 0, 9] 100 [90, 9] 1000 [9, 9] 10000 [9009]

In fact, for any tuple of \(\{x_1 , x_2, \dots , x_n\}\) of powers of a base \(b\) we can create a palindrome for all those bases that can be written as \(b^{x_i}\) by simply taking an initial and final digit in base \(b\) and filling in \(\text{LCM}(\{x_1 , x_2, \dots , x_n\}) - 1\) zeros between them. Here's an example - consider 7000007. This should by this theory be a palindrome in base 8, 64, and 512. Please ignore the extremely cursed base10toN(baseNto10 call.

for i in range(4):
  power = i+1
  print(8**power)
  print(base10toN(baseNto10([7,0,0,0,0,0,7],8),8**power))

8 [7, 0, 0, 0, 0, 0, 7] 64 [7, 0, 0, 7] 512 [7, 0, 7] 4096 [448, 7]

Nice! I should probably write up a formal proof of it.

  • Can numbers that don't fit this pattern exhibit similar properties? Certainly. Consider the example of 90509 which is a palindrome in bases 10 and 100. This procedure of switching the middle number should work whenever we have an odd number of zeros.

    for i in range(4):
        power = i+1
        print(10**power)
        print(base10toN(90509,10**power))
    

10 [9, 0, 5, 0, 9] 100 [9, 5, 9] 1000 [90, 509] 10000 [9, 509]

for i in range(4):
  power = i+1
  print(10**power)
  print(base10toN(900050009,10**power))

10 [9, 0, 0, 0, 5, 0, 0, 0, 9] 100 [9, 0, 5, 0, 9] 1000 [900, 50, 9] 10000 [9, 5, 9]

Can we do more complex patterns than this? Not things that would be palindromes in base 10, maybe, but possibly ones that are palindromes in base 100 and base 10000. I'll have to see.


Back to Math Hub
Back to homepage