Converting Base 10 Integers To Base B Bases By The Numbers - Base `10` to Base B When discussing the process of base conversion, a logical place to begin is by learning how to first convert our every-day, standard base `10` integers into their corresponding equivalents in other bases.  We will develop a simple PHP function to do this base `10` integer to base B conversion in arbitrary-precision to any number of digits we wish. The process of integer base conversion is actually very simple and consists of nothing more than collecting up the remainders of a series of reductive integer divisions, in reverse order of their generation (in right-to-left order), and then fetching their corresponding base `B` digit symbols from within the digits spectrum used for the conversion. Here, a reductive integer division means that the resulting integer quotient of the division by the base value replaces the original dividend in preparation for the next cycle, if any.  Each division cycle thus reduces the subsequent numerator (X value) in the sequence of divisions.  For example, the integer division of `13/2` results in the integer quotient `6` (`Q=6`) and a remainder of `1` (`R=1`). The process of converting the base `10` integer `13` into binary (base `2`): Let: X = Base `10` integer to be converted B = Alternative base into which to convert X Q = Integer quotient of integer division X/B R = Integer remainder of integer division X/B Starting with base `10` integer `X`, we divide it by the base (`B`), keeping only the integer quotient (`Q`) and the remainder (`R`) as demonstrated below. Starting with ... `X=13` and `B=2`: ```\$Q = bcdiv(\$X, \$B); \$R = bcmod(\$X, \$B); \$X = \$Q; ``` ```  X / B = Q, R 13 / 2 = 6, 1  6 / 2 = 3, 0  3 / 2 = 1, 1  1 / 2 = 0, 1 ``` The following random example shows the base `10` integer,  `X=820522970188564`,  expressed in its corresponding equivalents in all bases from `2` to `36`. ```Base 10 value X = 820522970188564 B The same numerical value expressed in base B 2 10111010100100001011100100001010110000101100010100 3 10222121020020012120122221011111 4 2322210023210022300230110 5 1330021422020332013224 6 12025035014310144404 7 334554554053104106 8 27244134412605424 9 3877206176587144 10 820522970188564 11 218497923755435 12 7803AA22652104 13 292ABCA404C246 14 10689748CA1576 15 64CDA435E7D94 16 2EA42E42B0B14 17 16G01FD5BCA19 18 CDE9FH22E724 19 70FEEBG97BEC 20 402BDB83DB84 21 2740HC88F99D 22 18JE7CH1FHCG 23 JICH612CI1K 24 CME4GLMJI64 25 8F29C23H1HE 26 5L35436L0F6 27 3QG665FHP4D 28 2LFN9943IOK 29 1RG6PNG0M7H 30 1BKI5RB6IC4 31 1011G2O2FGG 32 NA8BI2M2OK 33 HMDPANIHJG 34 DHG22AA2HQ 35 AED24KBVNY 36 82UN1R6AS4 ``` The above example table demonstrates how the same numerical value can be expressed in several base systems.   The table below was derived by randomly selecting one of the conversions from within the table above, in this case base `3`, to demonstrate how its individual digits were derived by converting the base `10` integer, `X=820522970188564`, into base `3`, one digit at a time, using a series of successive integer divisions and reductions and converting the sequential remainders into base `3` digit symbols.  The same process can used with any base to render EXACT arbitrary-precision base `10` integer to base B conversions to any number of digits. ```X /Base Remainder Symbol 820522970188564 /3 1 1 273507656729521 /3 1 1 91169218909840 /3 1 1 30389739636613 /3 1 1 10129913212204 /3 1 1 3376637737401 /3 0 0 1125545912467 /3 1 1 375181970822 /3 2 2 125060656940 /3 2 2 41686885646 /3 2 2 13895628548 /3 2 2 4631876182 /3 1 1 1543958727 /3 0 0 514652909 /3 2 2 171550969 /3 1 1 57183656 /3 2 2 19061218 /3 1 1 6353739 /3 0 0 2117913 /3 0 0 705971 /3 2 2 235323 /3 0 0 78441 /3 0 0 26147 /3 2 2 8715 /3 0 0 2905 /3 1 1 968 /3 2 2 322 /3 1 1 107 /3 2 2 35 /3 2 2 11 /3 2 2 3 /3 0 0 1 /3 1 1 820522970188564 in base 10 = 10222121020020012120122221011111 in base 3``` The Number of Digits in a Base B Integer It is very interesting to note that we do not have to actually perform any conversion of X to base B to simply predict how many base B digits the result would have if we did!  For example, we may not know what the base `10` integer `820522970188564` looks like when expressed in base `3`, but we can still predict that it consists of `32` base `3` digits by using this simple logarithmic formula: `Ydigits = 1 + floor(log(X) / log(B))` In PHP, this formula can be written in very similar form as: `\$Ydigits = 1 + floor(log(\$X) / log(\$B));` In this case, the log(x) function refers to the natural logarithm. However, base 10 or any other logarithmic base could be used. EXAMPLE: For Base `10` Integer X Converted Into Base B Integer Y: Given base `10` integer, `X=820522970188564`, to be converted to base `B=9`: Base 9 integer `equivalent Y = 3877206176587144` Base 9 digits in `Y = 1 + floor(log(820522970188564) / log(9)) = 16` The above base conversion table for `X = 820522970188564`, is reproduced again below, with this version of the table including the counts of the digits (in parentheses). ```Base 10 value X = 820522970188564 B Same numerical value expressed in base B (with digits count) 2 10111010100100001011100100001010110000101100010100 (50) 3 10222121020020012120122221011111 (32) 4 2322210023210022300230110 (25) 5 1330021422020332013224 (22) 6 12025035014310144404 (20) 7 334554554053104106 (18) 8 27244134412605424 (17) 9 3877206176587144 (16) 10 820522970188564 (15) 11 218497923755435 (15) 12 7803AA22652104 (14) 13 292ABCA404C246 (14) 14 10689748CA1576 (14) 15 64CDA435E7D94 (13) 16 2EA42E42B0B14 (13) 17 16G01FD5BCA19 (13) 18 CDE9FH22E724 (12) 19 70FEEBG97BEC (12) 20 402BDB83DB84 (12) 21 2740HC88F99D (12) 22 18JE7CH1FHCG (12) 23 JICH612CI1K (11) 24 CME4GLMJI64 (11) 25 8F29C23H1HE (11) 26 5L35436L0F6 (11) 27 3QG665FHP4D (11) 28 2LFN9943IOK (11) 29 1RG6PNG0M7H (11) 30 1BKI5RB6IC4 (11) 31 1011G2O2FGG (11) 32 NA8BI2M2OK (10) 33 HMDPANIHJG (10) 34 DHG22AA2HQ (10) 35 AED24KBVNY (10) 36 82UN1R6AS4 (10) ``` For Higher Bases For the higher bases, (greater than `10`), we traditionally use the sequential (not case sensitive) letters of the English alphabet as extended digit symbols, such as the letters "A" to "F", as used in hexadecimal numbers.  Normally, there is no single digit with a value of `15`, so we use the letter "F" to represent it.  When dividing by `16` and the remainder is `15`, we use the symbol "F" to represent that digit value in hexadecimal and higher bases.  For numbers expressed in any base from `2` to `10`, the digit symbols are the same as the digits themselves.  We only apply the sequential letters to the higher bases when we run out of normal digits to represent their values, that is, base `11` and above. Below is a simple PHP function designed to perform the complete, exact arbitrary-precision base `10` integer to base B conversion process.  Note that since we are doing arbitrary-precision computations, the function can handle integer base conversions extending out to hundreds or even thousands of digits with EXACT accuracy. ``` function bcBase_10_Int_To_Base_B (\$X10, \$B) { \$X = \$X10; if (bccomp(\$X, 0) == 0) {return "0";} \$DigitsSpectrum = substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",0,\$B); \$XB = ""; while (bccomp(\$X, 0) > 0) { \$XBDigitSymbol = substr(\$DigitsSpectrum, bcmod(\$X,\$B),1); \$XB = substr(\$DigitsSpectrum, \$XBDigitSymbol . \$XB; \$X = bcdiv(\$X,\$B); } return \$XB; } ``` In the above function, to generate the specific digits spectrum string for any given base from `B=2` to `B=36`, we use the following code line: `\$DigitsSpectrum = substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",0,\$B);` Since our standard base `10` digits spectrum consists of all the numerical digits from `0` to `9`, the base `10` digits spectrum string takes the form, "`0123456789`". If we were converting into binary (`B=2`), then the binary digits spectrum string would only consist of the `2` digits, "`01`". If we were converting into octal (`B=8`), the digits spectrum would take the form, "`01234567`". If we were converting into hexadecimal (`B=16`), the hexadecimal digits spectrum string would take the form, "`0123456789ABCDEF`". In the case of `B=24`, the digits spectrum would take the form, "`0123456789ABCDEFGHIJKLMN`", and so on. The `0`-based position index of a digit in the digits spectrum corresponds to the value of the remainder of the integer division of the current base `10` integer, `X`, by the current base (`B`).  This division is computed and the corresponding base `B` digit symbol extracted from the digits spectrum by the line: `\$XBDigitSymbol = substr(\$DigitsSpectrum, bcmod(\$X, \$B), 1);` An integer division here means that both dividend (`X`) and divisor (`B`) are integers and that any fractional part is dropped without rounding.  The division of `127/16` would result in exactly `7`, and not `7.9375`, as in floating point arithmetic nor rounded up to `8`.  Any decimal fraction that results from the division is simply ignored and dropped without exception. Within the function, the value of the remainder of the integer division, `X/B`, is computed by the statement: `bcmod(\$X,\$B)` This value is the index of the base `B` digit symbol within the digits spectrum. A simple test call to the above function might resemble the following: ```\$X = "820522970188564"; \$B = 27; print bcBase_10_Int_To_Base_B(\$X, \$B); // The printed result should be: 3QG665FHP4D ``` Even Higher Bases For Base `2` to Base `36` As previously defined above, the case insensitive digits spectrum (up to base 36) is: "`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ`" = "`0123456789abcdefghijklmnopqrstuvwxyz`" For Bases > 36 If we allow case sensitivity, where lowercase "a" is NOT identical to uppercase "A", and both symbols represent entirely different values, then we can use the uppercase letters to extend the digits spectrum by yet another 26 letters, giving us a CASE SENSITIVE digits spectrum consisting of 62 unique digits. The case sensitive base 62 digits spectrum is: "`0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`" Note that the lowercase letters from "a" to "f" must be used to represent hexadecimal values under this convention, since the uppercase letters, "A" to "F", are NOT equivalent symbols here. Allowing case sensitivity this way, lets us handle bases from 2 to 62.  Of course, we could extend the digit symbols indefinitely to represent even higher bases. SPECIAL NOTE: When displaying numbers in higher bases, we need to be careful which font we choose to display or print the digit symbols.  For example, care must be taken so that digits like "`0`" (zero) and "1" (one) are not mistaken for letters, like "O" or the lower case "L" or uppercase "I". Since in some font styles, certain numerical digits can closely resemble certain letters, we need to read such higher-base numbers carefully, and a well-chosen alpha-numeric font can help reduce this kind of confusion.  To avoid this problem, either the 'Consolas' or 'Inconsolata' font is recomended because they show a slash through the digit zero (`0`) which easily distinguishes the digit from the letter '`O`' when higher bases are used.  For those who do not have either font or something similar, they are freely available on the Internet. Jay Tanner - 2020