| JTee |
Sep 16th, 2007 7:23 PM |
All Your Base Are Belong To Us
Hi, harryc
Don't give up hope.
I've had this problem too. Not many seem to want to touch the non-integer base conversion problem. The same rules apply to all bases.
I wrote two functions that you could call within your program that might solve your problem.
The following two functions used together can convert a positive non-integer base 10 number into another base.
This function converts positive base 10 integers into another base from 2 to 62.
:
function bcBase10_Int_To_BaseB($ArgN, $ArgB)
{
/*
This function performs a simple base conversion for
base 10 integers into any other base from 2 to 62.
Author: Jay Tanner ©2007
PHP v4.4.4
---------
ARGUMENTS
$ArgN = Positive base 10 integer string argument.
$ArgB = Base of output integer string. The base
can range from 2 to 62, but it is possible
to extend it further.
------
ERRORS
An error results if any argument is invalid,
in which case, boolean FALSE is returned.
*/
// Define digits available for the base conversions.
// NUMBERS ARE CONSIDERED CASE SENSITIVE WITH THE EXCEPTION OF DIGITS 0-9.
$digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Read input arguments and truncate
// to integer values if necessary.
$N = bcAdd(trim($ArgN), "0", 0);
$B = bcAdd(trim($ArgB), "0", 0);
// Error if base is outside valid range.
if ($B < 2 || $B > 62) {return FALSE;}
// Handle special case where N=0
if ($N == 0) {return 0;}
// Compute base B equivalent to
// original base 10 argument.
$out = "";
while ($N != 0)
{
// Compute and fetch current base B digit.
$d = SubStr($digits, bcMod($N, $B), 1);
// Collect current base B digit in
// leftmost output string position.
$out = "$d$out";
// Update $N value.
// Done when $N==0
// Otherwise, repeat
// using new $N value.
$N = bcDiv($N, $B, 0);
}
// Done.
return $out;
} // End of bcBase10_Int_To_BaseB()
This function calls the function defined above and converts positive non-integer base 10 integers into another base from 2 to 62.
:
function bcBase10_To_BaseB ($Base10ArgStr, $ToBaseArg)
{
/*
This function converts a non-integer base 10 value into
its equivalent in any other integer base.
The result can be up to 50 decimals.
Author: Jay Tanner ©2007
PHP v4.4.4
----------
DEPENDENCY
This function calls the bcBase10_Int_To_BaseB() integer
conversion function.
*/
// ---------------------
// Read input arguments.
$x = trim($Base10ArgStr);
$b = trim($ToBaseArg);
// ---------------------------------------------------
// Compute 200th power of base. For higher precision,
// increase the 200 to a higher value.
$q = "200";
$p200 = bcPow($b, $q);
// --------------------------------------------------------------
// Separate base 10 x argument into integer and fractional parts.
$dp = StrPos($x, "."); if ($dp === FALSE) {$x .= ".0"; $dp = StrPos($x, ".");}
$xInt = SubStr($x, 0, $dp); if ($xInt == "") {$xInt = "0";}
$xFrx = "0." . SubStr($x, $dp+1, StrLen($x));
// --------------------
// Compute new X value.
$X = bcMul($p200, $xFrx);
// --------------------------------------------------------
// Compute converted fractional digits minus decimal point.
$IntOut = bcBase10_Int_To_BaseB($xInt, $b);
$FrxOut = bcBase10_Int_To_BaseB($X, $b);
// ---------------------------------------
// Get length of fractional string result.
$FrxL = StrLen($FrxOut);
// -----------------------------------
// Compute number of zeros immediately
// following the decimal point.
$nZ = 200 - $FrxL;
// -------------------------------
// Construct string of ($nZ) zeros
// to follow the decimal point.
$zeros = Str_Repeat("0", $nZ);
// ------------------------------------
// Attach fractional sequence to zeros.
$FrxOut = "$zeros$FrxOut";
// --------------------------------------
// Truncate fractional part to 50 digits.
$FrxOut = SubStr($FrxOut, 0, 50);
// --------------------------------------
// Done. Return converted integer part
// attached to converted fractional part.
return "$IntOut.$FrxOut";
} // End of bcBase10_To_BaseB()
EXAMPLE 1:
Convert pi from base 10 to base 2
:
// Define pi to 64 decimals as a string.
$pi = "3.1415926535897932384626433832795028841971693993751058209749445923";
print bcBase10_To_BaseB($pi, 2);
// Result = 11.00100100001111110110101010001000100001011010001100
// to 50 decimals
EXAMPLE 2:
Convert e (Euler's constant) from base 10 to base 7
:
// Define e (Euler's constant) to 64 decimals as a string.
$e = "2.718281828459045235360287471352662497757247093699959574966967627724077";
print bcBase10_To_BaseB($e, 7);
// Result = 2.50124106542265043353530003006264426305144420013153
// to 50 decimals
As with many ordinary decimal fractions, there may be a fuzz factor at the end of the fraction, since many fractions cannot be expressed exactly.
Hope this is useful.
Jay
:)
|