6

困惑することがあり、VMの仕様に関する情報はあまり見つかりませんでした。少しわかりにくいので、誰かが私を説明してくれたらいいのにと思います。

これらの数行のコード.....

double myTest = Double.MAX_VALUE;

System.out.println("1. float: " + (float)myTest);
System.out.println("2. int: " + (int)myTest);
System.out.println("3. short: " + (short)myTest);
System.out.println("4. byte: " + (byte)myTest);

.....この出力を生成します:

  1. フロート:インフィニティ
  2. int:2147483647
  3. 短い:-1
  4. バイト:-1

byteshortおよびint2の補数を含む8、16、32ビットです。float32ビットおよびdouble64ビットのIEEE754です(ここを参照)。

私の理解では、aの最大値はdouble、仮数のすべてのビット(52ビット)が1に切り替えられることを意味します。したがって、shortまたはbyteへのキャストが-1を返すこと、つまりすべてのビットがに切り替えられることは(非常に)驚くべきことではありません。 1.キャストは、8ビットまたは16ビットdoubleに収まるようにの「テール」を保持しているようです。byteshort

私を驚かせるのは、へのキャストでintあり、程度は少ないですが、へのキャストfloatです。0x7FFFFFFFである「2.int:2147483647」を取得するにはどうすればよいですか。これは、shortおよびバイト3と4が-1の場合の最大値です。

キャストfloatも変です。の「テール」の32ビットが保持されている場合、それは?myTestを生成するべきではありません。NaN

4

1 に答える 1

6

JLSは、セクション5.1.3 NarrowingPrimitiveConversionのルールを詳しく説明しています。ルールはターゲットタイプによって異なります。

float

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

intおよびlong

次の2つのケースのいずれかが当てはまる必要があります。

  • ..。
  • 値が大きすぎる必要があり(大きさが大きい正の値または正の無限大)、最初のステップの結果は、int型またはlong型の表現可能な最大値になります。

bytecharおよびshort

ターゲットタイプが、、またはの場合bytechar2short段階で変換します。まず、上記のようdoubleにに変換さlongれます。次に、longは次のように最終タイプに変換されます。

符号付き整数から整数型Tへのナロー変換では、n個の最下位ビットを除くすべてが単純に破棄されます。nは型Tを表すために使用されるビット数です。数値の大きさに関する情報が失われる可能性があります。 、これにより、結果の値の符号が入力値の符号と異なる場合があります。

于 2012-05-07T07:45:43.847 に答える