web-dev-qa-db-ja.com

JavaScript float比較

JavaScriptでの数値比較で大きな問題が発生しています。

スクリプトは、比較 "7 <10"が偽であると非難します。

console.clear();

var min = parseFloat("5").toFixed(2);
var max = parseFloat("10").toFixed(2);
var value = parseFloat("7").toFixed(2);

console.log(min, max, value);

console.log(value > min); // OK.
console.log(value < max); // ---- false ??????

誰もがハッピングを知っていますか?

23
Alexandre Perez

結局のところ、.toFixed()は文字列を返します-値を比較する前にparseFloatを追加して結果を確認してください。

console.log(parseFloat(value) < parseFloat(max)); // ---- now true
40
prototype

常に浮動小数点数を丸める必要があります、または場合によっては奇妙な結果が得られます。

これを試して問題を確認してください:console.log(parseFloat(6760/100*100));

丸めにより、正しい結果が得られます。

console.log(Math.round(parseFloat(value)*100000) < Math.round(parseFloat(max)*100000));

または、次のようなものを使用してみることもできます http://mikemcl.github.io/decimal.js/

浮動小数点数は正確な数値ではなく、数値を厳密に表現したものです。

それは実際にはかなり簡単です。 (私たちのような)基数10のシステムがある場合、それは基数の素因数を使用する分数のみを表現できます。 10の素因数は2と5です。したがって、分母はすべて10の素因数を使用するため、1/2、1/4、1/5、1/8、1/10はすべてき​​れいに表現できます。対照的に、1/3、1/6、および1/7は、分母が3または7の素因数を使用するため、すべて10進数の繰り返しです。2進数(または基数2)では、素因数は2のみです。素因数として2のみを含みます。 2進数では、1/2、1/4、1/8はすべて小数としてきれいに表現されます。 1/5または1/10は小数の繰り返しです。したがって、0.1と0.2(1/10と1/5)は、基数10のシステムでは小数をクリーンにし、コンピューターが動作する基数2のシステムでは小数を繰り返します。これらの繰り返し小数で計算を行うと、次のようになります。コンピューターの底2(2進数)をより人間が読める底10の数に変換するときに持ち越される残り物。 ソース


これは JavaScriptの問題ではありません です。これは、コンピューターが実際に理解しているのは1と0だけだからです。

トピックの詳細を知りたい場合は、これを出発点としてお勧めします。 https://docs.Oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

6
Lukas Liesis