analyze
JavaScript has only one number type Number, and all numbers in Javascript are represented in the IEEE-754 standard format. The precision problem of floating-point numbers is not unique to JavaScript, because some decimals represent infinite digits in binary:
Decimal 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 cannot actually represent '1.1', but can only achieve a certain degree of accuracy. This is an inevitable loss of accuracy:
1.0999999999999999999
The problem in JavaScript is more complicated, here is only some test data in Chrome:
Input and output
1.0-0.9 == 0.1 False
1.0-0.8 == 0.2 False
1.0-0.7 == 0.3 False
1.0-0.6 == 0.4 True
1.0-0.5 == 0.5 True
1.0-0.4 == 0.6 True
1.0-0.3 == 0.7 True
1.0-0.2 == 0.8 True
1.0-0.1 == 0.9 True
solve
So how to avoid this type of non-bug problem with 1.0-0.9 != 0.1? Here is a solution that is currently used more frequently. The calculation results are reduced in accuracy before judging the floating-point calculation results, because the process of reducing the accuracy will always be automatically rounded:
The code copy is as follows:
(1.0-0.9).toFixed(digits) // toFixed() The accuracy parameters must be between 0 and 20
parseFloat((1.0-0.9).toFixed(10)) === 0.1 // The result is True
parseFloat((1.0-0.8).toFixed(10)) === 0.2 // The result is True
parseFloat((1.0-0.7).toFixed(10)) === 0.3 // The result is True
parseFloat((11.0-11.8).toFixed(10)) === -0.8 // The result is True
Method Refining
The code copy is as follows:
// Use the isEqual tool method to determine whether the values are equal or not
function isEqual(number1, number2, digits){
digits = digits == undefined? 10: digits; // The default accuracy is 10
return number1.toFixed(digits) === number2.toFixed(digits);
}
isEqual(1.0-0.7, 0.3); // return true
// Native extension method, prefer object-oriented style
Number.prototype.isEqual = function(number, digits){
digits = digits == undefined? 10: digits; // The default accuracy is 10
return this.toFixed(digits) === number.toFixed(digits);
}
(1.0-0.7).isEqual(0.3); // return true