3

このループは無期限に続きます。

char a = 100;
for(a=100; a>=0;--a)
    System.out.println(a);

a が算術演算の int 値に昇格し、16 ビットの char 値から 32 ビットに拡張され、常に正のままになるために発生しますか?

4

3 に答える 3

8

それは確かに無期限にループします-そしてあなたが述べた理由は近いです。これは、満たさないa数値を表すことができないために発生します--は署名されていません。算術アンダーフローは Java で明確に定義されており、明示されていません。以下の仕様の関連部分を参照してください。a >= 0char

  • §4.2.2

    整数演算子は、オーバーフローまたはアンダーフローを決して示しません。

    これは、単に値を比較する以外にオーバーフロー/アンダーフローの兆候がないことを意味します...たとえば、a<=--aの場合、アンダーフローが発生したことを意味します。

  • §15.15.2

    減算の前に、値 1 と変数の値に対してバイナリ数値昇格 (§5.6.2) が実行されます。必要に応じて、プリミティブ変換 (§5.1.3) を縮小することによって差異を縮小するか、格納する前に変数の型へのボックス化変換 (§5.1.7) を適用します。前置デクリメント式の値は、新しい値が格納された後の変数の値です。

    したがって、ここには 2 つの主要なステップがあることがわかります。2 進数値の昇格と、それに続く原始的な縮小変換です。

  • §5.6.2

    拡張プリミティブ変換 (§5.1.2) は、次の規則で指定されているように、オペランドの一方または両方を変換するために適用されます。

    • いずれかのオペランドの型が の場合double、もう一方は に変換されdoubleます。
    • それ以外の場合、いずれかのオペランドが 型のfloat場合、もう一方は に変換されfloatます。
    • それ以外の場合、いずれかのオペランドが 型のlong場合、もう一方は に変換されlongます。
    • それ以外の場合、両方のオペランドが type に変換されますint

    aデクリメント式が扱いとして扱われint、拡大変換を実行することがわかります。これにより、値-1を表すことができます。

  • §5.1.3

    縮小プリミティブ変換では、数値の全体的な大きさに関する情報が失われる可能性があり、精度と範囲も失われる可能性があります。

    ...

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

    下位nビットのみを保持するということは、int式の下位 16 ビットのみa - 1が保持されることを意味します。ここでは-1は0b11111111 11111111 11111111 11111111なので、下位の0b11111111 11111111だけが保存されます。charは符号なしであるため、これらすべてのビットが結果に寄与し、65535が得られます。

ここで何か気づきましたか?基本的に、これは Java 整数演算がモジュラーであることを意味します。この場合、係数は2^16または65536です。これcharは が 16 ビットのデータ型であるためです。-1 (mod 65536) ≡ 65535であるため、デクリメントはラップアラウンドします。

于 2012-09-09T06:01:58.100 に答える
4

いいえ。char値は符号なしです。値が 0 を下回ると、約 65535 に戻ります。

と交換charbyteます-それでうまくいきます。

于 2012-09-09T06:01:35.660 に答える
1

他の人が言ったようにchar、Java の型は署名されていないため、a >= 0常に true になります。0にa達してからもう一度デクリメントすると、65535 になります。ひねくれ者になりたい場合は、次のように 101 回の反復後にループを終了するように記述できます。

char a = 100;
for(a=100; a<=100;--a)
    System.out.println(a);

コードレビュー担当者は、そのような恐ろしいことを書いたことであなたを引き裂くフィールドデイを過ごすことができます. :)

于 2012-09-09T06:25:44.150 に答える