9

私は標準的な参考文献を熟読するのに時間を費やしましたが、次の答えを見つけることができませんでした:

  • 符号付き整数型 S とその対応する符号なし U が与えられた場合、可能な各 S の絶対値は常に U の最大値以下であることが C/C++ 標準によって技術的に保証されていますか?

私が得た最も近いものは、C99 標準のセクション6.2.6.2からのものです (C++ の文言は私には難解ですが、これは同等であると思います):

符号付き整数型の場合、オブジェクト表現のビットは、値ビット、パディング ビット、符号ビットの 3 つのグループに分けられます。(...) 値ビットである各ビットは、対応する符号なし型のオブジェクト表現の同じビットと同じ値を持つものとします (符号付き型に M 個の値ビットがあり、符号なし型に N 個の値ビットがある場合、M≤ N)。

したがって、架空の 4 ビット符号付き/符号なし整数型では、符号なし型が 1 つのパディング ビットと 3 つの値ビットを持ち、符号付き型が 3 つの値ビットと 1 つの符号ビットを持つことを妨げるものはありますか? このような場合、符号なしの範囲は [0,7] になり、符号付きの場合は [-8,7] になります (2 の補数を仮定)。

誰かが興味を持っている場合に備えて、私は現時点で、最初に符号なしの対応するものへのキャスト、次に単項マイナス演算子の適用からなる負の整数の絶対値を抽出する手法に依存しています (そのため、たとえば - 3 はキャストによって 4 になり、次に単項マイナスによって 3 になります)。これは、unsigned 型で表すことができなかった -8 の上記の例では壊れます。

編集: Keith と Potatoswatter 以下の返信に感謝します。さて、私の最後の疑問点は、標準の文言における「サブレンジ」の意味です。それが厳密に「未満」の包含を意味する場合、上記の私の例と以下のキースの例は標準に準拠していません。サブ範囲が潜在的に unsigned の全範囲であることを意図している場合、それらはそうです。

4

2 に答える 2

7

C の場合、答えはノーです。そのような保証はありません。

intunsigned int;について説明します。これは、符号付きと符号なしの型の対応するペアに等しく適用されます (どちらもパディング ビットを持つことができない と を除く) charunsigned char

引用したセクションの標準は、 を暗黙的に保証していますUINT_MAX >= INT_MAX。これは、すべての非負のint値を として表すことができることを意味しunsigned intます。

しかし、以下は完全に合法です (**累乗を表すために使用します)。

CHAR_BIT == 8
sizeof (int) == 4
sizeof (unsigned int) == 4
INT_MIN  = -2**31
INT_MAX  = +2**31-1
UINT_MAX = +2**31-1

これintは、通常の 2 の補数表現である 1 つの符号ビット (必要に応じて) と 31 の値ビットをunsigned int持ち、31 の値ビットと 1 つのパディング ビットを持つことを意味します。 unsigned intそのパディング ビットが設定された表現は、トラップ表現であるか、パディング ビットが設定されていない値の余分な表現である可能性があります。

これは、2 の補数の符号付き算術をサポートしているが、符号なし算術のサポートが不十分なマシンに適している場合があります。

これらの特性を考えると、-INT_MIN(数学的な値) は の範囲外ですunsigned int

一方で、このような現代的なシステムが存在することを真剣に疑っています。パディング ビットは標準で許可されていますが、非常にまれであり、これ以上一般的になるとは考えていません。

次のようなものを追加することを検討してください。

#if -INT_MIN > UINT_MAX
#error "Nope"
#endif

したがって、必要なことができる場合にのみコンパイルされます。(もちろん、よりも適切なエラー メッセージを考えるべきです"Nope"。)

于 2012-07-07T04:08:57.087 に答える
3

了解しました。C++11 では、文言がより明確になります。§3.9.1/3:

符号付き整数型の負でない値の範囲は、対応する符号なし整数型の部分範囲であり、対応する各符号付き/符号なし型の値表現は同じでなければなりません。

しかし、対応する 2 つのタイプの間の接続の意味は実際には何なのでしょうか? それらは同じサイズですが、ローカル変数だけがある場合は問題ありません。

誰かが興味を持っている場合に備えて、私は現時点で、最初に符号なしの対応するものへのキャスト、次に単項マイナス演算子の適用からなる負の整数の絶対値を抽出する手法に依存しています (そのため、たとえば - 3 はキャストによって 4 になり、次に単項マイナスによって 3 になります)。これは、unsigned 型で表すことができなかった -8 の上記の例では壊れます。

マシンがサポートする数値範囲に対処する必要があります。署名されていない対応する型にキャストする代わりに、署名されていない型で十分なキャストを行います。必要に応じて、対応する型よりも大きい型にキャストします。十分な大きさの型が存在しない場合、マシンは目的の処理を実行できない可能性があります。

于 2012-07-07T03:47:31.293 に答える