背景
Js 和任何一門語言一樣竞膳,對其數(shù)值的范圍有限制。
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MIN_VALUE // 5e-324
Number.MIN_SAFE_INTEGER // -9007199254740991
如果我們想要對一個(gè)超大的整數(shù)(> Number.MAX_SAFE_INTEGER)進(jìn)行加法運(yùn)算汇跨,但是又想輸出一般形式呛占,那么使用 + 是無法達(dá)到的,一旦數(shù)字超過 Number.MAX_SAFE_INTEGER 數(shù)字會被立即轉(zhuǎn)換為科學(xué)計(jì)數(shù)法暴区,并且數(shù)字精度相比以前將會有誤差闯团。在此時(shí)就需要自己實(shí)現(xiàn)一套加法算法。
代碼實(shí)現(xiàn)
function sumBigNumber(a, b) {
var res = '',
temp = 0;
a = a.split('');
b = b.split('');
while (a.length || b.length || temp) {
temp += ~~a.pop() + ~~b.pop();
res = (temp % 10) + res;
temp = temp > 9;
}
return res.replace(/^0+/, '');
}
解釋
- 首先我們用字符串的形勢來保存大數(shù)仙粱,就保證了其在數(shù)學(xué)表示上不會發(fā)生變化
初始化res, temp變量來保存中間計(jì)算的結(jié)果房交,在將兩個(gè)字符串split為數(shù)組,以便我們進(jìn)行每一位的運(yùn)算 - 循環(huán)的第一次就是進(jìn)行 "個(gè)位" 的運(yùn)算伐割,將二者最末尾的兩個(gè)數(shù)相加候味,由于每一位數(shù)字是0 - 9,所以需要進(jìn)行進(jìn)位隔心,在進(jìn)過取余數(shù)操作后白群,將結(jié)果保留在個(gè)位。
- 判斷 temp 是否大于 10济炎,若是則將 temp 賦值為 true川抡,等等,為什么要賦值成布爾值,不要著急崖堤,魔法即將發(fā)生侍咱。
- 在兩個(gè)大數(shù)中的一個(gè)還有數(shù)字沒有參與運(yùn)算,或者前一次運(yùn)算發(fā)生進(jìn)位后密幔,進(jìn)行下一次循環(huán)楔脯。
- 接著除了對新的兩個(gè)數(shù)字相加還要加上 temp,若上次發(fā)生了進(jìn)位胯甩,則此時(shí) temp 為 true昧廷,Js因?yàn)榇嬖陔[式轉(zhuǎn)換,所以 true 轉(zhuǎn)換為 1偎箫,我們借用 Js 的類型轉(zhuǎn)換木柬,完成了邏輯上的逢10進(jìn)1操作。
接下來就是重復(fù)上述的操作淹办,直到計(jì)算結(jié)束眉枕。
例子:
sumBigNumber('100000000000002222', '111111'); // 100000000000113333
sumBigNumber('3782647863278468012934670', '23784678091370408971329048718239749083'); /