Convert Any Integer (± X) From One Base System Into Another

Enter Integer ±X  (Expressed in any base from 2 to 36)

  Integer X     from base    to base      (base = 2 to 36)

The 1-digit base 10 integer given above EXACTLY equates to the following 1-digit base 16 integer:
Processing time = 00:00:00.000

A Problem With the Native PHP Base Conversion Function

Although PHP has a built-in base conversion function, it has a serious accuracy limitation.  No matter how many digits may be in the converted result, the actual accuracy may be only up to 12 or 14 digits at best.  This means that any digits after the 12th or 14th digit are most likely bogus, but nothing clearly indicates this, so we must be cautious when using that function.  The examples below will serve to illustrate this problem.

For example, when the numbers are very large, the accuracy of the result may break down at a certain point and the remaining digits are all junk digits.  However, the native PHP Base_Convert(...) function does not indicate that the converted result is wrong.  Consider this example, converting from base 22 to base 32

Native PHP function value = NOT EXACT

2R2D7QBVD4P0000000000000000000000000 = NOT EXACT
To work around this accuracy limitation, the following two functions were developed to convert an arbitrary-precision integer from any given base (2 to 36) into its base 10 equivalent and vice versa.  The converted result will be exactly correct, to the last digit, even if the result is thousands of digits long!  Just don't get too ridiculous.  These are the functions that performed the computations above.

The first-level functions used in this program handle integers only.

This is the first of the two base conversion functions used in this program.  It converts any arbitrary-precision integer from any given base (2 to 36) into its base 10 equivalent.

   function bcBaseB_Int_To_Base10 ($XBIntStr, $FromBase)
   $XB = strtoupper(trim($XBIntStr));
   $B  = $FromBase;

   if ($B < 2 or $B > 36) {return FALSE;}

   $sign = (substr($XB, 0,1) == '-')? '-' : '';

   if ($sign == '-') {$XB = substr($XB, 1, strlen($XB));}

   $X10 = 0;
   $piB = 1;
   $XBDigitsCount = strlen($XB);

   $DigitsSpectrum = substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $B);

   for ($i=0;   $i < $XBDigitsCount;   $i++)
   $diB = substr($XB, $XBDigitsCount - $i - 1, 1);

   $di10 = strpos($DigitsSpectrum, $diB); if($di10 === FALSE) {return $di10;}

   $Xi10 = bcmul($piB, $di10);
   $X10  = bcadd($X10, $Xi10);
   $piB  = bcmul($piB, $B);
   return "$sign$X10";

The following function converts an arbitrary-precision base 10 integer into its equivalent in any alternate base (from 2 to 36).  When used together, these functions allow easy two-way translation of an integer from any one base into another.

We use the first function, defined above, to convert the given integer argument into its base 10 equivalent and then we use the second function, defined below, to convert the base 10 value into the alternate base equivalent.

Since we are using arbitrary-precision arithmetic, all computations will be exactly accurate to the last digit, which could extend out to multiple thousands of digits.

   function bcBase10_Int_To_BaseB ($X10IntStr, $ToBase)
   $w = trim($X10IntStr);  if (!is_numeric($w)) {return FALSE;}

   $sign = (substr($w, 0,1) == "-")? "-" : "";

   if ($sign == "-") {$w = substr($w, 1, strlen($w));}

   if (bccomp($w, 0) == 0) {return "0";}

   $B = $ToBase;  if (!is_numeric($B) or $B < 2 or $B > 36) {return FALSE;}

   $DigitsSpectrum = substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $B);

   $XB = "";

   while (bccomp($w, 0) > 0)
          $XB  = substr($DigitsSpectrum, bcmod($w, $B), 1) . $XB;
          $w = bcdiv($w, $B);

   return $sign . $XB;

v2.5 - Jay Tanner - 2017