15

このテーマに関する情報を簡単に理解できる方法で見つけるのはかなり困難だったので、見つけたもののレビューを求めています。それはすべて変換と変換のみです。


例では、次のことを参照します。

(signed/unsigned) int bigger;
(signed/unsigned) char smaller;
  1. 整数の切り捨て。(大きい→小さい)

    • サイズに合わせて最初にMSB側を切り捨てます。 biggersmaller
    • 次に、小さい型に応じて、切り捨てられた結果を符号付き/符号なし変換します。


    大きい値が大きすぎて小さい型に収まらない場合、未定義の動作が発生します (これについては訂正してください)。ただし、私のルールはすべてのマシンで機能する必要があり (それについても訂正してください)、結果は予測可能である必要があります。

  2. 整数の拡大(小さい -> 大きい)

    a) signed char->signed int

    • 大きい方のサイズに合わせて小さい方に MSB (1 または 0) を付加します
    • 署名付きに変換

    b) signed char->unsigned int

    • 小さい方の先頭に MSB (1 または 0) を追加して、大きい方のサイズに合わせます。
    • 無署名に変換

    c) unsigned char->signed int

    • 大きいサイズに合わせて先頭に 0 を追加
    • 署名付きに変換

    d) unsigned char->unsigned int

    • 大きいサイズに合わせて先頭に 0 を追加
    • 無署名に変換

私が言及しなかった未定義/未指定の動作がポップアップする可能性があるのはどこですか?

4

2 に答える 2

23

整数変換は、未定義の動作を生成することはありません (実装定義の動作を生成する可能性があります)。

変換される値を表すことができる型への変換は、常に明確に定義されています。値は変更されないままです。

符号なし型への変換は、常に明確に定義されています。値はモジュロ UINT_MAX+1 (またはターゲット型が許容する最大値) で取得されます。

変換される値を表すことができない符号付き型への変換は、実装定義の値または実装定義のシグナルのいずれかになります。

上記のルールは整数値に関して定義されており、ビットのシーケンスに関して定義されていないことに注意してください。

于 2013-10-09T14:14:39.037 に答える