Comments (11)
Yes, the README doesn't mention, as the API document states, that "values of type number with more than 15 significant digits are considered invalid as calling toString
or valueOf
on such numbers may not result in the intended value".
There is a good reason for this limitation. Notice, for example, that precision is lost when the following 16 significant digit numbers are converted from decimal to binary floating point and back to decimal again
console.log( 88259496234518.57 ); // 88259496234518.56
console.log( -707422234799.9383 ); // -707422234799.9384
This does not happen with any numbers which have 15 s.d. or less.
Also, but less importantly, most number literals that have 'too many' significant digits to be accurately stored will be represented as numbers with 16 digits or more,
console.log( 12345678.123456789 ); // 12345678.12345679 16 s.d.
console.log( 99999999999999999999 ); // 100000000000000000000 21 s.d.
although not all, particularly those that result in exponential notation and that have numerous intervening zeros
console.log( 1.0000000000000001 ); // 1
console.log( 10000000000000001 ); // 1e+16
console.log( 0.10000000000000001 ); // 0.1
console.log( 0.000000000000010000000000000001 ); // 1e-14
The constructor accepts literal numbers as a convenience and the error message acts as a warning that a number may not be as intended. In production it is expected that the error messaging would be turned off and the constructor will then accept any numbers
BigNumber.config({ ERRORS: false });
new BigNumber( Math.PI ); // '3.141592653589793'
new BigNumber( Math.random() ); // '0.9544870883598676'
Alternatively, if a user doesn't want to turn off error messages, toString
can be called on the values
new BigNumber( Math.PI.toString() ); // '3.141592653589793'
new BigNumber( Math.random().toString() ); // '0.9544870883598676'
I am not sure what you are referring to when you state that the current design makes "the improper use [of literal numbers] easier". As shown above, their improper use would certainly be easier if the 15 s.d. limit was removed, as you seem to want.
I do not agree that: "If you're going to allow conversion of a base two floating point number into a base ten floating point number, you're almost surely introducing error anyway." There is no reason to assume a literal number passed to the constructor is in error, and a string argument could equally be formed from the result of inaccurate floating-point calculations. The 15 s.d. limit helps prevent such errors
console.log( 0.7 + 0.1 ); // 0.7999999999999999 16 s.d. so rejected
console.log( 0.2 + 0.1 ); // 0.30000000000000004 17 s.d. so rejected
As long as only numbers with 15 s.d. or less are involved, any errors introduced by the imprecision of floating-point arithmetic will result in a number with more than 15 s.d.
While you seem to consider the 15 s.d. limit a pointless cause of irritation, confusion and bugs, I think on balance it is better to have it then not. It is a reminder about the potential loss of precision in decimal-binary-decimal conversions and is easily turned off.
I agree that it would be better to keep the decimal point in the error messages so that the offending value can be identified more easily. I will update the constructor presently, and add a note about the 15 s.d. limit in the README.
Thanks for the feedback.
I would be interested to hear if anybody else would prefer the 15 s.d. limit to be removed.
from bignumber.js.
nice library!
I would be interested to hear if anybody else would prefer the 15 s.d. limit to be removed.
I think it would be practical if it could be configurable, since maybe I want to work with 20 digits, without having to disable the errors.
BigNumber.config({ ERRORS: false });
from bignumber.js.
Thanks.
Can't you just convert the numbers to strings?
n = 12345123451234512345;
x = new BigNumber(String(n));
And most 20 digit numbers can't be stored exactly as JavaScript numbers anyway
console.log(n); // 12345123451234513000
I have removed the 15 digit limit for numbers in decimal.js and I may do it here, but not at present.
from bignumber.js.
Shouldn't the cap be Number.MAX_SAFE_INTEGER rather than 15 digits?
from bignumber.js.
No, it is a matter of significant digits rather than whether a number is an integer or float.
Many values with sixteen significant digits or more cannot be stored precisely using JavaScript numbers (double-precision floating-point). For example,
console.log(9.543245345454127) // 9.543245345454126
from bignumber.js.
I wonder if it could be a little more selective - as was working with integers it was frustrating to have to drop from my ceiling from MAX_SAVE_INTEGER to 999999999999999. It is an excellent library BTW which this extremely minor criticism does nothing to change :)
from bignumber.js.
Thanks for the feedback.
See #91
From v2.2.0, all integers up to Number.MAX_SAFE_INTEGER are now accepted.
from bignumber.js.
@MikeMcl is it possible to automatically convert arguments to String
? Now we have to wrap every argument, very inconvenient: toBigNumber(String(10 ** -decimals)).mul(String(quantity)).mul(String(priceItem.value.usd)));
from bignumber.js.
There is no need to convert arguments to string. You are commenting on a very old issue here which probably contains discussion that is irrelevant to later versions of this library.
Since v7.0.0 there is no error thrown on numbers with more than 15 significant digits unless a DEBUG property is added to BigNumber and set to true.
BigNumber.DEBUG = true;
from bignumber.js.
@MikeMcl We use v7.2.1
That's strange, because we didn't set DEBUG = true
from bignumber.js.
Oh, we use bignumber.js
inside web3
lib, which uses old version: https://github.com/frozeman/bignumber.js-nolookahead - we should use the new one.
Thank you!
from bignumber.js.
Related Issues (20)
- Using version 9.1.1, run new BigNumber(0).exponentiatedBy('-12345678901234567890123456789012345678901234567890').valueOf() Is return to infinity normal? HOT 1
- Issue toNumber() function round up when number is too big (v9.1.1) HOT 2
- Division on exponential values leads to infinite loop HOT 3
- 负数加减乘除不好用 HOT 1
- [Feature Request]: Can we support `toBigInt`?
- Type error HOT 2
- Big Number (toFixed,dp,decimalPlaces,toFormat) - Chrome Update Issue 115.0.5790.102 HOT 24
- Minus sign in formatted strings HOT 2
- wrong calculation result on multipliedBy/times methods HOT 1
- toNumber does not respect ROUNDING_MODE HOT 11
- Calculation error HOT 1
- Is there any other way to handle new BigNumber(999999999999999999999) without using strings? HOT 2
- Difference between multipliedBy and dividedBy behaviors HOT 2
- Different result between toFixed and toNumber HOT 1
- Can't convert to Base64 HOT 1
- Tree shake commonjs version from mjs version HOT 1
- toFixed error
- [Bug] Return Type of Methods HOT 2
- Logarithms (I know there is another issue about this)
- toString() default base is not 10? HOT 2
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 bignumber.js.