0

I have searched pretty extensively for this and cannot find anything. Here is the problem: converting a base 10 number into a very large base, such as base 400.

The purpose of this is simply educational.

I know that there are not enough ASCII characters to represent 400 different 'digits' in base 400, but for this problem, each place value of the high base number could remain in base 10. Each place value of the high base number could be separated by a space (or period) for readability.

Example of a base 400 number:

372 0 105 50

Example of a base 500 number:

492.0.256

Example of a base 1000 number (this is a 5 digits number in base 1000):

854 685 353 498 123

Any help is greatly appreciated. Suggestions for alternative ways to represent or separate the digits are also welcome.

spenibus
  • 4,339
  • 11
  • 26
  • 35
  • Thank you for that tip! I will update the question. – Change_Base Oct 02 '15 at 15:32
  • PHP has a built-in [`base_convert()`](http://php.net/manual/en/function.base-convert.php) function. It works beautifully for bases where there are sufficient simple alphanumeric characters to cover the digits -- typical use-case would be something like base32 or base36. I don't think it goes any higher than that, but some of the comments on that manual page do give code for higher base conversions so you could try them. There are also discussions there about the problems of loss of precision when dealing with very large numbers (quite likely if you have a multi-digit number in base 500!) – Simba Oct 02 '15 at 15:42

1 Answers1

1

Assuming $number as source number and $base as target base, we perform base conversion using a loop, where for each iteration:

  1. Get the remainder of the modulo $number % $base. This returns the value of the current digit as $digit.
  2. Subtract $digit from $number. This will give us rounded divisions later on.
  3. Divide $number by $base. We elevate the calculation to the next digit.
  4. We store $digit.
  5. Back to step 1 until $number is equal to 0.

Examples:

Step      1         2         3         4
      D=N%B     N=N-D     N=N/B         D
-----------------------------------------
512 in base 10 = 512
-----------------------------------------
512       2       510        51         2
 51       1        50         5         1
  5       5         0         0         5
-----------------------------------------
27 in base 2 = 11011
-----------------------------------------
27        1        26        13         1
13        1        12         6         1
 6        0         6         3         0
 3        1         2         1         1
 1        1         0         0         1
-----------------------------------------
1234567 in base 400 = 7 286 167
-----------------------------------------
123456  167   1234400      3086       167
  3086  286      2800         7       286
     7    7         0         0         7

This procedure in code form, using BCMath Arbitrary Precision Mathematics:

// arguments must be strings
function largeBaseConvert($num, $base) {

    $output = array();

    while($num !== '0') {

        // get remainder from modulo
        $digit = bcmod($num, $base);

        // substract remainder from number
        $num = bcsub($num, $digit);

        // divide by base
        $num = bcdiv($num, $base);

        // save
        $output[] = $digit;
    }

    // need to reverse the array as we count from the lowest digit
    return implode(' ', array_reverse($output));
}

Test:

echo largeBaseConvert('1234567', '17');

Output

14 13 4 14 10

Check:

14 * 17^4 = 1169294
13 * 17^3 =   63869
 4 * 17^2 =    1156
14 * 17^1 =     238
10 * 17^0 =      10
          = 1234567
spenibus
  • 4,339
  • 11
  • 26
  • 35