I. Description of the problem
Recently in a project, there will be some JS floating-point arithmetic on the page, found that JS floating-point arithmetic there are some bugs. For example:
0.1+0.2 = = 0.300000000000000040.1 + 0.7 = = 0.79999999999999997*0.8 = = 5.60000000000000055.6/7 = 0.7999999999999999
Two. Solution
JS operation will have a very small error. Not like. NET or Java as accurate. Mainly JS is not the focus of the operation above, but sometimes the project must be used. Think about it. There are probably two solutions.
A programme I:
The result of the operation retains 2-3 decimal digits. The front-end interface generally uses less operations. The accuracy requirement is not too high. So take 2 decimal digits.
B. Programme II:
Converts the number of decimal digits to an integer operation. Such as:
0.1+0.2 = "(1+2)/10 = = 0.30.1 + 0.7 =" (1+7)/10 = = 0.87*0.8 = (7*8)/10 = = 5.65.6/7 = (56/7)/10 = 0.1
For ease of invocation. So we can extract a public way out. For example, the following Jsmath library, Jsmath rewritten subtraction. The argument is converted to an integer before the operation Jsmath (parameter 1). Operation (Parameter 2)
Parameters 1 and 2, respectively, are the first number and the second number of the operation. Gets the value through the Value property after the calculation.
(function () {var jsmath = function () {return this; } JSMath.prototype.from = function (value) {///support Jsmath parameter pass is primarily used for nested call if ((typeof (value) = = ' object ') &am p;& (Value.value! = undefined)) {this.value = Value.value; } else {this.value = value; } return this; }//Addition JSMath.prototype.add = function (value) {var thisvaluestring = this.value.toString (); var valuestring = value.tostring (); var timesCount1 = 0; var timesCount2 = 0; if (Thisvaluestring.indexof ('. ') > 0) {timesCount1 = Thisvaluestring.split ('. ') [1].length; } if (Valuestring.indexof ('. ') > 0) {timesCount2 = Valuestring.split ('. ') [1].length; } var maxtimecount = timesCount1 > TimesCount2? Timescount1:timescount2; This.value = (Math.pow (ten, Maxtimecount) * this.value + Math.pow (Ten, Maxtimecount) * value)/Math.pow (ten, Maxtimecount); return this; }//Subtraction JSMath.prototype.sub = function (value) {var thisvaluestring = this.value.toString (); var valuestring = value.tostring (); var timesCount1 = 0; var timesCount2 = 0; if (Thisvaluestring.indexof ('. ') > 0) {timesCount1 = Thisvaluestring.split ('. ') [1].length; } if (Valuestring.indexof ('. ') > 0) {timesCount2 = Valuestring.split ('. ') [1].length; } var maxtimecount = timesCount1 > TimesCount2? Timescount1:timescount2; This.value = (Math.pow (ten, Maxtimecount) * THIS.VALUE-MATH.POW (Ten, Maxtimecount) * value)/Math.pow (Maxtimecount); return this; }//Division JSMath.prototype.div = function (value) {var thisvaluestring = this.value.toString (); var valuestring = value.tostring (); var timesCount1 = 0; var timesCount2 = 0; if (Thisvaluestring.indexof ('. ') > 0) {timesCount1 = Thisvaluestring.split(‘.‘) [1].length; } if (Valuestring.indexof ('. ') > 0) {timesCount2 = Valuestring.split ('. ') [1].length; } var maxtimecount = timesCount1 > TimesCount2? Timescount1:timescount2; This.value = ((Math.pow (Ten, Maxtimecount) * this.value)/(Math.pow (Ten, Maxtimecount) * value)); return this; }//Multiplication JSMath.prototype.times = function (value) {var thisvaluestring = this.value.toString (); var valuestring = value.tostring (); var timesCount1 = 0; var timesCount2 = 0; if (Thisvaluestring.indexof ('. ') > 0) {timesCount1 = Thisvaluestring.split ('. ') [1].length; } if (Valuestring.indexof ('. ') > 0) {timesCount2 = Valuestring.split ('. ') [1].length; } var maxtimecount = timesCount1 > TimesCount2? Timescount1:timescount2; This.value = (Math.pow (ten, Maxtimecount) * This.value * MATH.POW (Ten, Maxtimecount) * value)/Math.pow (MaxtimecoUNT * 2); return this; } if (window. Jsmath = = undefined) {window. Jsmath = function (value) {var result = new Jsmath (); Result.from (value); return result; } }})()
B1. Basic operations
0.1+0.2=> Jsmath (0.1). Add (0.2). Value = = 0.37+0.8=> Jsmath (7). Times (0.8). Value = = 5.65.6/7=> Jsmath (5.6). Div ( 7). Value = 0.8
B2. Multi-Mesh operation
0.05 + 0.05 + 0.2=> Jsmath (Jsmath (0.05). Add (0.05)). Add (0.2). Value = = 0.3 (5+0.6)/7=> Jsmath (Jsmath (5). Add (0.6)). Div (7). Value = = 0.8
Three Small summary
Some of the solutions that I know for the time being. It is not clear whether there is a more reliable tripartite library to solve this problem, if any, I hope Bo friends recommend.
Post some of the solutions that Stockoverflow see:
Http://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript
Http://stackoverflow.com/questions/3556789/javascript-math-error-inexact-floats
js--floating-point arithmetic processing