3

この小さなコードの宣伝文句

    Dim s As Single = 1.15
    Dim d As Double = CDbl(s)
    Console.WriteLine(s)
    Console.WriteLine(d)

収量:

1.15
1.14999997615814

これは完全に予想外です。なぜこれが起こっているのですか?どうすれば修正できますか?

到着予定時刻:

これは私のコードではなく、元の入力が文字列 "1.15" として入ってきたことが判明したため、それを single に変換してから double に変換していました。ひとつの部品を取り除いたことで、みんながうれしくなりました。

4

2 に答える 2

1

sとにはまったく同じ数値が含まれていますが、とテキストへの変換にd使用される桁数が異なるため、異なる数字が表示されます。SingleDouble

Console.WriteLine(s)ここに記載されているフォーマット指定子「G」を使用して変換する usingのConsole.WriteLine(Single)テキスト表現を生成する呼び出し。同様に、 を呼び出します。sSingle.ToStringConsole.Writeline(d)Double.ToString

ドキュメントによると、使用される最大桁数は の場合は 7 桁、 の場合はSingle15 桁ですDouble。実際に使用される桁数を指定しているドキュメントはありません。最大値のみです。

このステートメントは、 1.15 に最も近い値である 1.14999997615814208984375 にDim s As Single = 1.15設定します。(2 番目に近いのは 1.150000095367431640625 です。)その値を 7 桁に丸めると、結果は「1.150000」になります。私は、.NET が末尾のゼロを省略して「1.15」を生成していると推測します。sSingle

d同じ値に設定して印刷すると、15 桁が使用されます。1.14999997615814208984375 を 15 桁に四捨五入すると、結果は「1.14999997615814」になります。

したがって、 aSingleを に変換してもエラーは発生しませんDouble。これは単なる表示の錯覚です。

Doubleを に変換すると、一般にエラーが発生することに注意してくださいSingle。と書いたDim d As Double = 1.15場合、d1.149999999999999911182158029987476766109466552734375 に設定され、Console.WriteLine(d)「1.15」が生成されると予想されます。に変換dするSingleと、1.14999997615814208984375 が生成されます。

于 2013-05-23T16:27:54.407 に答える
1

コンピュータ サイエンスの用語では、精度は仮数と指数のサイズで表されます。「有効数字」とは関係ありません。おそらく最も紛らわしいのは、基数 2の浮動小数点数を基数 10で表示しているという事実です。

2 つの値の基数 2 の表現を見ると、それらがそれほど離れていないことがわかります。

10 進数の 1.15 のバイナリ値は 1.00100110011001... ad infinitumです。で 23 ビットの仮数を取得しSingle、 で 52 ビットの仮数を取得しDoubleます。明らかに、有限の精度では、仮数の繰り返しはさまざまな場所で途切れます。

数値を同じ 10 進数の表現で表示したい場合は、文字列変換ルーチンに、より適切な方法でフォーマットするように通知しない限り、多少のズレを我慢する必要があります。

于 2013-05-23T15:25:44.887 に答える