Comments (13)
不一致是因为有bug,有一定概率会遇到, 我改了一个 split 的版本
const add2 = (x, y) => {
x = '' + x;
y = '' + y;
if (/\D/.test((x + y))) {
return NaN;
}
let output = '';
let carry = '';
let zero = '0000000000000000000000';
const split = (str) => (zero + str).split(/(?=\d{14}$)/);
const remove_left_zero = (str) => ('' + str).replace(/^0+/, '');
while (x.length > 0 || y.length > 0 || carry.length > 0) {
let tx = split(x);
let ty = split(y);
let ta = split(parseInt(tx[1] || 0, 10) + parseInt(ty[1] || 0, 10) + parseInt(carry || 0, 10));
output = ta[1] + output;
carry = ta[0];
x = remove_left_zero(tx[0]);
y = remove_left_zero(ty[0]);
carry = remove_left_zero(carry);
}
return remove_left_zero(output);
}
from exercise2.
虽然
The JavaScript number format allows you to exactly represent all integers between
−9007199254740992 and 9007199254740992
我改成-15试了下,结果和-14是不一样的
let times = 100;
let numbers1 = '';
let numbers2 = '';
while(--times) {
numbers1 += Math.random();numbers2 += Math.random();
}
numbers1 = numbers1.replace(/\D/g, '');numbers2 = numbers2.replace(/\D/g, '');
const add1 = (x, y) => {
let rs = [];
while (x.length > 0 || y.length > 0) {
rs.push(parseInt(x.substr(-14) || 0, 10) + parseInt(y.substr(-14) || 0, 10));
x = x.substr(0, x.length - 14);
y = y.substr(0, y.length - 14);
}
var u = 0, o = '';
while (rs.length) {
let v = (rs.shift() + u).toString();
o = v.substr(-14) + o;
u = parseInt(v.substr(0, v.length - 14) || 0, 10);
}
return o;
}
const add2 = (x, y) => {
let rs = [];
while (x.length > 0 || y.length > 0) {
rs.push(parseInt(x.substr(-15) || 0, 10) + parseInt(y.substr(-15) || 0, 10));
x = x.substr(0, x.length - 15);
y = y.substr(0, y.length - 15);
}
var u = 0, o = '';
while (rs.length) {
let v = (rs.shift() + u).toString();
o = v.substr(-15) + o;
u = parseInt(v.substr(0, v.length - 15) || 0, 10);
}
return o;
}
console.log(add1(numbers1,numbers2));
console.log(add2(numbers1,numbers2));
from exercise2.
var safeLength = 15; // 14 ?
const add1 = (x, y) => {
var sum = ''; // 相加结果
var flag = 0; // 进位
while (x.length > 0 || y.length > 0) {
// 计算最后面safeLength个数字的相加值
var tailX = x.substr(-safeLength) || '0';
var tailY = y.substr(-safeLength) || '0';
var tailSum = (parseInt(tailX) + parseInt(tailY) + flag).toString();
// 前头补齐0(刚好切害到0开头的情况)
var orginLength = Math.max(tailX.length, tailY.length);
if (tailSum.length < orginLength) {
tailSum = '0'.repeat(orginLength - tailSum.length) + tailSum;
}
// 重新计算进位
flag = parseInt(tailSum.substr(0, tailSum.length - safeLength) || 0);
// 除进位之外,添加到结果前面
sum = tailSum.substr(-safeLength) + sum;
// 去掉已计算的最后面safeLength个数字
x = x.substr(0, x.length - safeLength);
y = y.substr(0, y.length - safeLength);
}
// 最后的进位
sum = flag ? flag + sum : sum;
return sum;
}
function add2(a, b) {
var aList = a.split('').reverse();
var bList = b.split('').reverse();
var max = Math.max(aList.length, bList.length);
var cList = [];
var flag = 0;
for (var i = 0; i < max; i++) {
var temp = (+aList[i] || 0) + (+bList[i] || 0) + flag;
flag = 0;
if (temp > 9) {
temp -= 10;
flag = 1;
}
cList.push(temp);
}
if (flag > 0) {
cList.push(flag);
}
return cList.reverse().join('');
}
(function test() {
let times = 100;
let numbers = '';
while(--times) {
numbers += Math.random();
}
numbers = numbers.replace(/\D/g, '');
let counts = 1e5;
while(--counts) {
let x = numbers.substring(Math.random() * 10 >> 0, Math.random() * 30 >> 0);
let y = numbers.substring(Math.random() * 30 >> 0, Math.random() * 80 >> 0);
//x = '1736';
//y = '611111750505538122824820966007687248173708494041043351';
var sum1 = add1(x, y);
var sum2 = add2(x, y);
if (sum1 != sum2) {
console.log('x:' + x);
console.log('y:' + y);
console.log('sum1', sum1);
console.log('sum2', sum2);
}
}
})()
from exercise2.
说明一下,one by one
这个 case 实在是太慢了,我把 counts 改成了 1e3,结果...
留一个问题:为什么 add 1 的 substr 是 -14
from exercise2.
再提一点,add1 可以用一个 while 搞定
from exercise2.
叼叼叼,膜拜大佬
from exercise2.
话说有同学回答一下-14的问题,和写一个单个while就搞定的算法吗?
from exercise2.
感觉应该改成-15会比较合适,js最大不会丢失进度的+运算,测试了一下是15位,见下图:
from exercise2.
刚才自己跑了一遍代码,才发现自己在群里说的是错的(捂脸,下次不敢没跑代码就乱说了)
我现在理解这个-14就是一次分组,改变一位一位相加,那么为了不丢失精度,肯定越大越好了
我这边试过了两个15位的也是不会丢失精度
额,赞上面的同学,把例子写出来了!向你学习!
from exercise2.
数字类型通过8字节的 double 浮点型表示,在JS中,使用 Number.MAX_SAFE_INTEGER 可以获得JS最大安全可进行算数运算的最大值范围 => 9007199254740991 十六位整型,因为使用的是浮点数运算会丢失精度,所以大于这个值运算都不对。 由于在第-14位上面有进位的问题,所以按13位进行切分计算,用-15会丢位的。
from exercise2.
const add1 = (x, y) => {
let rs = [];
let res = ''
while (x.length > 0 || y.length > 0) {
var a = parseInt(x.substr(-14) || 0, 10)
var b = parseInt(y.substr(-14) || 0, 10)
x = x.substr(0, x.length - 14);
y = y.substr(0, y.length - 14);
res = (a + b) + res
}
return res
}
from exercise2.
666666~
我这个菜鸟基础还是太薄弱啦,要努力努力啦~
from exercise2.
重来没有考虑过这种运算边界值的问题,还有很多要学啊~膜拜上面的各位大佬!
from exercise2.
Related Issues (4)
- 大数相加网上找的一个很简洁的案例,个人觉得写得很好 HOT 4
- 大数相加参考资料 HOT 1
- 大数相加问题以及jsPerf性能测试报告 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from exercise2.