Summary of JavaScript floating-point number and operation precision Adjustment
JavaScript has only one numeric type number, and all the numbers in JavaScript are represented in the IEEE-754 standard format. The accuracy of floating-point numbers is not specific to JavaScript, because some decimals are in binary notation and the number of bits is infinite.
-
Source: thewalker|2015-12-02 10:21
-
Mobile collection Sharing
"Technology salon" AI developer Combat Camp-7 minutes to build 1 custom skills. July 22, we wait for you together!
JavaScript has only one numeric type number, and all the numbers in JavaScript are represented in the IEEE-754 standard format. the accuracy of floating-point numbers is not specific to JavaScript, because some decimals are in binary notation and the number of bits is infinite .
- Decimal binary binary
- 0.1 0.0001 1001 1001 1001 ...
- 0.2 0.0011 0011 0011 0011 ...
- 0.3 0.0100 1100 1100 1100 ...
- 0.4 0.0110 0110 0110 0110 ...
- 0.5 0.1
- 0.6 0.1001 1001 1001 1001 ...
So for example, 1.1, its program actually can not really represent ' 1.1′, but only to a certain degree of accuracy, which is unavoidable loss of precision: 1.09999999999999999
The problem in JavaScript is even more complicated, and here are just a few things to test in chrome:
- Console.log (1.0-0.9 = = 0.1) //false
- Console.log (1.0-0.8 = = 0.2) //false
- Console.log (1.0-0.7 = = 0.3) //false
- Console.log (1.0-0.6 = = 0.4) //true
- Console.log (1.0-0.5 = = 0.5) //true
- Console.log (1.0-0.4 = = 0.6) //true
- Console.log (1.0-0.3 = = 0.7) //true
- Console.log (1.0-0.2 = = 0.8) //true
- Console.log (1.0-0.1 = = 0.9) //true
So how to avoid this kind of 1.0-0.9! = 0.1 Non-bug problem occurs? Here is a more current solution, before judging the results of floating-point calculations to reduce the accuracy of the results, because in the process of precision reduction will always automatically rounded:
- (1.0-0.9). toFixed (digits) //toFixed () precision parameter digits must be between 0 and 20
- Console.log (parsefloat (1.0-0.9) toFixed ()= = = 0.1 ) //true
- Console.log (parsefloat (1.0-0.8) toFixed ()= = = 0.2 ) //true
- Console.log (parsefloat (1.0-0.7) toFixed ()= = = 0.3 ) //true
- Console.log (parsefloat (11.0-11.8) toFixed ()= = =-0.8) //true
Write a method:
- Determine if the values are equal by using the IsEqual tool method
- function IsEqual (number1, number2, digits) {
- digits = digits = = undefined? 10:digits; //default accuracy is ten
- return number1.tofixed (digits) = = = Number2.tofixed (digits);
- }
- Console.log (isequal (1.0-0.7, 0.3)); //true
- Prototype extension mode, prefer object-oriented style
- Number.prototype.isEqual = function (number, digits) {
- digits = digits = = undefined? 10:digits; //default accuracy is ten
- return this.tofixed (digits) = = = Number.tofixed (digits);
- }
- Console.log ((1.0-0.7). IsEqual (0.3)); //true
Next, try floating-point arithmetic,
- Console.log (1.79+0.12) //1.9100000000000001
- Console.log (2.01-0.12) //1.8899999999999997
- Console.log (1.01*1.3) //1.3130000000000002
- Console.log (0.69/) //0.06899999999999999
Solution:
- An addition function that is used to obtain accurate addition results
- Note: the addition of JavaScript will have an error, and it will be more obvious when the two floating-point numbers are added. This function returns a more accurate addition result.
- Call: Accadd (ARG1,ARG2)
- return value: Arg1 plus arg2 's exact result
- function Accadd (ARG1,ARG2) {
- var r1,r2,m;
- try{r1=arg1.tostring (). Split (".") [1].length} catch (E) {r1=0}
- try{r2=arg2.tostring (). Split (".") [1].length} catch (E) {r2=0}
- M=math.pow (10,math.max (R1,R2))
- return (arg1*m+arg2*m)/M
- }
- Adding an Add method to the number type makes it more convenient to call.
- Number.prototype.add = function (ARG) {
- return Accadd (ARG, this);
- }
- Subtraction function, which is used to get the exact subtraction result
- Note: the addition of JavaScript will have an error, and it will be more obvious when the two floating-point numbers are added. This function returns a more accurate subtraction result.
- Call: Accsub (ARG1,ARG2)
- return value: Arg1 minus arg2 's exact result
- function Accsub (ARG1,ARG2) {
- var r1,r2,m,n;
- try{r1=arg1.tostring (). Split (".") [1].length} catch (E) {r1=0}
- try{r2=arg2.tostring (). Split (".") [1].length} catch (E) {r2=0}
- M=math.pow (10,math.max (R1,R2));
- //last Modify by Deeka
- //Dynamic control accuracy length
- N= (R1>=R2) r1:r2;
- return ((arg1*m-arg2*m)/m). ToFixed (n);
- }
- The Division function, which is used to get accurate division results.
- Description: The result of the division of JavaScript will be error, which will be obvious when dividing two floating-point numbers. This function returns a more accurate division result.
- Call: Accdiv (ARG1,ARG2)
- Return value: Arg1 divided by the exact result of arg2
- function Accdiv (ARG1,ARG2) {
- var t1=0,t2=0,r1,r2;
- try{t1=arg1.tostring (). Split (".") [1].length} catch (e) {}
- try{t2=arg2.tostring (). Split (".") [1].length} catch (e) {}
- With (Math) {
- R1=number (Arg1.tostring (). Replace (".",""))
- R2=number (Arg2.tostring (). Replace (".",""))
- return (R1/R2) *pow (10,t2-t1);
- }
- }
- Adding a Div method to the number type makes it easier to call.
- Number.prototype.div = function (ARG) {
- return Accdiv (this, arg);
- }
- multiplication function to get the exact multiplication result
- Description: JavaScript multiplication results are error-evident when multiplying two floating-point numbers. This function returns a more accurate multiplication result.
- Call: Accmul (ARG1,ARG2)
- return value: Arg1 times the exact result of arg2
- function Accmul (ARG1,ARG2) {
- var m=0,s1=arg1.tostring (), s2=arg2.tostring ();
- try{m+=s1.split (".") [1].length} catch (e) {}
- try{m+=s2.split (".") [1].length} catch (e) {}
- return Number (S1.replace (".", "")) *number (s2.replace (".", ""))/math.pow (10,m)
- }
- Adding a Mul method to the number type makes it more convenient to call.
- Number.prototype.mul = function (ARG) {
- return Accmul (ARG, this );
- }
- <br>//verify:
- Console.log (Accadd (1.79, 0.12)); //1.91
- Console.log (Accsub (2.01, 0.12)); //1.89
- Console.log (Accdiv (0.69, 10)); //0.069<br>console.log (Accmul (1.01, 1.3)); 1.313
After the transformation, you can happily carry out the floating point subtraction operation ~
"Editor's recommendation"
- 25 free resources that are useful to JavaScript novice programmers
- JavaScript modularization and Seajs source analysis
- JavaScript design pattern Theory and actual combat: Observer pattern
- The problem of JavaScript prototype chain and scope during interview
- WordPress.com Open source, discard PHP instead of JavaScript
Summary of JavaScript floating-point number and operation precision Adjustment