首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 任意進制轉十進制完整實現(含步驟演示)

     編輯:PHP 相關知識

PHP 任意進制轉十進制完整實現(含步驟演示)

理解進制轉換原理有助於處理編碼、哈希、加密等底層邏輯。本文提供通用的「任意進制 → 十進制」轉換函數,支援整數、小數、字母數字混合(如十六進制),並可選擇性輸出計算步驟供教學演示。

核心轉換函數

<?php
/**
 * 任意進制字符串轉十進制數值
 *
 * @param string $number 來源數字字符串(支援 2-36 進制)
 * @param int $base 進制基數 (2-36)
 * @param bool $showSteps 是否返回計算步驟
 * @return float|array 十進制數值,或 [value, steps] 數組
 */
function baseToDecimal(string $number, int $base, bool $showSteps = false): float|array {
    if ($base < 2 || $base > 36) {
        throw new InvalidArgumentException("Base must be between 2 and 36");
    }
    
    // 分離整數與小數部分
    if (str_contains($number, '.')) {
        [$integerPart, $fractionPart] = explode('.', $number, 2);
    } else {
        $integerPart = $number;
        $fractionPart = '';
    }
    
    $steps = [];
    $total = 0.0;
    
    // 1. 整數部分:從右向左(低位到高位)
    $integerPart = strrev(strtoupper($integerPart));
    for ($pos = 0; $pos < strlen($integerPart); $pos++) {
        $char = $integerPart[$pos];
        $digitValue = charToValue($char);
        
        if ($digitValue >= $base) {
            throw new InvalidArgumentException("Digit '$char' (value $digitValue) invalid for base $base");
        }
        
        $power = $base ** $pos;
        $contribution = $digitValue * $power;
        $total += $contribution;
        
        if ($showSteps) {
            $steps[] = [
                'position' => $pos,
                'digit' => $char,
                'digit_value' => $digitValue,
                'power' => $power,
                'contribution' => $contribution,
                'formula' => "$digitValue × $base^$pos = $contribution"
            ];
        }
    }
    
    // 2. 小數部分:從左向右(高位到低位,負冪次)
    if ($fractionPart !== '') {
        $fractionPart = strtoupper($fractionPart);
        for ($pos = 1; $pos <= strlen($fractionPart); $pos++) {
            $char = $fractionPart[$pos - 1];
            $digitValue = charToValue($char);
            
            if ($digitValue >= $base) {
                throw new InvalidArgumentException("Digit '$char' invalid for base $base");
            }
            
            $power = $base ** -$pos; // 負冪次
            $contribution = $digitValue * $power;
            $total += $contribution;
            
            if ($showSteps) {
                $steps[] = [
                    'position' => -$pos,
                    'digit' => $char,
                    'digit_value' => $digitValue,
                    'power' => $power,
                    'contribution' => $contribution,
                    'formula' => "$digitValue × $base^(-$pos) = $contribution"
                ];
            }
        }
    }
    
    return $showSteps ? ['value' => $total, 'steps' => $steps] : $total;
}

/**
 * 字符轉數值 (0-9, A-Z -> 0-35)
 */
function charToValue(string $char): int {
    $char = strtoupper($char);
    $ord = ord($char);
    if ($ord >= ord('0') && $ord <= ord('9')) return $ord - ord('0');
    if ($ord >= ord('A') && $ord <= ord('Z')) return $ord - ord('A') + 10;
    throw new InvalidArgumentException("Invalid digit character: $char");
}

/**
 * 十進制轉任意進制(補全雙向)
 */
function decimalToBase(float $number, int $base, int $precision = 10): string {
    if ($base < 2 || $base > 36) throw new InvalidArgumentException("Base 2-36");
    
    $integerPart = (int)floor($number);
    $fractionPart = $number - $integerPart;
    
    // 整數部分
    $intStr = '';
    if ($integerPart === 0) $intStr = '0';
    while ($integerPart > 0) {
        $rem = $integerPart % $base;
        $intStr = valueToChar($rem) . $intStr;
        $integerPart = intdiv($integerPart, $base);
    }
    
    // 小數部分
    $fracStr = '';
    for ($i = 0; $i < $precision && $fractionPart > 0; $i++) {
        $fractionPart *= $base;
        $digit = (int)floor($fractionPart);
        $fracStr .= valueToChar($digit);
        $fractionPart -= $digit;
    }
    
    return $fracStr ? "$intStr.$fracStr" : $intStr;
}

function valueToChar(int $value): string {
    return $value < 10 ? (string)$value : chr(ord('A') + $value - 10);
}
?>

使用示例與步驟演示

<?php
// 1. 二進制轉十進制
$result = baseToDecimal('1011', 2, true);
echo "1011₂ = {$result['value']}₁₀\n";
foreach ($result['steps'] as $s) {
    echo "  位{$s['position']}: {$s['formula']}\n";
}
// 輸出:
// 1011₂ = 11₁₀
//   位0: 1 × 2^0 = 1
//   位1: 1 × 2^1 = 2
//   位2: 0 × 2^2 = 0
//   位3: 1 × 2^3 = 8

// 2. 十六進制轉十進制
echo baseToDecimal('FF', 16); // 255

// 3. 八進制帶小數
$result = baseToDecimal('17.4', 8, true);
echo "17.4₈ = {$result['value']}₁₀\n"; // 15.5

// 4. 36進制(0-9 + A-Z)
echo baseToDecimal('ZZ', 36); // 1295 (35*36 + 35)

// 5. 反向驗證
echo decimalToBase(255, 16); // FF
echo decimalToBase(15.5, 8); // 17.4
?>

內置函數對比(生產環境首選)

函數用途限制
bindec()二進制→十進制僅整數,字符串參數
octdec()八進制→十進制僅整數
hexdec()十六進制→十進制僅整數,支援大數字
base_convert()任意進制互轉 (2-36)大數字可能丟失精度(浮點運算),不支援小數
intval($str, $base)字符串按進制解析為整數2-36進制,忽略非法字符,不報錯

精度陷阱與 BCMath 解決方案

<?php
// base_convert 大數字精度問題
$bigHex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
echo base_convert($bigHex, 16, 10); // 可能科學計數法或不精確

// BCMath 高精度
function bcBaseConvert(string $num, int $fromBase, int $toBase): string {
    // 先轉十進制(BCMath 字符串運算)
    $dec = '0';
    $pow = '1';
    $num = strrev(strtoupper($num));
    for ($i = 0; $i < strlen($num); $i++) {
        $digit = charToValue($num[$i]);
        $dec = bcadd($dec, bcmul((string)$digit, $pow));
        $pow = bcmul($pow, (string)$fromBase);
    }
    // 十進制轉目標進制
    if ($dec === '0') return '0';
    $result = '';
    while (bccomp($dec, '0') > 0) {
        $rem = bcmod($dec, (string)$toBase);
        $result = valueToChar((int)$rem) . $result;
        $dec = bcdiv($dec, (string)$toBase, 0);
    }
    return $result;
}

echo bcBaseConvert($bigHex, 16, 10); // 精確完整輸出
?>

應用場景

  1. 教學演示:展示位權展開過程,輔助理解進制本質。
  2. 自定義編碼解碼:Base32、Base58、Base62(短鏈接 ID)等非標準進制。
  3. 協議解析:嵌入式設備、舊系統數據交換中的特殊進制字段。
  4. 哈希/校驗碼驗證:手動驗證 CRC、校驗和算法中的進制運算。

掌握通用進制轉換邏輯,能應對各類非標準編碼場景,也是理解計算機數值表示的基礎功底。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved