The last blog in-depth analysis of 0.1+0.2 === 0.30000000000000004 reasons.

This blog post will focus on code examples of several Javascript libraries that address fractional precision loss issues, as well as simple native EcmaScript methods.

Class library part

math.js

Math.js is an extensive math library for JavaScript and Node.js. Support number, large number, complex number, fraction, unit and matrix data type operations.

Mathjs.org/ GitHub: github.com/josdejong/m…

0.1+0.2 ===0.3

Var math = require('mathjs') console.log(math.add(0.1,0.2))//0.30000000000000004 The console. The log (math. The format ((math. The add (math.h bignumber (0.1), math. Bignumber (0.2))))) / / '0.3'Copy the code

decimal.js

Provides JavaScript with arbitrary precision values of decimal type.

Liverpoolfc.tv: mikemcl. Making. IO/decimal. Js /

GitHub:github.com/MikeMcl/dec…

Var Decimal = require('decimal.js') x = new Decimal(0.1) y = 0.2 console.log(x.plus(y).tostring ()))//'0.3'Copy the code

bignumber.js

JavaScript library for arbitrary precision arithmetic.

Liverpoolfc.tv: mikemcl. Making. IO/bignumber. J…

Github:github.com/MikeMcl/big…

Var BigNumber = require("bignumber.js") x = new BigNumber(0.1) y = 0.2 console.log(x.plus(y).tostring ()))//'0.3'Copy the code

big.js

A small fast JavaScript library for arbitrary precision decimal arithmetic. Liverpoolfc.tv: mikemcl. Making. IO/big. Js/Github:github.com/MikeMcl/big…

Var Big = require("big.js") x = new Big(0.1) y = 0.2 console.log(x.plus(y).tostring ()))//'0.3'Copy the code

One important thing to note is that using the library, the output 0.3 is a String, so if you want to keep it Number, you can use the parseFloat() method.

NPM I mathjs-g, require(‘mathjs’), not math.js, because josdejong named it mathjs when he created the project. MikeMcl, which has decimal. Js, bignumber.js and big.js above, has a project name with dot, and is therefore installed and imported as xxx.js.

How to make a choice between these three class libraries, we need to make a specific analysis according to the specific situation, I will not repeat here.

Npm.runkit.com. Enter the name of the Node.js package you want to test to implement the API in the online test package. For example, math.js: npm.runkit.com/mathjs big.js: npm.runkit.com/big.js

2. Native methods

The class library is quite powerful and our calculations of 0.1+0.2 are just scratching the surface, so how do we apply native EcmaScript code to simple problem scenarios?

To do this, use the number.prototype.tofixed () method.

Floating point operation

ToFixed () method

There are many solutions to floating-point arithmetic, but one commonly used solution is to reduce the accuracy of a floating-point arithmetic before judging it, because the accuracy of a floating-point arithmetic is always automatically rounded.

The toFixed() method uses fixed-point notation to format a number, rounding the result. Grammar:

ToFixed (digits) The digits parameter indicates the number of digits after the decimal point; Between 0 and 20 inclusive, the implementation environment may support a larger range. If this parameter is ignored, it defaults to 0.

Returns the string representation of a numeric value, not using exponential notation, but the digits digit after the decimal point. The value is rounded if necessary, and the decimal part is padded with zeros if necessary so that the decimal part has the specified number of digits. If the value is greater than 1 e + 21, this method can simply call the Number. The prototype. The toString () and returns a index notation format string.

Note in particular: toFixed() returns a string representation of a number.

For details, please refer to the instructions in MDN. Then we can solve the accuracy problem as follows:

JavaScript code:

ParseFloat ((math expression).tofixed (digits)); // toFixed() must be between 0 and 20, 2 is recommended. 2 is to deal with 5/9 infinite repeating decimals. // Run parseFloat((0.1 + 0.2).tofixed (10))// Result 0.3 parseFloat((0.3/0.1).tofixed (10))// Result 3 parseFloat((0.7 * ToFixed (10))// Result is 126 parseFloat((1.0-0.9).tofixed (10))// Result is 0.1 parseFloat((9.7 * 100).tofixed (10))// Result is 970 ParseFloat ((2.22 + 0.1).tofixed (10)) // Result is 2.32Copy the code

Accuracy parameters in Browser environment are allowed between 0 and 100 bits (including 100), with test versions Chrome62(64-bit) and Firefox56 (32-bit). In the Nodejs environment, it can only be between 0 and 20, and the test version is V6.9.5.

The second is toFixed() browser compatibility discussion, MDN gave all the results are YES, no matter desktop or mobile, that is to say, do not worry about toFixed() compatibility issues (IE8 – we will not discuss).

The desktop client:

Mobile client:

Thanks: www.css88.com/archives/73… Developer.mozilla.org/zh-CN/docs/…


2019.7.28 update:

ParseFloat ((5/9).tofixed (10)) returns 0.5555555556. So it is more recommended to parseFloat((5/9).tofixed (2)) and keep the decimal number to two digits.

The calculation of money is the most complicated, such as the calculation of RMB, in fact, the final accuracy to the minute is very ok, yuan jiao. The unit is so small that it is rare in our daily life.

I am looking forward to communicating with you and making progress together. Welcome to join the technical discussion group I created which is closely related to front-end development:

  • SegmentFault column: Be a good front-end engineer while you’re still young
  • Zhihu column: Be an excellent front-end engineer while you are still young
  • Github blog: Personal blog 233 while You’re Still Young
  • excellent_developers

Strive to be an excellent front-end engineer!