20

追加の値の範囲を必要としない場合、変数を unsigned int として宣言する必要がありますか? たとえば、for ループで変数を宣言するときに、それが負にならないことがわかっている場合、それは問題になるでしょうか? 一方は他方より速いですか?C++ で unsigned と同じように unsigned int を宣言するのは悪いことですか?

繰り返しますが、余分な範囲が必要ない場合でも、それを行う必要がありますか? 混乱を招くため、避けるべきだと聞きました(IIRCがJavaにないのはそのためです)。

4

7 に答える 7

14

負の値を持つ意味がない場合は、符号なし整数を使用する必要があります。これは範囲の問題とは完全に無関係です。はい、余分な範囲が必要ない場合でも符号なし整数型を使用する必要があります。必要でない場合は s (またはその他のもの) を使用しないでくださいunsigned int。ただし、必要なものの定義を修正する必要があります。

于 2012-09-01T06:40:59.697 に答える
13

uint を使用する理由は、コンパイラにさまざまな最適化を提供するためです。たとえば、x が正であることがわかっている場合は、'abs(x)' のインスタンスを 'x' に置き換えることができます。また、正の数に対してのみ機能するさまざまなビット単位の「強度削減」も可能になります。int を常に 2 のべき乗で乗算/除算する場合、コンパイラは演算をビット シフト (つまり、x*8 == x<<3) に置き換えることができ、実行速度が大幅に向上します。残念ながら、この関係は「x」が正の場合にのみ成立します。これは、負の数がこれを排除する方法でエンコードされているためです。int の場合、値が常に正であることを証明できる場合 (またはコードの前の方で正の値になるように変更できる場合)、コンパイラはこのトリックを適用できます。uint の場合、この属性は簡単に証明できます。

別の例として、式がありますy = 16 * x + 12。x が負になる可能性がある場合は、乗算と加算が必要になります。ただし、x が常に正の場合、x*16 項を x<<4 に置き換えることができるだけでなく、項は常に 4 つのゼロで終わるため、「+ 12」をバイナリ OR に置き換えることができます (限り「12」項は 16 未満であるため)。結果は になりますy = (x<<4) | 12

一般に、「unsigned」修飾子は、変数に関するより多くの情報をコンパイラに提供します。これにより、コンパイラはより多くの最適化を行うことができます。

于 2012-09-01T07:05:34.773 に答える
9

多くの場合、符号なし整数を使用する必要があります。

オーバーフローなどの未定義の動作に関しては、より予測可能です。
これはそれ自体が大きなテーマなので、これ以上は説明しません。
実際に符号付きの値が必要でない限り、符号付き整数を避けるのは非常に良い理由です。

また、範囲チェックの際の操作も簡単です。負の値をチェックする必要はありません。

一般的な経験則:

  • 制御変数としてインデックスを使用して順方向forループを作成している場合、ほとんどの場合、符号なし整数が必要になります。実際、ほとんどの場合、 が必要です。size_t

  • 制御変数としてインデックスを使用して逆forループを作成している場合は、明らかな理由から、おそらく符号付き整数を使用する必要があります。おそらくそうするでしょptrdiff_tう。

注意すべきことの 1 つは、異なるサイズの符号付き値と符号なし値の間でキャストする場合です。
キャストが期待どおりに機能していることを確認するために、おそらくダブルチェック (またはトリプルチェック) を行う必要があります。

于 2012-09-01T07:05:46.383 に答える
7

int汎用整数型です。整数が必要で、int要件 (範囲 [-32767,32767]) を満たす場合は、それを使用します。

より専門的な目的がある場合は、他のものを選択できます。配列へのインデックスが必要な場合は、 を使用しますsize_t。ベクトルへのインデックスが必要な場合は、 を使用しますstd::vector<T>::size_type。特定のサイズが必要な場合は、 から何かを選択して<cstdint>ください。64 ビットより大きいものが必要な場合は、gmpなどのライブラリを見つけてください。

を使用する正当な理由が思いつきませんunsigned int。少なくとも、直接ではありません (size_tまた、特定のサイズの型の一部は の<cstdint>typedef である可能性がありますunsigned int)。

于 2012-09-01T07:53:44.863 に答える
6

when values can't be negativeの体系的な使用に関する問題はunsigned、Java に がないことunsignedではありません。符号なしの値を持つ式、特に符号付きの値と混合した場合、符号なしを範囲をずらした整数型。unsigned はモジュラー型であり、整数を正またはゼロに制限するものではありません。

したがって、従来のビューはunsigned、モジュラー型が必要な場合やビットごとの操作に使用する必要があります。そのビューは K&R では暗黙的です — int と unsigned がどのように使用されているかを見てください — そして TC++PL (第 2 版、p. 50) ではより明示的です:

整数型は、unsignedストレージをビット配列として扱う用途に最適です。unsignedの代わりに を使用して、int正の整数を表すためにもう 1 ビット取得することは、ほとんど良い考えではありません。変数を宣言することによっていくつかの値が正であることを保証しようとする試みunsignedは、通常、暗黙的な変換規則によって失敗します。

于 2012-09-01T08:48:41.113 に答える
2

In almost all architectures the cost of signed operation and unsigned operation is the same. So efficiency wise you wont get any advantage for using unsigned over signed. But as you pointed out, if you use unsigned you will have a bigger range

于 2012-09-01T06:45:42.657 に答える