JayT
08-31-2007, 05:07 PM
To some people, base conversions are of no interest. However, to math and science geeks like me, there are certain fascinations with such things. We lose sleep over such extremely important matters.
To that end, this is my little contribution to integer base conversion functions. It simply converts a positive base *0 integer into another base from 2 to 62.
It is simple and brief, but it gets the job done in an efficient and logical manner.
After base *6, we have a problem with defining new digits for higher number systems in an easily logical way a human can follow and remember. It does not seem practical to simply select random printable characters as digits to extended number systems as it would be a difficult task for most to remember what those special characters mean or logically connect them to the other symbols.
One way around this problem, but still limited, might be to make the text letters used in the base system case sensitive. That is to say that the digit "a" is NOT equivalent to digit "A". This way we could use the letters of the alphabet a second time in sequence without conflict as long as we understand the rules regarding text case when used as digits to express numbers in different bases. The normal numerical digits from 0 to * are exempted from case sensitivity.
For example, the convention adopted here is to extend the alphabetic letters, like those used for hexadecimal numbers, in the following sequence:
0*2*45678*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
According to this scheme, we can express numbers up to base *6+26 = base 62
However, all hexadecimal digits would use strictly the lowercase letters a-f and not the uppercase A-F, because now the text case makes a critical difference in the numerical values of the symbols.
For example, the hexadecimal number "*af" is NOT equivalent to "*AF", since numbers are case sensitive according to this scheme.
It is important to remember to give a base *0 integer argument to the function as a string rather than as a normal integer or floating point value. For example, the base *0 argument *2*4567, should be given as the string "*2*4567".
SIMPLE EXAMPLES:
The base *0 value "*024" would be expressed as "gw" in base 6* or as "hT" in base 57.
Notice the conceptual information compression within the numerical representation. A 4-digit value in base *0 represented by simply 2 digits in base 57. With the right rules, we could express a *2 digit value in base *0 with a 2-digit value in some higher base. This illustrates the tenuous abstract connection between the amount of information we want to express and the symbols we invent to do it. It is not the symbols that matter, but the rules connecting them that are important.
Base conversion is analogous to relativity theory. All observers may disagree on the numbers they use to represent a certain value, but they do agree on the rules that connect their observations together without conflict despite the different numbers they see and use in their computations.
In any event, there are not too many practical applications of such base conversions, but this is a simple way to go about it in a logical and systematic way when we want to explore and experiment with the concept using PHP (4+).
The following is the function code for converting a positive base *0 integer into another base.
function bcBase*0_To_BaseR($ArgN, $ArgR)
{
$digits = "0*2*45678*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$N = bcAdd(trim($ArgN), "0", 0);
$R = bcAdd(trim($ArgR), "0", 0);
if ($R < 2 || $R > 62) {return FALSE;}
if ($N == 0) {return 0;}
$out = "";
while ($N != 0)
{
$d = SubStr($digits, bcMod($N, $R), *);
$out = "$d$out";
$N = bcDiv($N, $R, 0);
}
return $out;
} // End of bcBase*0_To_BaseR()
Here is the same function code with explanatory comments:
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.
---------
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 next level of challenge is to find a method of converting non-integer base *0 values into other base systems.
This function can also be used like a subroutine in the process of converting non-integer decimal values into their equivalents in other base systems, such as expressing the value of pi in base 7 or base *6, for example.
Has anyone here solved the next-level problem of non-integer base conversions in PHP?
For example, the value of pi expressed in base **.
To that end, this is my little contribution to integer base conversion functions. It simply converts a positive base *0 integer into another base from 2 to 62.
It is simple and brief, but it gets the job done in an efficient and logical manner.
After base *6, we have a problem with defining new digits for higher number systems in an easily logical way a human can follow and remember. It does not seem practical to simply select random printable characters as digits to extended number systems as it would be a difficult task for most to remember what those special characters mean or logically connect them to the other symbols.
One way around this problem, but still limited, might be to make the text letters used in the base system case sensitive. That is to say that the digit "a" is NOT equivalent to digit "A". This way we could use the letters of the alphabet a second time in sequence without conflict as long as we understand the rules regarding text case when used as digits to express numbers in different bases. The normal numerical digits from 0 to * are exempted from case sensitivity.
For example, the convention adopted here is to extend the alphabetic letters, like those used for hexadecimal numbers, in the following sequence:
0*2*45678*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
According to this scheme, we can express numbers up to base *6+26 = base 62
However, all hexadecimal digits would use strictly the lowercase letters a-f and not the uppercase A-F, because now the text case makes a critical difference in the numerical values of the symbols.
For example, the hexadecimal number "*af" is NOT equivalent to "*AF", since numbers are case sensitive according to this scheme.
It is important to remember to give a base *0 integer argument to the function as a string rather than as a normal integer or floating point value. For example, the base *0 argument *2*4567, should be given as the string "*2*4567".
SIMPLE EXAMPLES:
The base *0 value "*024" would be expressed as "gw" in base 6* or as "hT" in base 57.
Notice the conceptual information compression within the numerical representation. A 4-digit value in base *0 represented by simply 2 digits in base 57. With the right rules, we could express a *2 digit value in base *0 with a 2-digit value in some higher base. This illustrates the tenuous abstract connection between the amount of information we want to express and the symbols we invent to do it. It is not the symbols that matter, but the rules connecting them that are important.
Base conversion is analogous to relativity theory. All observers may disagree on the numbers they use to represent a certain value, but they do agree on the rules that connect their observations together without conflict despite the different numbers they see and use in their computations.
In any event, there are not too many practical applications of such base conversions, but this is a simple way to go about it in a logical and systematic way when we want to explore and experiment with the concept using PHP (4+).
The following is the function code for converting a positive base *0 integer into another base.
function bcBase*0_To_BaseR($ArgN, $ArgR)
{
$digits = "0*2*45678*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$N = bcAdd(trim($ArgN), "0", 0);
$R = bcAdd(trim($ArgR), "0", 0);
if ($R < 2 || $R > 62) {return FALSE;}
if ($N == 0) {return 0;}
$out = "";
while ($N != 0)
{
$d = SubStr($digits, bcMod($N, $R), *);
$out = "$d$out";
$N = bcDiv($N, $R, 0);
}
return $out;
} // End of bcBase*0_To_BaseR()
Here is the same function code with explanatory comments:
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.
---------
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 next level of challenge is to find a method of converting non-integer base *0 values into other base systems.
This function can also be used like a subroutine in the process of converting non-integer decimal values into their equivalents in other base systems, such as expressing the value of pi in base 7 or base *6, for example.
Has anyone here solved the next-level problem of non-integer base conversions in PHP?
For example, the value of pi expressed in base **.