Git Product home page Git Product logo

number-precision's Introduction

number-precision npm version Build Status codecov

Perform addition, subtraction, multiplication and division operations precisely using javascript

Why

0.1 + 0.2 = 0.30000000000000004
1.0 - 0.9 = 0.09999999999999998
0.105.toFixed(2) = 0.1 // not 0.11

Install

npm install number-precision --save

Methods

NP.strip(num)         // strip a number to nearest right number
NP.plus(num1, num2, num3, ...)   // addition, num + num2 + num3, two numbers is required at least.
NP.minus(num1, num2, num3, ...)  // subtraction, num1 - num2 - num3
NP.times(num1, num2, num3, ...)  // multiplication, num1 * num2 * num3
NP.divide(num1, num2, num3, ...) // division, num1 / num2 / num3
NP.round(num, ratio)  // round a number based on ratio

Usage

import NP from 'number-precision'
NP.strip(0.09999999999999998); // = 0.1
NP.plus(0.1, 0.2);             // = 0.3, not 0.30000000000000004
NP.plus(2.3, 2.4);             // = 4.7, not 4.699999999999999
NP.minus(1.0, 0.9);            // = 0.1, not 0.09999999999999998
NP.times(3, 0.3);              // = 0.9, not 0.8999999999999999
NP.times(0.362, 100);          // = 36.2, not 36.199999999999996
NP.divide(1.21, 1.1);          // = 1.1, not 1.0999999999999999
NP.round(0.105, 2);            // = 0.11, not 0.1

PS: If you want to get rid of XXX is beyond boundary when transfer to integer, the results may not be accurate, use this at the beginning of your app to turn off boundary checking.

NP.enableBoundaryChecking(false); // default param is true

License

MIT

number-precision's People

Contributors

camsong avatar cbbfcd avatar dependabot[bot] avatar jasonhzq avatar jiangtao avatar kmvan avatar luxp avatar lvqq avatar lxfriday avatar qmhc avatar xiaosu12138 avatar zhiyan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

number-precision's Issues

undefined/null校验

目前如果传入undefined/null数据,就会报错,是否可以校验传入数据的正确性

控制台warning

image
31941166666666700 is beyond boundary when transfer to integer, the results may not be accurate
控制台warning

Publish an ES 6 module

With more and more projects making steps towards http 2 and using modules right in the browser (no bundling/webpack involved), an ES6 importable version (which does not rely on webpack to transpile the import) would be desirable.

0.7-0.1 is not equal 0.6

0.7*100 is not 7,is 7.000000000000001

describe('NP.minus', () => {
function check(num1, num2, result) {
assert.strictEqual(NP.minus(num1, num2), result);
}

it('can do minus operation', () => {
check(0.07, 0.01, 0.06);
});
});

warning

-3000000000000000500 is beyond boundary when transfer to integer, the results may not be accurate

Multiplication issue

I'm trying to multiply 9.700000042 and 1000000000 using the times method.
It should show 9700000042 as the final result. But it's returning 9700000041.999998.
please help.

strip 不生效

const NP = require("number-precision");
console.log(0.151 - 0.145);// 0.006000000000000005
console.log(NP.strip(0.151-0.145)); //0.00600000000000001

divide(4750.49269435, 4)结果错误

/**
 * 精确乘法
 */
function times(num1, num2) {
    // var num1Changed = Number(num1.toString().replace('.', ''));
    // var num2Changed = Number(num2.toString().replace('.', ''));
    // var baseNum = digitLength(num1) + digitLength(num2);
    var dl1 = digitLength(num1);
    var dl2 = digitLength(num2);
    var num1Changed = num1 * Math.pow(10, dl1);
    var num2Changed = num2 * Math.pow(10, dl2);
    var baseNum = dl1 + dl2;
    return num1Changed * num2Changed / Math.pow(10, baseNum);
}

/**
 * 精确除法
 */
function divide(num1, num2) {
    // var num1Changed = Number(num1.toString().replace('.', ''));
    // var num2Changed = Number(num2.toString().replace('.', ''));
    var dl1 = digitLength(num1);
    var dl2 = digitLength(num2);
    var num1Changed = num1 * Math.pow(10, dl1);
    var num2Changed = num2 * Math.pow(10, dl2);
    return times((num1Changed / num2Changed), Math.pow(10, dl2 - dl1));
}

希望能在运算效率上再加强

我做了一下压力测试,感觉效率上有改进的余地:

describe('求余数运算', () => {

//Math.round 用时14ms
it('test Math', () => {
let total=0;
for (let i = 1; i <= 10000 * 10; i++) {
total += Math.round(i * 100) / 100;
}
console.log(total);
});

//Math.round 再加上求精度,转浮点数,用时 273ms
it('test Math2', () => {
let total=0;
for (let i = 1; i <= 10000 * 10; i++) {
total += Math.round(parseFloat((i * 100).toPrecision(14))) / 100;
}
console.log(total);
});

//NP.round 用时1sec963ms
it('test NP', () => {
let total=0;
for (let i = 1; i <= 10000 * 10; i++) {
total += NP.round(i ,2) ;
}
console.log(total);
});
})

除法超出最大整型值报错

版本:1.6.0

image

12833333333333334 大于 Number.MAX_SAFE_INTEGER,导致报错

原始调用如下:

NP.divide(231, 18)
// Chrome:231 / 18 = 12.833333333333334

我看有个 PR 处理过这个问题,看来没修复成功

参数为字符串且末尾包含空格导致计算错误

NP.times('0.1', 100); // 10
NP.times('0.1 ', 100); // 1

第一种情况是正常的计算,第二种情况计算结果异常,原因是 '0.1 ' 中末尾包含空格。

调试发现 NP 在计算参数小数位数之前没有将其先转换为数字再计算,因此空格也算在小数位数之中并且空格在进行运算的时候不会报错,因此导致 NP 静默错误。

NP 是否需要处理参数为字符串的情况?

Missing .d.ts file in packaged output, when using tsc in host program based ts 4.x may cause problem

打包产物中缺少 .d.ts 文件,在 ts 项目中直接引用的 src/index.ts 文件的类型定义,执行 tsc 会直接编译 node_module 中 number-precison 的 index.ts,可能会产生错误。

例如在使用 ts 4.x,且开启了 noUncheckedIndexedAccess 编译选项时会产生下面的报错:

node_modules/number-precision/src/index.ts:22:16 - error TS2532: Object is possibly 'undefined'.

22   const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
                  ~~~~~~~~~

node_modules/number-precision/src/index.ts:55:23 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

55   let res = operation(num1, num2);
                         ~~~~

node_modules/number-precision/src/index.ts:73:35 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

73   const num1Changed = float2Fixed(num1);
                                     ~~~~

node_modules/number-precision/src/index.ts:74:35 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

74   const num2Changed = float2Fixed(num2);
                                     ~~~~

node_modules/number-precision/src/index.ts:75:31 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

75   const baseNum = digitLength(num1) + digitLength(num2);
                                 ~~~~

node_modules/number-precision/src/index.ts:75:51 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

75   const baseNum = digitLength(num1) + digitLength(num2);
                                                     ~~~~

node_modules/number-precision/src/index.ts:93:53 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

93   const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
                                                       ~~~~

node_modules/number-precision/src/index.ts:93:72 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

93   const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
                                                                          ~~~~

node_modules/number-precision/src/index.ts:95:17 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

95   return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
                   ~~~~

node_modules/number-precision/src/index.ts:95:40 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

95   return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
                                          ~~~~

node_modules/number-precision/src/index.ts:107:53 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

107   const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
                                                        ~~~~

node_modules/number-precision/src/index.ts:107:72 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

107   const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
                                                                           ~~~~

node_modules/number-precision/src/index.ts:108:17 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

108   return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
                    ~~~~

node_modules/number-precision/src/index.ts:108:40 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

108   return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
                                           ~~~~

node_modules/number-precision/src/index.ts:120:35 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

120   const num1Changed = float2Fixed(num1);
                                      ~~~~

node_modules/number-precision/src/index.ts:121:35 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

121   const num2Changed = float2Fixed(num2);
                                      ~~~~

node_modules/number-precision/src/index.ts:125:74 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

125   return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
                                                                             ~~~~

node_modules/number-precision/src/index.ts:125:94 - error TS2345: Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

125   return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
                                                                                                 ~~~~


Found 18 errors.

因为 .ts 文件一旦被引用总会被 tsc 编译,无法被忽略,.d.ts 类型声明文件则可以被排除,因此希望可以加上类型声明文件的生成

参考:

NP.plus(2.018, 0.001)

NP.plus(2.018, 0.001)
2.0189999999999997

原因是 > 2.018 * 1000
2017.9999999999998

所以简单的乘以10的n次方不能覆盖所有情况..

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.