Yo, Syntax
I'm not sure what your level of experience in mathematics is, but I'll try to explain the process of converting a non-integer base *0 number into its equivalent in another base. It can't always be done exactly as in the case of integers.
For higher precision, arbitrary precision operators must be used.
To convert a non-integer value from base *0 into base B, it is easier to do if we treat each part of the number separately. That is, convert the integer value first, separately from the decimal value.
When you multiply any base *0 value by a power of *0 (the base), notice that only the decimal point changes position, but the sequence of digits remains constant.
For example, multiplying 0.*4*5* by *00000 gives *4*5* as a result. The sequence of digits will remain the same. This rule also applies to other bases and is what makes it possible to convert non-integer values into another base.
For example, in the case of pi:
The base *0 value of the constant pi to 64 decimals can be defined by the PHP code:
define ("pi", "*.*4*5*265*58*7**2*846264**8*27*502884**7*6*****75*05820*74*445*2*");
The task will be to convert pi into its base 2 equivalent.
We first split the base *0 input argument into its separate integer and fractional parts ($I, $F) respectively.
Let
Code:
$I = "*";
$F = "0.*4*5*265*58*7**2*846264**8*27*502884**7*6*****75*05820*74*445*2*";
Let's use P = *00
and Q = (Base ^ P) = 2^*00 = *26765060022822*40*4*670*205*76
This Q value can be computed by the PHP code:
Code:
$Q = bcPow("2", *00); // = *26765060022822*40*4*670*205*76
Now compute
w = F *5; Q (truncated, not rounded, to an integer value)
Code:
$w = $bcMul($F, $Q); // = *7*4*00*2***00**5***824*4*7824
Convert the base *0 integer ($w) into base 2, which gives the fractional digit sequence
F = *00*0000******0**0*0*0*000*000*0000*0**0*000**0000*000**0*00**000*00**000**00**000*0*000*0***00000
The length of F is *8 digits in this case.
There may be one or more zeros following the decimal point and prior to the converted fractional string computed above.
To determine how many zeros (if any) follow the decimal point:
Code:
$NumZeros = $P - StrLen($F);
In this case it works out to
NumZeros = (*00 - *8) = 2
This means we attach 2 zeros to the beginning of $F (leftmost end).
Which gives
00*00*0000******0**0*0*0*000*000*0000*0**0*000**0000*000**0*00**000*00**000**00**000*0*000*0***00000
Now simply take the converted integer part, attach a decimal point and then attach the fractional part after it to obtain
**.00*00*0000******0**0*0*0*000*000*0000*0**0*000**0000*000**0*00**000*00**000**00**000*0*000*0***00 000
which is the required pi value expressed in base 2, to about *00 decimals, with a slight rounding fuzz factor at the end.
Like many base *0 fractional values, pi cannot be expressed exactly in any integer base. There will always be a fuzzy rounding error of some sort.
The rule is, the higher the power of the base used as a multiplier for the fractional part, the farther the accuracy of the converted decimal value extends.
The following function converts a base *0 integer into another base.
Code:
function bcBase*0_To_BaseR($ArgN, $ArgR)
{
/*
This function performs a simple base conversion for
base *0 integers into any other base from 2 to 62.
Author: Jay Tanner &#*6*;2007
PHP v4.4.4
Released under provisions of GPL v*
http://www.gnu.org/licenses
---------
ARGUMENTS
$ArgN = Positive base *0 integer string argument.
$ArgR = Radix argument (base) of output integer string.
The radix 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-*.
$digits = "0*2*45678*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Read input arguments and truncate
// to integer values if necessary.
$N = bcAdd(trim($ArgN), "0", 0);
$R = bcAdd(trim($ArgR), "0", 0);
// Error if radix (base) is outside valid range.
if ($R < 2 || $R > 62) {return FALSE;}
// Handle special case where N=0
if ($N == 0) {return 0;}
// Compute radix R equivalent to
// original base *0 argument.
$out = "";
while ($N != 0)
{
// Compute and fetch current base R digit.
$d = SubStr($digits, bcMod($N, $R), *);
// Collect current base R 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, $R, 0);
}
// Done.
return $out;
} // End of bcBase*0_To_BaseR()
The following function is for converting non-integer base *0 numbers into another base. It requires the function defined above.
Code:
function bcBase*0_To_BaseB ($Base*0ArgStr, $ToBaseArg)
{
/*
This function converts a non-integer base *0 value into
its equivalent in any other integer base.
Author: Jay Tanner &#*6*;2007
PHP v4.4.4
Released under provisions of GPL v*
http://www.gnu.org/licenses
----------
DEPENDENCY
This function requires the bcBase*0_To_BaseR() integer
conversion function.
*/
// ---------------------
// Read input arguments.
$x = trim($Base*0ArgStr);
$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 *0 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+*, StrLen($x));
// --------------------
// Compute new X value.
$X = bcMul($p200, $xFrx);
// --------------------------------------------------------
// Compute converted fractional digits minus decimal point.
$IntOut = bcBase*0_To_BaseR($xInt, $b);
$FrxOut = bcBase*0_To_BaseR($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 bcBase*0_To_BaseB()
I hope this isn't too complicated.
LOL
The functions could use some beta testing, since there are probably some bugs to be worked out. The error checking is not extensive.
USAGE:
To use the function to convert 2.7** into binary,
Code:
print bcBase*0_To_BaseB ("2.7**", 2);
The value returned will be:
*0.*0**0**0*0000***00*0*0**000000*00000**000*00*00**0
to 50 decimals.
The value 0.2* (base *0) converted into base 5 is:
0.*0************************************************
to 50 decimals