21

を使用していてdouble、それをに変換した場合、floatこれはどのように正確に機能しますか?値は切り捨てられてフロートに収まりますか?または、値の丸めが異なりますか?これが少し改善されたように聞こえたら申し訳ありませんが、私は変換の概念floatdouble変換を把握しようとしています。

4

2 に答える 2

19

Java言語仕様のセクション5.1.3から:

doubleからfloatへのナローイングプリミティブ変換は、IEEE 754丸め規則(§4.2.4)によって管理されます。この変換は精度を失う可能性がありますが、範囲も失う可能性があり、その結果、非ゼロのdoubleからはfloatゼロになり、有限のdoubleからはfloat無限大になります。二重NaNは浮動小数点NaNに変換され、二重無限大は同じ符号の浮動小数点無限大に変換されます。

そしてセクション4.2.4は言う:

Javaプログラミング言語では、浮動小数点演算は、すべての浮動小数点演算子が浮動小数点の結果を結果の精度に丸めたかのように動作する必要があります。不正確な結果は、無限に正確な結果に最も近い表現可能な値に丸める必要があります。最も近い2つの表現可能な値が等しく近い場合、最下位ビットがゼロの値が選択されます。これは、IEEE754標準のデフォルトの丸めモードです。これは最も近い値への丸めとして知られています。

于 2012-04-09T14:55:52.560 に答える
9

浮動小数点型は、値の範囲を表すものとして最も有用に見なされることをお勧めします。0.1fが0.100000001490116119384765625ではなく0.1として表示される理由は、実際には13421772.5/134217728から13421773.5/134217728までの数値の範囲(つまり、0.0999999977648258209228515625から0.1000000052154064178466796875)を表すためです。数値が小さい場合は0.100より大きいことを示す数字を追加したり、数値が大きい場合は0.100未満であることを示す9の文字列を使用したりすることは意味がありません。

ダブルをフロートにキャストすると、値の範囲にダブルで表されるダブルの範囲が含まれるフロートが選択されます。この操作は元に戻せませんが、操作の結果は一般に算術的に正しいことに注意してください。100%算術的に正しくないのは、2つのフロートの境界を正確に中心とした範囲のダブルをフロートするためにキャストした場合だけです。そのような状況では、システムはダブルの範囲の片側または反対側のフロートを選択します。doubleが実際に範囲の反対側の数値を表している場合、結果の変換はわずかに不正確になります。

実際には、浮動小数点型で表される「値の範囲」は実際には上記よりも少し大きいため、上記の小さな不正確さはほとんど関係ありません。ある程度の不確実性がある2つの数値に対して計算(加算など)を実行すると、より不確実な結果が得られますが、システムはどの程度の不確実性が存在するかを追跡しません。それでも、フロートで数十回の操作を実行したり、ダブルで数千回の操作を実行したりしない限り、不確実性の量は通常、心配する必要がないほど十分に小さくなります。

フロートをダブルにキャストすることは、ダブルをフロートにキャストするよりも実際にははるかに危険な操作であることに注意することが重要です。フロートをダブルにキャストすると、システムは、フロートの範囲の中心を中心に範囲が設定されているダブルを選択します。これにより、ほとんどの場合、実際の不確かさが倍精度数値の一般的な値よりもはるかに大きい値になります。たとえば、0.1fをdoubleにキャストすると、結果のdoubleは、0.10000000149011611から0.10000000149011613の範囲の数値を表しますが、それが表すはずの数値(10分の1)は、比較的言えば、その範囲にはほど遠いものです。

于 2012-05-31T15:43:50.157 に答える