Summary of JavaScript floating point number and operation Precision Adjustment
JavaScript has only one numeric type Number, and all numbers in Javascript are represented in IEEE-754 standard format. The precision of floating point numbers is not unique to JavaScript, because some decimals useBinary indicates that the number of digits is infinite..
- 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...
Therefore, for example, 1.1, the program can not really represent '1. 1', but can only be accurate to a certain extent, which is an unavoidable loss of precision: 1.09999999999999999
The problem in JavaScript is more complicated. Here we only give some test data 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
How can we avoid this type of 1.0-0.9! = What happens to 0.1 of non-bug issues? The following provides a more widely used solution. The accuracy of the computing result is reduced before the floating point calculation result is judged, because the accuracy is automatically rounded down:
- (1.0-0.9). toFixed (digits) // toFixed () The accuracy parameter digits must be between 0 and 20
- Console. log (parseFloat (1.0-0.9). toFixed (10) === 0.1) // true
- Console. log (parseFloat (1.0-0.8). toFixed (10) === 0.2) // true
- Console. log (parseFloat (1.0-0.7). toFixed (10) === 0.3) // true
- Console. log (parseFloat (11.0-11.8). toFixed (10) ===- 0.8) // true
Write a method:
- // Use the isEqual tool to determine whether the values are equal
- Function isEqual (number1, number2, digits ){
- Digits = undefined? 10: digits; // The default precision is 10.
- Return number1.toFixed (digits) === number2.toFixed (digits );
- }
- Console. log (isEqual (1.0-0.7, 0.3); // true
- // Prototype extension method, prefer the object-oriented Style
- Number. prototype. isEqual = function (number, digits ){
- Digits = undefined? 10: digits; // The default precision is 10.
- Return this. toFixed (digits) === number. toFixed (digits );
- }
- Console. log (1.0-0.7). isEqual (0.3); // true
Next, let's try the floating point operation,
- 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/10) //0.06899999999999999
Solution:
- // Addition function, used to obtain accurate addition results
- // Note: The addition result of javascript has an error, which is obvious when two floating point numbers are added. This function returns a more accurate addition result.
- // Call: accAdd (arg1, arg2)
- // Return value: the exact result of adding arg2 to arg1
- 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
- }
- // Add an add method to the Number type to facilitate calling.
- Number. prototype. add = function (arg ){
- Return accAdd (arg, this );
- }
-
- // Subtraction function, used to obtain the exact subtraction result
- // Note: The addition result of javascript has an error, which is obvious when two floating point numbers are added. This function returns a more precise subtraction result.
- // Call: accSub (arg1, arg2)
- // Return value: the exact result of arg1 minus arg2
- 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
- // Dynamically control the Precision Length
- N = (r1> = r2 )? R1: r2;
- Return (arg1 * m-arg2 * m)/m). toFixed (n );
- }
- // Division function, used to obtain accurate division results
- // Note: the division result of javascript has an error, which is obvious when two floating point numbers are separated. This function returns a more precise division result.
- // Call: accDiv (arg1, arg2)
- // Return value: the exact result of dividing arg1 by 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 );
- }
- }
- // Add a div Method to the Number type to facilitate calling.
- Number. prototype. div = function (arg ){
- Return accDiv (this, arg );
- }
-
- // Multiplication function, used to obtain accurate multiplication results
- // Note: there is an error in the javascript multiplication result, which is obvious when two floating point numbers are multiplied. This function returns a more accurate multiplication result.
- // Call: accMul (arg1, arg2)
- // Return value: the exact result of multiplying arg1 by 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)
- }
- // Add a mul Method to the Number type to facilitate calling.
- Number. prototype. mul = function (arg ){
- Return accMul (arg, this );
- }
- <Br> // verify the following:
- 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 perform the floating point addition, subtraction, multiplication, division operation ~