ホームページ >ウェブフロントエンド >jsチュートリアル >JS-浮動小数点数演算処理の詳細説明
1. 問題の説明
私は最近、JS 浮動小数点計算にいくつかのバグがあることに気づきました。
JS の計算後に多くの問題が発生する 小さなエラー .Net や Java ほど正確ではない 主な理由は、JS が計算に焦点を当てていないことですが、よく考えてみると、プロジェクトで JS を使用する必要がある場合があります。おそらく 2 つの解決策です
解決策 1:
計算結果を小数点以下 2 ~ 3 桁に保持する。フロントエンド インターフェイスでは通常、使用する演算が少なくなります。精度の要件はそれほど高くありません。 したがって、小数点以下 2 桁を取得するだけです。
B. オプション 2:
小数点以下の桁数を整数演算に変換します。 例:
0.1+0.2 == 0.30000000000000004 0.1 + 0.7 == 0.7999999999999999 7*0.8 == 5.6000000000000005 5.6/7 == 0.7999999999999999
したがって、次の JSMath ライブラリを抽出することができます。 、減算、乗算、除算。パラメータは最初に整数に変換され、次に JSMath (パラメータ 2) が計算されます。パラメータ 1 とパラメータ 2 はそれぞれ、演算の最初の数値と 2 番目の数値です。計算では、値は Value 属性を通じて取得されます。
0.1+0.2 =》 (1+2)/10 == 0.3 0.1 + 0.7 =》 (1+7)/10 == 0.8 7*0.8 == (7*8)/10 == 5.6 5.6/7 == (56/7)/10 == 0.1
B1. 基本操作
(function() { var JSMath = function() { return this; } JSMath.prototype.from = function(value) { // 支持JSMath参数传递主要是用于嵌套的调用 if ((typeof(value) == 'object') && (value.value != undefined)) { this.value = value.value; } else { this.value = value; } return this; } // 加法 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(10, maxtimeCount) * this.value + Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount); return this; } // 减法 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(10, maxtimeCount) * this.value - Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount); return this; } // 除法 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(10, maxtimeCount) * this.value) / (Math.pow(10, maxtimeCount) * value)); return this; } // 乘法 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(10, maxtimeCount) * this.value * Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount * 2); return this; } if (window.JSMath == undefined) { window.JSMath = function(value) { var result = new JSMath(); result.from(value); return result; } } })()
B2. 複数オブジェクトの操作
0.1+0.2 => JSMath(0.1).add(0.2).value == 0.3 7+0.8 => JSMath(7).times(0.8).value == 5.6 5.6/7 => JSMath(5.6).div(7).value = 0.8
3.ちょっとしたまとめ
とりあえずわかっている解決策をいくつか。この問題を解決するための、より信頼性の高いオープンソースのサードパーティ ライブラリがあるかどうかは不明です。