基数 2 から基数 62 まで機能する関数が必要base_convert()
ですが、使用する必要がある数学がありません。PHP の制限により、bcmath を使用する必要があることはわかっています。これで問題ありません。
これらのような関数は、基数 10 から別の基数 62 までの間で数値を変換しますが、同じ機能を実装したいと思いますbase_convert()
。たとえば、任意の基数間で変換できる関数は 1 つだけです。
これを行うと思われる関数を見つけましたが、冗長で遅いコードがあるように感じます。ドイツ語を知っていれば、少し調整したいと思います。=(
関数のより読みやすいバージョンを次に示します。
function bc_base_convert($value, $quellformat, $zielformat)
{
$vorrat = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (min($quellformat, $zielformat) < 2)
{
trigger_error('Bad Format min: 2', E_USER_ERROR);
}
if (max($quellformat, $zielformat) > strlen($vorrat))
{
trigger_error('Bad Format max: ' . strlen($vorrat), E_USER_ERROR);
}
$dezi = '0';
$level = 0;
$result = '';
$value = trim(strval($value), "\r\n\t +");
$vorzeichen = '-' === $value{0} ? '-' : '';
$value = ltrim($value, "-0");
$len = strlen($value);
for ($i = 0; $i < $len; $i++)
{
$wert = strpos($vorrat, $value{$len - 1 - $i});
if (FALSE === $wert)
{
trigger_error('Bad Char in input 1', E_USER_ERROR);
}
if ($wert >= $quellformat)
{
trigger_error('Bad Char in input 2', E_USER_ERROR);
}
$dezi = bcadd($dezi, bcmul(bcpow($quellformat, $i), $wert));
}
if (10 == $zielformat)
{
return $vorzeichen . $dezi; // abkürzung
}
while (1 !== bccomp(bcpow($zielformat, $level++), $dezi));
for ($i = $level - 2; $i >= 0; $i--)
{
$factor = bcpow($zielformat, $i);
$zahl = bcdiv($dezi, $factor, 0);
$dezi = bcmod($dezi, $factor);
$result .= $vorrat{$zahl};
}
$result = empty($result) ? '0' : $result;
return $vorzeichen . $result;
}
上記の関数を説明したり、任意のベース間の直接変換のプロセスについて説明したりできますか?