重複の可能性:
JavaScript の数学は壊れていますか?
Javascript では、なぜreturn が、 whileが戻る230/100*100
のかわかりません229.99999999999997
240/100*100
240.
などにも当てはまり460, 920
ます...
解決策はありますか?
重複の可能性:
JavaScript の数学は壊れていますか?
Javascript では、なぜreturn が、 whileが戻る230/100*100
のかわかりません229.99999999999997
240/100*100
240.
などにも当てはまり460, 920
ます...
解決策はありますか?
230/100*100
= (230 / 100) * 100
= 2.3 * 100 in binary
2進数の2.3は循環 10 進数です。10.01001100110011001100110011001100...
この繰り返し小数は、精度が限られているため、正確に表すことができず、 のようなものになり2.29999999981373548507...
ます。
興味深いことに、2 進数で正確に表現できる (循環小数ではなく、すべての桁が FP 標準で対応する最大有効桁数内にある)ような除算演算を選択した場合、そのような不一致は見られません。
例225/100*100
=225
2.25
バイナリでは10.01
浮動小数点値が等しいかどうかをチェックするときは、常に精度に注意してください。特定の有効桁数に切り上げる/切り下げることは、良い方法です。
JavaScript では、すべての数値がIEEE 754 64 ビット浮動小数点値として格納されます (double
多くの言語では浮動小数点値としても知られています)。この表現には有限の精度しかなく (したがって、すべての数値を正確に表現できるわけではありません)、2 進数であるため、10 進数で表現するのは簡単に見える値でも、扱いに問題があることが判明する可能性があります。
すべての人に適したファイア アンド フォーゲット ソリューションはありません。整数が必要な場合は、 を使用して単純に丸めMath.round
ます。
同じ理由で、あなたが特定の精度にとどまることを余儀なくされ、すべてのステップを踏むことになった場合、あなたはとして与えるでしょ10/3*3
う9.99999...
。
あなたが維持しなければならなかった精度が10桁だったとしましょう。10/3
あなたが持っているだろう後3.333333333
。次に、これに3を掛けると、が得られます9.999999999
。
さて、3が永遠に続くことを知っているので、9が永遠に続くことを知っているので、答えは本当に10であることがわかります。しかし、それはここでの取引ではありません。できます、そして次に進みます。
繰り返し表現される数字だけでなく、正確に表現できるものもありますが、使用している桁数では表現できません。
10/3
10進数で完全に表現できないのと同じように、2進数で完全230/100
に表現することはできません。
この問題は、浮動小数点の不正確さに関連しています。詳細については、この質問を参照してください: 浮動小数点演算は壊れていますか?
JavaScript の除算は整数除算ではなく、浮動小数点です。
2.3 または 2.4 は浮動小数点で正確に表現できません。違いは、2.4 の最も近い fp が 2.4000000953 であるのに対し、2.3 は約 2.2999999523 であることです。
使用するMath.round(x)
か、JavaScript トリックを使用することができます。
(x|0) は、'|' として x を整数に変換します。演算子は、オペランドを整数に強制します。この場合でも、299.9943 は丸められず、切り捨てられます。