Java 基本類型 long 最大 9.22e18,double 53 位有效數字約 15-16 位十進制精度。當涉及超大整數(百位以上)精確運算或金融級定點小數運算時,必須實現手工模擬乘法邏輯。
int[],每元素存一位(0-9)result[i+j] += a[i] * b[j]carry = result[k] / 10; result[k] %= 10public static String multiplyLargeIntegers(String num1, String num2) {
int[] a = toDigitArray(num1); // 低位在前
int[] b = toDigitArray(num2);
int[] res = new int[a.length + b.length]; // 最大長度
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
res[i + j] += a[i] * b[j];
}
}
// 統一進位
for (int k = 0; k < res.length; k++) {
int carry = res[k] / 10;
res[k] %= 10;
if (k + 1 < res.length) res[k + 1] += carry;
}
// 去除前導零並構建字符串
StringBuilder sb = new StringBuilder();
boolean leading = true;
for (int i = res.length - 1; i >= 0; i--) {
if (leading && res[i] == 0) continue;
leading = false;
sb.append(res[i]);
}
return sb.length() == 0 ? "0" : sb.toString();
}
d1、d2i1、i2productd1 + d2public static String multiplyDecimals(String num1, String num2) {
// 1. 符號處理
boolean neg = false;
if (num1.startsWith("-")) { neg = !neg; num1 = num1.substring(1); }
if (num2.startsWith("-")) { neg = !neg; num2 = num2.substring(1); }
// 2. 分離小數位
int d1 = decimalDigits(num1);
int d2 = decimalDigits(num2);
String i1 = removeDecimalPoint(num1);
String i2 = removeDecimalPoint(num2);
// 3. 大整數相乘
String product = multiplyLargeIntegers(i1, i2);
// 4. 插入小數點
int totalDec = d1 + d2;
if (totalDec > 0) {
if (product.length() <= totalDec) {
product = "0".repeat(totalDec - product.length() + 1) + product;
}
product = product.substring(0, product.length() - totalDec) + "."
+ product.substring(product.length() - totalDec);
}
// 5. 去除尾部零 & 標準化
product = product.replaceFirst("\\.?0+$", ""); // 移除小數點後多餘零
if (product.startsWith(".")) product = "0" + product;
if (product.endsWith(".")) product = product.substring(0, product.length() - 1);
return neg ? "-" + product : product;
}
public static void main(String[] args) {
// 大整數測試
String a = "123456789012345678901234567890";
String b = "987654321098765432109876543210";
System.out.println("大整數乘積長度: " + multiplyLargeIntegers(a, b).length()); // 60 位
// 浮點數測試(對比 Python 高精度)
String x = "-23424.2300";
String y = "02345.23400000";
String javaResult = multiplyDecimals(x, y);
// Python: -23424.2300 * 02345.23400000 = -54935300.619819999
System.out.println("Java 手工: " + javaResult);
// 預期: -54935300.61982 (尾部零已移除)
}
| 優化點 | 說明 | 複雜度提升 |
|---|---|---|
| Karatsuba 算法 | 分治遞歸,減少乘法次數 | O(n^1.585) |
| FFT/NTT 乘法 | 數論變換/快速傅里葉,極大數(萬位+) | O(n log n) |
| 基數優化 | 每元素存 4 位(基數 10000)或 9 位(基數 1e9),減少數組長度 | 常數倍加速 |
| 原地運算 | 複用數組,減少 GC 壓力 | 記憶體友好 |
java.math.BigInteger / BigDecimal:經過嚴格測試、JIT 優化、安全審計手工實現大數/浮點乘法是理解計算機算術基礎的優秀練習。通過「字符串→數組→豎式乘法→進位→格式化」的流程,可清晰掌握任意精度運算的核心邏輯。實際工程中,請擁抱 BigDecimal,並配合 MathContext 控制精度與捨入模式。