1

私はgrailsプロジェクトでこの奇妙な除算エラーが発生しました(しかし、grailsはそれとはほとんど関係がないと思います。GroovyまたはJavaの質問だと思います):

グルーヴィーなコンソールでこれを実行する場合

float money = -1.30
float r = 0.01

println ((money/r).class.name)
println ((money/r).floatValue())
println ((money/r).toString() )

この出力を取得します

java.lang.Double
-130.0
-129.99999813735482

groovyのfloat除算は私にDoubleを与えます、そしてこれは正しいです、しかしなぜDouble toString()は私にとても奇妙な値 "-129.99999813735482"を与え、正しい "-130.0"ではないのですか?

4

3 に答える 3

6

浮動小数点ガイドから:

0.1 + 0.2のような私の数値を合計すると、良いラウンド0.3になりませんが、代わりに0.30000000000000004のような奇妙な結果が得られますか?

内部的には、コンピューターは0.1、0.2、0.3などの数値を正確に表すことができない形式(2進浮動小数点)を使用しているためです。

コードがコンパイルまたは解釈されるとき、「0.1」はすでにその形式で最も近い数値に丸められているため、計算が行われる前でも小さな丸め誤差が発生します。

具体的には、1.3も0.01もaで正確に表すことはできませんfloat

于 2012-12-03T12:04:41.533 に答える
5

誰もが言うように、doubleそしてfloatあなたがやろうとしていることに対して十分に正確ではありません。

float1つの解決策は、オブジェクトタイプとして使用せず、次のことを行うことです。

def money = -1.30
def r = 0.01

println ((money/r).class.name)
println ((money/r).floatValue())
println ((money/r).toString() )

ご覧のとおり、Groovyはを使用しますBigDecimal。これは、出力が次のことを意味します。

java.math.BigDecimal
-130.0
-130
于 2012-12-03T12:07:38.317 に答える
1

を実行することによりfloatValue、値の精度を制限します。したがって、JVMは丸めを行い、異なる値を取得します。

また、「130.0は正しい値であるため、計算された値である必要があります」と言う前に、コンピューターは2進数形式を使用して小数を表すため、分数で丸め誤差が発生することに注意してください(理由を理解するには、0.3を2進数で表すようにしてください)。 。

于 2012-12-03T12:06:05.607 に答える