【js】js高精度加减乘除函数

加法

/**
 * 高精度加法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 被加数
 * @param {string|number} b - 加数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const add = (a, b) => {
    // 将输入转换为字符串
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    // 分割整数部分和小数部分
    let [intA = '0', decA = '0'] = a.split('.');
    let [intB = '0', decB = '0'] = b.split('.');
    // 去除小数部分可能为空的情况
    decA = decA || '0';
    decB = decB || '0';
    // 将小数部分补齐到相同长度
    const maxDecLen = Math.max(decA.length, decB.length);
    decA = decA.padEnd(maxDecLen, '0');
    decB = decB.padEnd(maxDecLen, '0');
    // 初始化进位
    let carry = 0;
    let resultDec = '';
    // 从小数部分开始逐位相加
    for (let i = maxDecLen - 1; i >= 0; i--) {
        let sum = parseInt(decA[i]) + parseInt(decB[i]) + carry;
        carry = Math.floor(sum / 10);
        resultDec = (sum % 10) + resultDec;
    }
    // 处理整数部分
    let resultInt = '';
    intA = intA.padStart(Math.max(intA.length, intB.length), '0');
    intB = intB.padStart(Math.max(intA.length, intB.length), '0');
    // 从整数部分开始逐位相加
    for (let i = intA.length - 1; i >= 0; i--) {
        let sum = parseInt(intA[i]) + parseInt(intB[i]) + carry;
        carry = Math.floor(sum / 10);
        resultInt = (sum % 10) + resultInt;
    }
    // 如果还有进位,添加到结果的开头
    if (carry) resultInt = carry + resultInt;
    // 去除结果整数部分的前导零
    resultInt = resultInt.replace(/^0+/, '');
    if (resultInt === '') resultInt = '0';
    // 拼接结果,处理小数部分尾部多余的零
    let result = resultInt + (resultDec !== '0' ? '.' + resultDec.replace(/0+$/, '') : '');
    return result;
};

减法

/**
 * 高精度减法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 被减数
 * @param {string|number} b - 减数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const subtract = (a, b) => {
    // 将输入转换为字符串
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    // 分割整数部分和小数部分
    let [intA = '0', decA = '0'] = a.split('.');
    let [intB = '0', decB = '0'] = b.split('.');
    // 去除小数部分可能为空的情况
    decA = decA || '0';
    decB = decB || '0';
    // 将小数部分补齐到相同长度
    const maxDecLen = Math.max(decA.length, decB.length);
    decA = decA.padEnd(maxDecLen, '0');
    decB = decB.padEnd(maxDecLen, '0');
    // 初始化借位
    let borrow = 0;
    let resultDec = '';
    // 从小数部分开始逐位相减
    for (let i = maxDecLen - 1; i >= 0; i--) {
        let diff = parseInt(decA[i]) - parseInt(decB[i]) - borrow;
        if (diff < 0) {
            diff += 10;
            borrow = 1;
        } else {
            borrow = 0;
        }
        resultDec = diff + resultDec;
    }
    // 处理整数部分
    let resultInt = '';
    intA = intA.padStart(Math.max(intA.length, intB.length), '0');
    intB = intB.padStart(Math.max(intA.length, intB.length), '0');
    // 从整数部分开始逐位相减
    for (let i = intA.length - 1; i >= 0; i--) {
        let diff = parseInt(intA[i]) - parseInt(intB[i]) - borrow;
        if (diff < 0) {
            diff += 10;
            borrow = 1;
        } else {
            borrow = 0;
        }
        resultInt = diff + resultInt;
    }
    // 去除结果整数部分的前导零
    resultInt = resultInt.replace(/^0+/, '');
    if (resultInt === '') resultInt = '0';
    // 拼接结果,处理小数部分尾部多余的零
    let result = resultInt + (resultDec !== '0' ? '.' + resultDec.replace(/0+$/, '') : '');
    return result;
};

乘法

/**
 * 高精度乘法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 乘数
 * @param {string|number} b - 被乘数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
const multiply = (a, b) => {
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    let [intA, decA] = a.split('.');
    let [intB, decB] = b.split('.');
    decA = decA || '0';
    decB = decB || '0';
    const totalDecLen = decA.length + decB.length;
    const intPartA = intA + decA;
    const intPartB = intB + decB;
    let result = Array(intPartA.length + intPartB.length).fill(0);
    for (let i = intPartA.length - 1; i >= 0; i--) {
        for (let j = intPartB.length - 1; j >= 0; j--) {
            let product = parseInt(intPartA[i]) * parseInt(intPartB[j]) + result[i + j + 1];
            result[i + j + 1] = product % 10;
            result[i + j] += Math.floor(product / 10);
        }
    }
    result = result.join('').replace(/^0+/, '');
    if (totalDecLen > 0) {
        const integerLen = result.length - totalDecLen;
        if (integerLen <= 0) {
            result = '0.' + '0'.repeat(-integerLen) + result;
        } else {
            result = result.slice(0, integerLen) + '.' + result.slice(integerLen);
        }
        result = result.replace(/(\.[0-9]*?)0+$/, '$1').replace(/\.$/, '');
    } else {
        result = result || '0';
    }
    return result;
};

除法

/**
 * 高精度除法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} dividend - 被除数
 * @param {string|number} divisor - 除数
 * @param {number} precision - 结果保留的小数位数,默认为 28
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const highPrecisionDivision = (dividend, divisor, precision = 28) => {
    const dividendStr = String(dividend);
    const divisorStr = String(divisor);
    let [dividendInt = '0', dividendDec = ''] = dividendStr.split('.');
    let [divisorInt = '0', divisorDec = ''] = divisorStr.split('.');
    const maxDecLength = Math.max(dividendDec.length, divisorDec.length, precision);
    dividendDec = dividendDec.padEnd(maxDecLength, '0');
    divisorDec = divisorDec.padEnd(maxDecLength, '0');
    const dividendFull = dividendInt + '.' + dividendDec;
    const divisorFull = divisorInt + '.' + divisorDec;
    const bigDividend = parseFloat(dividendFull);
    const bigDivisor = parseFloat(divisorFull);
    let result = (bigDividend / bigDivisor).toFixed(precision);
    // 去除尾部多余的零
    result = result.replace(/\.?0+$/, '');
    return result;
};
add(0.1, "0.3") // 0.4
add(0.1, 0.3) // 0.4
add(0.1687486415614614, 0.3) // 0.4687486415614614
add("5614", "999999999999999991454444444444444444444444444444") // 999999999999999991454444444444444444444444450058


subtract("5", "3") // 2
subtract(123.45, "67.89") // 55.56
subtract('561456.514614', "679") // 560777.514614
subtract("1000000000000000000000000000000", "1") // 999999999999999999999999999999


multiply("123", "456") // 56088
multiply(0.52, "67.89") // 35.3028
multiply(0.548568482, "0.5688974989") // 0.3120792373851696698
multiply("1000000000000000000000000000000", "1") // 1000000000000000000000000000000


highPrecisionDivision(10,2) // 5
highPrecisionDivision(0.456,0.00458) // 0.1249999988609375028980608135
highPrecisionDivision('0.456',0.08) // 0.1249999988609375028980608135
highPrecisionDivision(42424,424732545354332543543) // 0.0000000000000000998840339975

在这里插入图片描述
感谢你的阅读,如对你有帮助请收藏+关注!
只分享干货实战精品从不啰嗦!!!
如某处不对请留言评论,欢迎指正~
博主可收徒、常玩QQ飞车,可一起来玩玩鸭~

相关推荐

  1. 精度乘除

    2024-07-11 07:40:05       34 阅读
  2. 第一章 基础算法(二)(精度乘除

    2024-07-11 07:40:05       53 阅读
  3. php乘除函数

    2024-07-11 07:40:05       60 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 07:40:05       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 07:40:05       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 07:40:05       57 阅读
  4. Python语言-面向对象

    2024-07-11 07:40:05       68 阅读

热门阅读

  1. 在Linux上查找文件的2个好用的命令

    2024-07-11 07:40:05       24 阅读
  2. anaconda创建虚拟环境,指定路径

    2024-07-11 07:40:05       23 阅读
  3. npm、cnpm、pnpm、yarn的区别

    2024-07-11 07:40:05       22 阅读
  4. 使用标识符快捷登录远程SSH服务器

    2024-07-11 07:40:05       23 阅读
  5. ArcGIS Pro SDK (八)地理数据库 5 编辑

    2024-07-11 07:40:05       22 阅读
  6. 自动驾驶论文总结

    2024-07-11 07:40:05       27 阅读