Code Monkey home page Code Monkey logo

Comments (13)

loskael avatar loskael commented on July 19, 2024 2

@moux1024

不一致是因为有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.

moux1024 avatar moux1024 commented on July 19, 2024 1

虽然

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.

chencye avatar chencye commented on July 19, 2024 1
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.

loskael avatar loskael commented on July 19, 2024

说明一下,one by one 这个 case 实在是太慢了,我把 counts 改成了 1e3,结果...

留一个问题:为什么 add 1 的 substr 是 -14

from exercise2.

loskael avatar loskael commented on July 19, 2024

再提一点,add1 可以用一个 while 搞定

from exercise2.

miniflycn avatar miniflycn commented on July 19, 2024

叼叼叼,膜拜大佬

from exercise2.

miniflycn avatar miniflycn commented on July 19, 2024

话说有同学回答一下-14的问题,和写一个单个while就搞定的算法吗?

from exercise2.

kisscancer avatar kisscancer commented on July 19, 2024

感觉应该改成-15会比较合适,js最大不会丢失进度的+运算,测试了一下是15位,见下图:

image

from exercise2.

changyu496 avatar changyu496 commented on July 19, 2024

刚才自己跑了一遍代码,才发现自己在群里说的是错的(捂脸,下次不敢没跑代码就乱说了)
我现在理解这个-14就是一次分组,改变一位一位相加,那么为了不丢失精度,肯定越大越好了
我这边试过了两个15位的也是不会丢失精度
额,赞上面的同学,把例子写出来了!向你学习!

from exercise2.

kangschampagne avatar kangschampagne commented on July 19, 2024

数字类型通过8字节的 double 浮点型表示,在JS中,使用 Number.MAX_SAFE_INTEGER 可以获得JS最大安全可进行算数运算的最大值范围 => 9007199254740991 十六位整型,因为使用的是浮点数运算会丢失精度,所以大于这个值运算都不对。 由于在第-14位上面有进位的问题,所以按13位进行切分计算,用-15会丢位的。

from exercise2.

kangschampagne avatar kangschampagne commented on July 19, 2024

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.

kisscancer avatar kisscancer commented on July 19, 2024

666666~
我这个菜鸟基础还是太薄弱啦,要努力努力啦~

from exercise2.

juntingl avatar juntingl commented on July 19, 2024

重来没有考虑过这种运算边界值的问题,还有很多要学啊~膜拜上面的各位大佬!

from exercise2.

Related Issues (4)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.