10

重複の可能性:
JavaScript の数学は壊れていますか?

Javascript では、なぜreturn が、 whileが戻る230/100*100のかわかりません229.99999999999997240/100*100240.

などにも当てはまり460, 920ます...

解決策はありますか?

4

5 に答える 5

9

問題:

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

変換のテスト: 2 進数から 10 進数への変換


それに対処する:

浮動小数点値が等しいかどうかをチェックするときは、常に精度に注意してください。特定の有効桁数に切り上げる/切り下げることは、良い方法です。

于 2012-11-06T09:43:06.880 に答える
8

JavaScript では、すべての数値がIEEE 754 64 ビット浮動小数点値として格納されます (double多くの言語では浮動小数点値としても知られています)。この表現には有限の精度しかなく (したがって、すべての数値を正確に表現できるわけではありません)、2 進数であるため、10 進数で表現するのは簡単に見える値でも、扱いに問題があることが判明する可能性があります。

すべての人に適したファイア アンド フォーゲット ソリューションはありません。整数が必要な場合は、 を使用して単純に丸めMath.roundます。

于 2012-11-06T09:40:58.547 に答える
1

同じ理由で、あなたが特定の精度にとどまることを余儀なくされ、すべてのステップを踏むことになった場合、あなたはとして与えるでしょ10/3*39.99999...

あなたが維持しなければならなかった精度が10桁だったとしましょう。10/3あなたが持っているだろう後3.333333333。次に、これに3を掛けると、が得られます9.999999999

さて、3が永遠に続くことを知っているので、9が永遠に続くことを知っているので、答えは本当に10であることがわかります。しかし、それはここでの取引ではありません。できます、そして次に進みます。

繰り返し表現される数字だけでなく、正確に表現できるものもありますが、使用している桁数では表現できません。

10/310進数で完全に表現できないのと同じように、2進数で完全230/100に表現することはできません。

于 2012-11-06T09:56:51.087 に答える
1

この問題は、浮動小数点の不正確さに関連しています。詳細については、この質問を参照してください: 浮動小数点演算は壊れていますか?

于 2012-11-06T09:42:20.990 に答える
0

JavaScript の除算は整数除算ではなく、浮動小数点です。

2.3 または 2.4 は浮動小数点で正確に表現できません。違いは、2.4 の最も近い fp が 2.4000000953 であるのに対し、2.3 は約 2.2999999523 であることです。

使用するMath.round(x)か、JavaScript トリックを使用することができます。

(x|0) は、'|' として x を整数に変換します。演算子は、オペランドを整数に強制します。この場合でも、299.9943 は丸められず、切り捨てられます。

于 2012-11-06T09:43:54.867 に答える