blog icon indicating copy to clipboard operation
blog copied to clipboard

大数相加

Open diamont1001 opened this issue 5 years ago • 0 comments

JS 和任何一门语言一样,对其数值的范围有限制。

Number.MAX_VALUE // 1.7976931348623157e+308
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MIN_VALUE // 5e-324
Number.MIN_SAFE_INTEGER // -9007199254740991

如果我们想要对一个超大的整数(> Number.MAX_SAFE_INTEGER)进行加法运算,但是又想输出一般形式,那么使用 + 是无法达到的,一旦数字超过 Number.MAX_SAFE_INTEGER 数字会被立即转换为科学计数法,并且数字精度相比以前将会有误差。在此时就需要自己实现一套加法算法。

function sum(a, b) {
    var res = '', temp = 0, aSymbol = '', bSymbol = '', num1, num2, lastSymbol = '';
    if (a < 0) {
        aSymbol = '-';
        a = a.substring(1);
    }

    if (b < 0) {
        bSymbol = '-';
        b = b.substring(1);
    }
    aArr = a.split('');
    bArr = b.split('');

    while (aArr.length || bArr.length || temp) {
        if (aSymbol === bSymbol) { // 加法
            temp += ~~aArr.pop() + ~~bArr.pop();
            res = temp % 10 + res;
            temp = temp > 9 ? 1 : 0;
            lastSymbol = aSymbol;
        } else { // 减法(大减小)
            num1 = ~~aArr.pop();
            num2 = ~~bArr.pop();
            if (parseInt(a, 10) < parseInt(b, 10)) {
                temp += num2 - num1;
                if (temp < 0) {
                    temp += 10;
                    res = temp % 10 + res;
                    temp = -1;
                } else {
                    res = temp % 10 + res;
                    temp = 0;
                }
                lastSymbol = bSymbol;
           } else {
                temp += num1 - num2;
                if (temp < 0) {
                    temp += 10;
                    res = temp % 10 + res;
                    temp = -1;
                } else {
                    res = temp % 10 + res;
                    temp = 0;
                }
                if (parseInt(a, 10) > parseInt(b, 10)) {
                    lastSymbol = aSymbol;
                }
            }
        }
    }
    res = res.replace(/^0+/, '');
    if (!res) {
        res = '0';
    } else {
        res = lastSymbol + res;
    }
    return res
}

diamont1001 avatar Oct 18 '18 10:10 diamont1001