JavaScript超大整數加法

來源:互聯網
上載者:User

JavaScript超大整數加法
什麼是「超大整數」?JavaScript 採用 IEEE754標準 中的浮點數演算法來表示數字 Number。 我也沒花時間去詳細瞭解 IEEE754標準 ,但對於處理超大整數,瞭解下面的幾個知識點就足夠了。 首先,JavaScript 實際上可以表示的最大數是: 1.7976931348623157e+308 Number.MAX_VALUE;    // 1.7976931348623157e+308雖然這個數可以正確表示出來,但會存在「精度丟失」的問題。 那什麼是「精度丟失」? 我們看看下面的例子: num1 = 10000000000000000000000000 + 11111111111111111111111111;    // 2.111111111111111e+25num2 = 21111111111111111111111000;    // 2.111111111111111e+25num1 === num2;    // true按照常規的數學預算, num1 的計算結果是 21111111111111111111111111,而 num2 的值是 21111111111111111111111000,兩者是不可能相等。但實際上 JavaScript 可以精確表示到個位的最大整數是:9007199254740992 Math.pow(2, 53);    // 9007199254740992Math.pow(2, 53) === Math.pow(2, 53) + 1;    // true9007199254740992 === 9007199254740992 + 1;    // true關於 JavaScript Number 的一些上下極限,更詳細的資料可以看:   正因為 JavaScript 的 Number 類型存在這些限制,當我們需要處理兩個「超大整數」的相加時,直接套用加法運算子會存在以下問題: 當結果大於 Math.pow(2, 53)  時,會出現精度丟失,導致最終結果存在偏差當結果大於 Number.MAX_VALUE,直接返回 Infinity  為瞭解決這些問題,才產生了「超大整數」加法的需求,實現代碼如下: 複製代碼var largeIntegerAddition = function () {    function isNumberString() {        var result = true;        for (var i = arguments.length; i--;) {            if (typeof arguments[i] !== 'string' || !/^\d+$/.test(arguments[i])) {                console.error('arguments format is incorrect!');                result = false;                break;            }        }        return result;    }     function trimHeadZero(numberStr) {        return numberStr.replace(/^0*/, '');    }     return function () {        var bigNum1 = arguments[0],            bigNum2 = arguments[1];         if (!bigNum2) {            return isNumberString(bigNum1) ? trimHeadZero(bigNum1) : '0';        } else {            if (!isNumberString(bigNum1, bigNum2)) {                return '0';            }             bigNum1 = trimHeadZero(bigNum1);            bigNum2 = trimHeadZero(bigNum2);             var carry = 0,  // 進位                bigNum1Split = bigNum1.split('').reverse(),                bigNum2Split = bigNum2.split('').reverse(),                result = '',                maxNumSize = bigNum1Split.length > bigNum2Split.length ? bigNum1Split.length : bigNum2Split.length;             for (var i = 0; i < maxNumSize; i++) {                var n1 = bigNum1Split[i] ? +bigNum1Split[i] : 0,                    n2 = bigNum2Split[i] ? +bigNum2Split[i] : 0,                    sum = (n1 + n2 + carry).toString();                if (sum.length > 1) {                    carry = +sum.slice(0, 1);                    result = sum.slice(1, 2) + result;                } else {                    carry = 0;                    result = sum + result;                }            }             if (carry !== 0) {                result = carry + result;            }             if (arguments[2]) {                var argumentArr = Array.prototype.slice.call(arguments, 0).slice(2);                argumentArr.unshift(result);                return largeIntegerAddition.apply(this, argumentArr);            } else {                return result;            }        }    }}();複製代碼  測試案例: 複製代碼// 測試案例function unitTest(arg, result) {    var res = largeIntegerAddition.apply(this, arg);    console.log(res, res === result);}unitTest([], '');unitTest(['012', 3], '15');unitTest(['012', '0013', '214', 100002], '100241');unitTest(['1.1111111111111111e+227', '1'], '1.1111111111111111e+227');unitTest(['123'], '123');unitTest(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], '45');unitTest(['0', '2', '3', '4', '123'], '132');unitTest(['012', '3'], '15');unitTest(['012', '0013', '214', '100002'], '100241');unitTest(['99999999999999999999', '1'], '100000000000000000000');unitTest(['99999999999999999999', '11111111111111111111'], '111111111111111111110');unitTest(['99999999999999999999', '11111111111111111111', '11111111'], '111111111111122222221');unitTest(['4810284728175829182', '92817475910285750182'], '97627760638461579364');unitTest(['4810284728175829182', '92817475910285750182', '9728172845'], '97627760648189752209');unitTest(['4810284728175829182', '92817475910285750182', '9728172845' , '92875018002020102'], '97720635666191772311');unitTest([    (function () {        var str = '';        for (var i = 500; i--;) {            str += '9';        }        return str;    })(),    (function () {        var str = '';        for (var i = 500; i--;) {            str += '1';        }        return str;    })()], (function () {    var str = '';    for (var i = 500; i--;) {        str += '1';    }    return str + '0';})());

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.