Coder Social home page Coder Social logo

Comments (11)

MikeMcl avatar MikeMcl commented on August 20, 2024

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.

igorlino avatar igorlino commented on August 20, 2024

@MikeMcl

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.

MikeMcl avatar MikeMcl commented on August 20, 2024

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.

Slowlearneruk avatar Slowlearneruk commented on August 20, 2024

Shouldn't the cap be Number.MAX_SAFE_INTEGER rather than 15 digits?

from bignumber.js.

MikeMcl avatar MikeMcl commented on August 20, 2024

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.

Slowlearneruk avatar Slowlearneruk commented on August 20, 2024

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.

MikeMcl avatar MikeMcl commented on August 20, 2024

Thanks for the feedback.

See #91

From v2.2.0, all integers up to Number.MAX_SAFE_INTEGER are now accepted.

from bignumber.js.

mqklin avatar mqklin commented on August 20, 2024

@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.

MikeMcl avatar MikeMcl commented on August 20, 2024

@mqklin

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.

mqklin avatar mqklin commented on August 20, 2024

@MikeMcl We use v7.2.1
That's strange, because we didn't set DEBUG = true

from bignumber.js.

mqklin avatar mqklin commented on August 20, 2024

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)

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.