package biginteger;
import java.util.Arrays;
/**
* 大整数类,支持符号和任意精度的整数运算
* 使用倒序数组存储数字(个位在索引0位置)
*/
public class testBigInteger {
private int[] digits; // 数字的倒序数组表示
private boolean isNegative; // 符号标志:true表示负数,false表示正数
/**
* 构造函数 - 从字符串构造大整数
* @param numberStr 数字字符串,可包含正负号
*/
public testBigInteger(String numberStr) {
if (numberStr == null || numberStr.isEmpty()) {
throw new IllegalArgumentException("Number string cannot be null or empty");
}
// 处理符号
if (numberStr.charAt(0) == '-') {
this.isNegative = true;
numberStr = numberStr.substring(1);
} else if (numberStr.charAt(0) == '+') {
this.isNegative = false;
numberStr = numberStr.substring(1);
} else {
this.isNegative = false;
}
// 去除前导零
numberStr = removeLeadingZeros(numberStr);
if (numberStr.isEmpty()) {
// 如果去除前导零后为空,说明是0
this.digits = new int[]{0};
this.isNegative = false; // 0没有负号
return;
}
// 转换为倒序数组
this.digits = stringToReverseArray(numberStr);
}
/**
* 构造函数 - 从倒序数组和符号构造大整数
* @param digits 数字的倒序数组
* @param isNegative 是否为负数
*/
public testBigInteger(int[] digits, boolean isNegative) {
this.digits = removeLeadingZeros(digits);
this.isNegative = isNegative;
// 如果是0,确保不是负数
if (isZero()) {
this.isNegative = false;
}
}
/**
* 拷贝构造函数
* @param other 另一个大整数
*/
public testBigInteger(testBigInteger other) {
this.digits = Arrays.copyOf(other.digits, other.digits.length);
this.isNegative = other.isNegative;
}
/**大数法乘法
*
* @param other
* @return 两个大整数的积
*/
public testBigInteger multipy(testBigInteger other){
int[] result = multipyBigInteger(this.digits,other.digits);
boolean resultNegative = this.isNegative != other.isNegative;
return new testBigInteger(result,resultNegative);
}
/**
* 大整数加法
* @param other 另一个大整数
* @return 两个大整数的和
*/
public testBigInteger add(testBigInteger other) {
// 同号相加
if (this.isNegative == other.isNegative) {
int[] resultDigits = addAbsolute(this.digits, other.digits);
return new testBigInteger(resultDigits, this.isNegative);
}
// 异号相加转换为减法
if (compareAbsolute(this.digits, other.digits) >= 0) {
int[] resultDigits = subtractAbsolute(this.digits, other.digits);
return new testBigInteger(resultDigits, this.isNegative);
} else {
int[] resultDigits = subtractAbsolute(other.digits, this.digits);
return new testBigInteger(resultDigits, other.isNegative);
}
}
/**
* 大整数减法
* @param other 另一个大整数
* @return 两个大整数的差
*/
public testBigInteger subtract(testBigInteger other) {
// 转换为加上相反数
testBigInteger negatedOther = new testBigInteger(other.digits, !other.isNegative);
return this.add(negatedOther);
}
/**
* 大整数拆分
* @param num 一个大整数
* @return 分治后的两个局部大整数
*/
public static testBigInteger[] splitNumber(testBigInteger num) {
int n = num.digits.length;
int mid = n/2;
int[] low = Arrays.copyOfRange(num.digits,0,mid);
int[] high = Arrays.copyOfRange(num.digits,mid,n);
testBigInteger lowpart = new testBigInteger(low,false);
testBigInteger highpart = new testBigInteger(high,false);
return new testBigInteger[]{lowpart,highpart};
}
/**
* Karatsuba算法
* @param other 另一个大整数
* @return 乘法得到的结果
*/
public testBigInteger karatsubamultiply(testBigInteger other){
testBigInteger[] p1 = splitNumber(this);
testBigInteger p1Low = p1[0];
testBigInteger p1High = p1[1];
testBigInteger[] p2 = splitNumber(other);
testBigInteger p2Low = p2[0];
testBigInteger p2High = p2[1];
testBigInteger z1 = p1High.multipy(p2High);
testBigInteger z2 = p1Low.multipy(p2Low);
testBigInteger z3 = (p1High.add(p1Low)).multipy(p2High.add(p2Low));
testBigInteger middle = z3.subtract(z2).subtract(z1);
int n =this.digits.length;
int m =n/2;
testBigInteger result = z1.shiftLeft(2*m).add(middle.shiftLeft(m)).add(z2);
return result;
}
/**
* 左移操作
* @param m 进位的多少
* @return 返回数组*10^m次方后的结果
*/
public testBigInteger shiftLeft(int m) {
if(m==0) return this;
int[] newDigits = new int[this.digits.length+m] ;
System.arraycopy(this.digits,0,newDigits,0,this.digits.length);
return new testBigInteger(newDigits,false);}
/**
* 判断是否为零
* @return 如果是零返回true,否则返回false
*/
public boolean isZero() {
for (int digit : digits) {
if (digit != 0) return false;
}
return true;
}
/**
* 获取符号
* @return 如果是负数返回-1,如果是正数返回1,如果是0返回0
*/
public int signum() {
if (isZero()) return 0;
return isNegative ? -1 : 1;
}
/**
* 取相反数
* @return 当前大整数的相反数
*/
public testBigInteger negate() {
if (isZero()) {
return this;
}
return new testBigInteger(this.digits, !this.isNegative);
}
/**
* 取绝对值
* @return 当前大整数的绝对值
*/
public testBigInteger abs() {
if (!isNegative) {
return this;
}
return new testBigInteger(this.digits, false);
}
/**
* 比较两个大整数的大小
* @param other 另一个大整数
* @return 如果当前数大于other返回1,等于返回0,小于返回-1
*/
public int compareTo(testBigInteger other) {
if (this.isNegative && !other.isNegative) return -1;
if (!this.isNegative && other.isNegative) return 1;
int absCompare = compareAbsolute(this.digits, other.digits);
if (this.isNegative) {
return -absCompare;
} else {
return absCompare;
}
}
/**
* 转换为字符串表示
* @return 大整数的字符串表示
*/
@Override
public String toString() {
if (isZero()) {
return "0";
}
StringBuilder sb = new StringBuilder();
if (isNegative) {
sb.append('-');
}
// 从最高位开始输出
for (int i = digits.length - 1; i >= 0; i--) {
sb.append(digits[i]);
}
return sb.toString();
}
/**
* 判断是否相等
* @param obj 要比较的对象
* @return 如果相等返回true,否则返回false
*/
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
testBigInteger other = (testBigInteger) obj;
return this.isNegative == other.isNegative &&
Arrays.equals(this.digits, other.digits);
}
// ========== 私有辅助方法 ==========
private static int[] multipyBigInteger(int[]a,int[]b){
int n = a.length+b.length;
int[] result =new int[n];
for(int i = 0;i<a.length;i++){
for(int j = 0 ; j<b.length;j++)
{
result[i+j]+=a[i]*b[j];
}
}
int carry = 0;
for(int i =0;i<result.length;i++)
{
int total;
result[i]+=carry;
total = result[i];
carry = total/10;
result[i] = total%10;
}
return removeLeadingZeros(result);
}
/**
* 绝对值加法
*/
private static int[] addAbsolute(int[] a, int[] b) {
int maxLen = Math.max(a.length, b.length);
int[] result = new int[maxLen + 1];
int carry = 0;
for (int i = 0; i < maxLen; i++) {
int digitA = (i < a.length) ? a[i] : 0;
int digitB = (i < b.length) ? b[i] : 0;
int sum = digitA + digitB + carry;
result[i] = sum % 10;
carry = sum / 10;
}
if (carry > 0) {
result[maxLen] = carry;
return result;
} else {
return Arrays.copyOf(result, maxLen);
}
}
/**
* 绝对值减法 (a >= b)
*/
private static int[] subtractAbsolute(int[] a, int[] b) {
int maxLen = Math.max(a.length, b.length);
int[] result = new int[maxLen];
int borrow = 0;
for (int i = 0; i < maxLen; i++) {
int digitA = (i < a.length) ? a[i] : 0;
int digitB = (i < b.length) ? b[i] : 0;
int diff = digitA - digitB - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
result[i] = diff;
}
return removeLeadingZeros(result);
}
/**
* 比较两个绝对值的大小
*/
private static int compareAbsolute(int[] a, int[] b) {
int lenA = a.length;
int lenB = b.length;
if (lenA > lenB) return 1;
if (lenA < lenB) return -1;
// 长度相等,从最高位开始比较
for (int i = lenA - 1; i >= 0; i--) {
if (a[i] > b[i]) return 1;
if (a[i] < b[i]) return -1;
}
return 0; // 相等
}
/**
* 去除数组前导零
*/
private static int[] removeLeadingZeros(int[] arr) {
int i = arr.length - 1;
while (i > 0 && arr[i] == 0) {
i--;
}
return Arrays.copyOf(arr, i + 1);
}
/**
* 去除字符串前导零
*/
private static String removeLeadingZeros(String str) {
int i = 0;
while (i < str.length() - 1 && str.charAt(i) == '0') {
i++;
}
return str.substring(i);
}
/**
* 字符串转换为倒序数组
*/
private static int[] stringToReverseArray(String numStr) {
int[] arr = new int[numStr.length()];
for (int i = 0; i < numStr.length(); i++) {
char c = numStr.charAt(i);
if (c < '0' || c > '9') {
throw new IllegalArgumentException("Invalid digit: " + c);
}
arr[numStr.length() - 1 - i] = c - '0';
}
return arr;
}
// ========== 测试代码 ==========
public static void main(String[] args) {
// 测试基本功能
testBasicOperations();
// 测试大数运算
testLargeNumberOperations();
// 测试边界情况
testEdgeCases();
// 测试乘法
testMultiplication();
// 测试Karastsuba算法
testKaratsubaCases();
}
private static void testBasicOperations() {
System.out.println("=== 基本功能测试 ===");
testBigInteger a = new testBigInteger("123");
testBigInteger b = new testBigInteger("456");
// 加法测试
testBigInteger sum = a.add(b);
System.out.println(a + " + " + b + " = " + sum);
// 减法测试
testBigInteger diff = b.subtract(a);
System.out.println(b + " - " + a + " = " + diff);
// 符号测试
testBigInteger negativeA = new testBigInteger("-123");
System.out.println("负号测试: " + negativeA);
// 比较测试
System.out.println(a + " compareTo " + b + " = " + a.compareTo(b));
System.out.println(b + " compareTo " + a + " = " + b.compareTo(a));
System.out.println(a + " compareTo " + a + " = " + a.compareTo(a));
System.out.println();
}
private static void testLargeNumberOperations() {
System.out.println("=== 大数运算测试 ===");
String num1 = "9876543210123456789";
String num2 = "1234567890123456789";
testBigInteger a = new testBigInteger(num1);
testBigInteger b = new testBigInteger(num2);
System.out.println("数字1: " + a);
System.out.println("数字2: " + b);
// 加法
testBigInteger sum = a.add(b);
System.out.println("加法结果: " + sum);
// 减法
testBigInteger diff1 = a.subtract(b);
testBigInteger diff2 = b.subtract(a);
System.out.println("减法结果1: " + diff1);
System.out.println("减法结果2: " + diff2);
// 负数运算
testBigInteger negativeA = new testBigInteger("-" + num1);
testBigInteger negativeB = new testBigInteger("-" + num2);
System.out.println("负数加法: " + negativeA + " + " + negativeB + " = " + negativeA.add(negativeB));
System.out.println("负数减法: " + negativeA + " - " + negativeB + " = " + negativeA.subtract(negativeB));
System.out.println();
}
private static void testEdgeCases() {
System.out.println("=== 边界情况测试 ===");
// 零测试
testBigInteger zero = new testBigInteger("0");
testBigInteger num = new testBigInteger("123");
System.out.println("零加法: " + zero + " + " + num + " = " + zero.add(num));
System.out.println("零减法: " + num + " - " + zero + " = " + num.subtract(zero));
System.out.println("零的符号: " + zero.signum());
// 负零测试(应该自动转为正零)
testBigInteger negativeZero = new testBigInteger("-0");
System.out.println("负零自动转为: " + negativeZero);
// 前导零测试
testBigInteger withLeadingZeros = new testBigInteger("00000123");
System.out.println("前导零处理: " + withLeadingZeros);
// 绝对值测试
testBigInteger negativeNum = new testBigInteger("-456");
System.out.println("绝对值: " + negativeNum.abs());
// 相反数测试
System.out.println("相反数: " + num.negate() + ", " + negativeNum.negate());
System.out.println();
}
private static void testMultiplication() {
System.out.println("=== 乘法测试 ===");
// 基本测试
testCaseMultiply("12", "13", "156");
testCaseMultiply("0", "12345", "0");
testCaseMultiply("999", "0", "0");
// 符号测试
testCaseMultiply("-5", "6", "-30");
testCaseMultiply("7", "-8", "-56");
testCaseMultiply("-9", "-10", "90");
// 大数测试
testCaseMultiply("123456789", "987654321", "121932631112635269");
testCaseMultiply(
"999999999999999999999999999999",
"555555555555555555555555555555",
"555555555555555555555555555554444444444444444444444444444445"
);
// 前导零测试
testCaseMultiply("000123", "000456", "56088");
System.out.println();
}
private static void testCaseMultiply(String num1, String num2, String expected) {
testBigInteger a = new testBigInteger(num1);
testBigInteger b = new testBigInteger(num2);
testBigInteger product = a.multipy(b);
String result = product.toString();
System.out.printf("%s * %s = %s", a, b, result);
if (!result.equals(expected)) {
System.out.printf(" ✗ 错误!期望值: %s", expected);
}
System.out.println();
}
private static void testKaratsubaCases() {
System.out.println("=== Karatsuba 算法测试用例 ===");
// 1. 基础功能测试
System.out.println("\n--- 基础乘法测试 ---");
testBigInteger a = new testBigInteger("1234");
testBigInteger b = new testBigInteger("5678");
testBigInteger karatsubaResult = a.karatsubamultiply(b);
testBigInteger traditionalResult = a.multipy(b);
System.out.println("Karatsuba: " + a + " × " + b + " = " + karatsubaResult);
System.out.println("传统方法: " + traditionalResult);
System.out.println("结果一致: " + karatsubaResult.toString().equals(traditionalResult.toString()));
// 2. 边界情况测试
System.out.println("\n--- 边界情况测试 ---");
// 零乘法测试
testBigInteger zero = new testBigInteger("0");
testBigInteger num = new testBigInteger("9876");
System.out.println("零乘法: " + zero + " × " + num + " = " + zero.karatsubamultiply(num));
System.out.println("数乘零: " + num + " × " + zero + " = " + num.karatsubamultiply(zero));
System.out.println("零的符号: " + zero.signum());
// 1乘法测试(单位元)
testBigInteger one = new testBigInteger("1");
System.out.println("单位元: " + num + " × " + one + " = " + num.karatsubamultiply(one));
// 3. 负数测试
System.out.println("\n--- 负数运算测试 ---");
testBigInteger negA = new testBigInteger("-1234");
testBigInteger negB = new testBigInteger("-5678");
System.out.println("正×负: " + a + " × " + negB + " = " + a.karatsubamultiply(negB));
System.out.println("负×正: " + negA + " × " + b + " = " + negA.karatsubamultiply(b));
System.out.println("负×负: " + negA + " × " + negB + " = " + negA.karatsubamultiply(negB));
System.out.println("负零测试: " + zero.negate() + " × " + num + " = " + zero.negate().karatsubamultiply(num));
// 4. 大数性能测试
System.out.println("\n--- 大数性能对比测试 ---");
testBigInteger largeA = new testBigInteger("123456789012345678901234567890");
testBigInteger largeB = new testBigInteger("987654321098765432109876543210");
long startTime, endTime;
// Karatsuba 时间测试
startTime = System.nanoTime();
testBigInteger largeKaratsuba = largeA.karatsubamultiply(largeB);
endTime = System.nanoTime();
double karatsubaTime = (endTime - startTime) / 1_000_000.0; // ms
// 传统方法时间测试(仅小数)
if (largeA.digits.length <= 10 && largeB.digits.length <= 10) {
startTime = System.nanoTime();
testBigInteger largeTraditional = largeA.multipy(largeB);
endTime = System.nanoTime();
double traditionalTime = (endTime - startTime) / 1_000_000.0; // ms
System.out.println("大数结果: " + largeKaratsuba);
System.out.println("Karatsuba耗时: " + String.format("%.3f", karatsubaTime) + "ms");
System.out.println("传统方法耗时: " + String.format("%.3f", traditionalTime) + "ms");
System.out.println("加速比: " + String.format("%.2fx", traditionalTime/karatsubaTime));
} else {
System.out.println("大数: " + largeKaratsuba);
System.out.println("Karatsuba耗时: " + String.format("%.3f", karatsubaTime) + "ms");
System.out.println("传统方法跳过(数字过大)");
}
}
}
karatsuba算法结果错误
最新发布