Skip to main content

高精度算法

·722 words·4 mins
WFUing
Author
WFUing
A graduate who loves coding.
Table of Contents

高精度乘法
#

import java.util.*;

public class Main {
    
    public static String mulNums(String a, String b) {
        // Create an array to store multiplication results
        int[] res = new int[a.length() + b.length() - 1];
        // Populate the result array with products of digits
        for (int i = 0; i < a.length(); i++) {
            for (int j = 0; j < b.length(); j++) {
                res[i + j] += (a.charAt(i) - '0') * (b.charAt(j) - '0');
            }
        }
        
        // Convert the result array into the final result string
        StringBuilder ret = new StringBuilder();
        int carry = 0;
        for (int i = res.length - 1; i >= 0; i--) {
            int num = res[i] + carry;
            ret.insert(0, (char) (num % 10 + '0'));
            carry = num / 10;
        }
        // Add remaining carry if present
        if (carry > 0)
            ret.insert(0, (char) (carry + '0'));
        return ret.toString();
    }

    public static void main(String[] args) {
        System.out.println(mulNums("12345", "67890111"));
    }
}

高精度除法
#

import java.math.BigInteger;

public class HighPrecisionDivision {

    public static String divideNumbers(String dividend, String divisor) {
        // Convert strings to BigInteger for handling large numbers
        BigInteger bigDividend = new BigInteger(dividend);
        BigInteger bigDivisor = new BigInteger(divisor);
        
        // Perform division and get the quotient
        BigInteger quotient = bigDividend.divide(bigDivisor);
        
        // Return the quotient as a string
        return quotient.toString();
    }

    public static void main(String[] args) {
        String dividend = "12345678901234567890";
        String divisor = "12345";
        System.out.println("Quotient: " + divideNumbers(dividend, divisor));
    }
}
public class HighPrecisionDivision {

    public static String divide(String dividend, String divisor, int scale) {
        // 移除小数点并记录小数点扩展的位数
        int scaleDividend = dividend.indexOf('.');
        int scaleDivisor = divisor.indexOf('.');
        int decimalPlaces = 0;

        if (scaleDividend != -1) {
            decimalPlaces += (dividend.length() - scaleDividend - 1);
            dividend = dividend.replace(".", "");
        }
        if (scaleDivisor != -1) {
            decimalPlaces -= (divisor.length() - scaleDivisor - 1);
            divisor = divisor.replace(".", "");
        }

        // 处理结果的小数点位置
        decimalPlaces -= scale;

        // 用于收集结果的StringBuilder
        StringBuilder result = new StringBuilder();

        // 高精度的除法核心
        StringBuilder part = new StringBuilder();
        int index = 0;
        while (index < dividend.length()) {
            part.append(dividend.charAt(index));
            while (new BigInteger(part.toString()).compareTo(new BigInteger(divisor)) < 0 && index < dividend.length() - 1) {
                part.append(dividend.charAt(++index));
                if (result.length() != 0) result.append("0");
            }
            BigInteger[] divisionResult = new BigInteger(part.toString()).divideAndRemainder(new BigInteger(divisor));
            result.append(divisionResult[0].toString());
            part = new StringBuilder(divisionResult[1].toString());
            index++;
        }

        // 处理余数部分以生成所需精度的小数
        if (scale > 0) {
            result.append('.');
            for (int i = 0; i < scale; i++) {
                part.append("0");
                BigInteger[] divisionResult = new BigInteger(part.toString()).divideAndRemainder(new BigInteger(divisor));
                result.append(divisionResult[0].toString());
                part = new StringBuilder(divisionResult[1].toString());
            }
        }

        // 调整小数点的最终位置
        if (decimalPlaces > 0) {
            result.append("0".repeat(decimalPlaces));
        } else if (decimalPlaces < 0) {
            result.insert(result.length() + decimalPlaces, '.');
        }

        return result.toString();
    }

    public static void main(String[] args) {
        String dividend = "12345.678";
        String divisor = "12.345";
        String result = divide(dividend, divisor, 10);  // 设置小数点后的精度为10位
        System.out.println("Result: " + result);
    }
}

高精度加减法
#

public class HighPrecisionArithmetic {

    // 高精度加法
    public static String add(String num1, String num2) {
        StringBuilder result = new StringBuilder();
        int carry = 0;  // 进位

        // 对齐两个字符串的长度
        int maxLen = Math.max(num1.length(), num2.length());
        num1 = String.format("%" + maxLen + "s", num1).replace(' ', '0');
        num2 = String.format("%" + maxLen + "s", num2).replace(' ', '0');

        // 从右向左逐位相加
        for (int i = maxLen - 1; i >= 0; i--) {
            int digit1 = num1.charAt(i) - '0';
            int digit2 = num2.charAt(i) - '0';
            int sum = digit1 + digit2 + carry;
            carry = sum / 10;
            result.append(sum % 10);
        }

        // 如果最后还有进位,需要添加到结果的最前面
        if (carry != 0) {
            result.append(carry);
        }

        return result.reverse().toString();
    }

    // 高精度减法
    public static String subtract(String num1, String num2) {
        // 确定哪个数字大,以决定结果的正负
        boolean negative = false;
        if (num1.length() < num2.length() || (num1.length() == num2.length() && num1.compareTo(num2) < 0)) {
            String temp = num1;
            num1 = num2;
            num2 = temp;
            negative = true; // 结果为负数
        }

        StringBuilder result = new StringBuilder();
        int borrow = 0;  // 借位

        // 对齐两个字符串的长度
        int maxLen = Math.max(num1.length(), num2.length());
        num1 = String.format("%" + maxLen + "s", num1).replace(' ', '0');
        num2 = String.format("%" + maxLen + "s", num2).replace(' ', '0');

        // 从右向左逐位相减
        for (int i = maxLen - 1; i >= 0; i--) {
            int digit1 = num1.charAt(i) - '0';
            int digit2 = num2.charAt(i) - '0' + borrow;
            if (digit1 < digit2) {
                digit1 += 10;
                borrow = 1;
            } else {
                borrow = 0;
            }
            result.append(digit1 - digit2);
        }

        // 移除结果前端的零
        while (result.length() > 1 && result.charAt(result.length() - 1) == '0') {
            result.deleteCharAt(result.length() - 1);
        }

        if (negative) {
            result.append('-');
        }

        return result.reverse().toString();
    }

    public static void main(String[] args) {
        System.out.println("Addition: " + add("1234567890", "987654321"));
        System.out.println("Subtraction: " + subtract("1234567890", "987654321"));
    }
}

💬评论