web-dev-qa-db-ja.com

Javaでdoubleからfloatに変換する

doubleを使用していて、それをfloatに変換した場合、これはどのように正確に機能しますか?値は切り捨てられて浮動小数点数に収まりますか?または、値は異なる方法で丸められますか?これは少し改善のように聞こえますが申し訳ありませんが、私はfloatおよびdouble変換の概念を理解しようとしています。

21
Franklin

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

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

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

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

19

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

Doubleをfloatにキャストすると、doubleで表されるdoubleの範囲が値の範囲に含まれるfloatが選択されます。この操作は元に戻せませんが、操作の結果は通常、算術的に正しいことに注意してください。算術的に100%正しくない唯一の時間は、2つの浮動小数点数の境界に正確に中心が合わせられているdoubleを浮動小数点数にキャストする場合です。その場合、システムはdoubleの範囲の片側または反対側のフロートを選択します。 doubleが実際に範囲の反対側の数値を表す場合、結果の変換はわずかに不正確になります。

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

Javaは前者を警告なしで暗黙的に許可しますが、後者でスコークしますが、floatをdoubleにキャストすることは、doubleをfloatにキャストするよりも実際にははるかに危険な操作であることに注意することが重要です。 floatからdoubleに設定すると、システムは浮動小数点の範囲の中心を中心とするdoubleを選択します。これにより、ほとんどの場合、実際の不確実性は倍精度数の典型的な値よりもはるかに大きい値になります。次に例を示します。 0.1fをdoubleにキャストすると、結果として生じるdoubleは、0.10000000149011611から0.10000000149011613の範囲の数値を表します。

9
supercat