進制轉換是計算機科學基礎,也是面試高頻考點。本文從**除基取餘法**原理出發,實現十進制轉二進制、八進制、十六進制的手動算法,並對比 Java 標準庫 API 的最佳實踐。
將十進制整數 $N$ 轉為 $b$ 進制:
例:$13_{10} \to 2$ 進制
13 ÷ 2 = 6 餘 1 6 ÷ 2 = 3 餘 0 3 ÷ 2 = 1 餘 1 1 ÷ 2 = 0 餘 1 讀餘數逆序:1101₂
import java.util.Scanner;
public class BaseConverter {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("輸入十進制整數 (0 退出):");
while (true) {
int n = sc.nextInt();
if (n == 0) break;
toBinary(n);
toOctal(n);
toHex(n);
}
}
// 通用轉換邏輯:基數 2-36
public static String convert(int num, int base) {
if (num == 0) return "0";
boolean negative = num < 0;
if (negative) num = -num;
StringBuilder sb = new StringBuilder();
while (num > 0) {
int rem = num % base;
char c = (rem < 10) ? (char)('0' + rem) : (char)('A' + rem - 10);
sb.append(c);
num /= base;
}
if (negative) sb.append('-');
return sb.reverse().toString();
}
public static void toBinary(int n) {
System.out.println("二進制: " + convert(n, 2));
}
public static void toOctal(int n) {
System.out.println("八進制: " + convert(n, 8));
}
public static void toHex(int n) {
System.out.println("十六進制: " + convert(n, 16));
}
}
// 餘數 0-9 → '0'-'9'
// 餘數 10-35 → 'A'-'Z' (支援最高 36 進制)
char digit = (rem < 10) ? (char)('0' + rem) : (char)('A' + rem - 10);
餘數產生順序為**低位在前**,`StringBuilder.append()` 後 `reverse()` 最高效 (O(N) 時間、O(N) 空間)。
| 需求 | 方法 | 範例輸出 | 備註 |
|---|---|---|---|
| int → 二進制字串 | `Integer.toBinaryString(n)` | `1101` | 無前綴、負數輸出 32 位補碼 |
| int → 八進制字串 | `Integer.toOctalString(n)` | `15` | 無前綴 |
| int → 十六進制字串 | `Integer.toHexString(n)` | `d` | 小寫、無前綴 |
| 任意基數 2-36 | `Integer.toString(n, base)` | `Integer.toString(13, 2) → "1101"` | 通用、負數帶 `-` |
| 長整型 | `Long.toBinaryString(n)` 等 | 同 int | 64 位補碼 |
| BigInteger | `bigInt.toString(base)` | 任意精度 | 大數轉換 |
| 格式化輸出 (含前綴) | `String.format("%#x", n)` | `0xd` | `#` 旗標加前綴 `0x`/`0`/`0b` |
int n = 13;
System.out.printf("二進制: %s%n", Integer.toBinaryString(n)); // 1101
System.out.printf("八進制: %#o%n", n); // 015
System.out.printf("十六進制: %#x%n", n); // 0xd
System.out.printf("十六進制大寫: %#X%n", n); // 0XD
System.out.printf("帶符號十六進制: %+#x%n", n); // +0xd
// 指定基數解析
int n1 = Integer.parseInt("1101", 2); // 13
int n2 = Integer.parseInt("15", 8); // 13
int n3 = Integer.parseInt("D", 16); // 13
int n4 = Integer.parseInt("-1101", 2); // -13
// 自動檢測前綴 (Java 8+)
int n5 = Integer.decode("0x1D"); // 29 (0x/0X 十六進制)
int n6 = Integer.decode("#1D"); // 29 (# 十六進制)
int n7 = Integer.decode("015"); // 13 (0 八進制)
// 注意:decode 不支援 0b 二進制前綴
| 方法 | 相對吞吐量 (ops/ms) | 適用場景 |
|---|---|---|
| `Integer.toBinaryString` | 1.00 (基準) | 生產代碼、高頻調用 |
| `Integer.toString(n, 2)` | 0.95 | 通用基數轉換 |
| 手動 StringBuilder | 0.60 | 教學、自定義字元集、非標準基數 |
| `String.format` | 0.15 | 低頻、需格式化輸出 |
掌握「除基取餘」手動實現能深入理解計算機數制本質;實際開發中,**優先使用 `Integer.toXxxString` / `toString(radix)`**,兼具效能、正確性與可讀性。面試時手寫通用 `convert(num, base)` 展示基本功,生產代碼呼叫標準庫展示工程素養。