大数相加
js 里面的 Number 用64位浮点数表示,数值范围为 -2^53 ------ 2^53 (包含边界)。如果数值相加后的结果超过这个范围,则会导致精度丢失。
大数相加原理是利用数组可以自动扩容来保存计算结果,并用字符串的形式输入与输出。
function add (str1, str2) { str1=str1.split(""); str2=str2.split(""); let result="";//结果 let flag=0; while(str1.length||str2.length||flag){
//~~把字符串转换为数字,用~~而不用parseInt,是因为~~可以将undefined转换为0,当a或b数组超限,不用再判断undefined
//注意这里的+=,每次都加了loc本身,loc为true,相当于加1,loc为false,相当于加0
flag+=~~str1.pop()+~~str2.pop(); result=flag%10+result; flag=flag>9; } return result.replace(/^0+/, ''); };
其实万变不离其宗,就是咱们小学学过的加减法,满10进1,接下来就1行1行分析下吧。
第一行和第二行,就是转为数组,为的就是利用数组的方法pop()一个个对应相加。
第二行,定义一个字符串,为的就是转换为字符串相加。
第三行,就是满10进1,还是不满10进0
第四行,就是判断两个数组相加完没有,注意这里的flag,是为了防止最后一次相加为10,需要进1的情况。
第五行,这里用到了按位取反运算符(~),这里用到这个为了解决~~undefined==0,因为[].pop()==undefined,而这里falg就是解决满10进1还是满10进0;
第六行,这个,举个例子,5+7=13;13%10=1....3;而这里就是先把3加上
第七行,这个是利用了隐形转为,falg转为1或者0,为了表示进1或进0。
add("1213123323213125","32131231231232132136")//32132444354555345261 //第一轮 //flag=flag(0)+5+6 //result=11%10(1)+"" result="1" //flag=11>9 flag=1 这里就是进满10进1 //第二轮 //flag=1+3+2 //result=6%10(6)+"1" result="61" //flag=6>9 flag=0 //不满10进0 //.......
2. 大数相乘
function multiplyBigNum(num1, num2) { //判断输入是不是数字 if (isNaN(num1) || isNaN(num2)) return ""; let len1 = num1.length, len2 = num2.length; let pos = []; //j放外面,先固定被乘数的一位,分别去乘乘数的每一位,更符合竖式演算法 for (let j = len2 - 1; j >= 0; j--) { for (let i = len1 - 1; i >= 0; i--) { //两个个位数相乘,最多产生两位数,index1代表十位,index2代表个位 let index1 = i + j, index2 = i + j + 1; //两个个位数乘积加上当前位置个位已累积的数字,会产生进位,比如08 + 7 = 15,产生了进位1 let mul = num1[i] * num2[j] + (pos[index2] || 0); //mul包含新计算的十位,加上原有的十位就是最新的十位 pos[index1] = Math.floor(mul / 10) + (pos[index1] || 0); //mul的个位就是最新的个位 pos[index2] = mul % 10; } } //去掉前置0 let result = pos.join("").replace(/^0+/, ""); return result || '0'; }
浙公网安备 33010602011771号