web-dev-qa-db-ja.com

「int mask =〜0;」の目的は何ですか?

私は次のコード行を見ました here C.

 int mask = ~0;

CおよびC++でmaskの値を出力しました。常に-1を出力します。

だから私はいくつかの質問があります:

  • なぜ値~0mask変数に割り当てるのですか?
  • ~0の目的は何ですか?
  • -1の代わりに~0を使用できますか?
44
Jayesh

これは、現在のアーキテクチャで整数に含まれるビット数を知る必要なく、整数のすべてのバイナリビットを1ビットに設定するポータブルな方法です。

79
Richard Hodges

CおよびC++では、符号の大きさ、1の補数、2の補数の3つの異なる符号付き整数形式を使用できます。

~0は、符号形式に関係なく、すべて1ビットのを生成しますシステムが使用します。 ポータブル-1より

U接尾辞(つまり、-1U)を追加して、オールワンビットパターンportablyを生成できます。1。ただし、~0意図をより明確に示す:値0のすべてのビットを反転します。一方、-1は、バイナリ表現ではなく、マイナス1の値が必要であることを示します

1 符号なしの演算は常に 結果の型で表現できる最大値よりも1大きい数を法とする縮小

36
phuclv

2の補数プラットフォーム(想定)で-1が得られますが、-1を直接書き込むことは規則(整数0..255、単項!~およびバイナリ&^|+<<および>>は許可されます)。

8
6502

特定のタスクを実行するために、演算子と言語構成にいくつかの制限があるコーディングの課題を勉強しています。

最初の問題は、-演算子を使用せずに値-1を返すです。

2の補数で負の数を表すマシンでは、値-1はすべてのビットが1に設定されて表されるため、~0-1に評価されます。

/* 
 * minusOne - return a value of -1 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 2
 *   Rating: 1
 */
int minusOne(void) {
  // ~0 = 111...111 = -1
  return ~0;
}

ファイル内の他の問題は、常に正しく実装されていません。 2番目の問題は、int値が16ビット符号付きshortに収まるという事実を表すブール値を返すことです:

/* 
 * fitsShort - return 1 if x can be represented as a 
 *   16-bit, two's complement integer.
 *   Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 1
 */
int fitsShort(int x) {
  /* 
   * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
   * so after shift, if x remains the same, then it means that x can be represent as 16-bit
  */
  return !(((x << 16) >> 16) ^ x); 
}

負の値またはシフト値がintの範囲を超える数値を左にシフトすると動作が未定義になり、負の値を右にシフトすると実装定義になるため、上記のソリューションは正しくありません(おそらく予想されるソリューションです) 。

5
chqrlie

これは、1K ZX 80やZX 81コンピューターなどの非常に限られた機器でメモリを節約する方法でした。 BASICでは、あなたは

Let X = NOT PI

のではなく

LET X = 0

数値は4バイトの浮動小数点として格納されているため、後者は最初のNOT PIの代替よりも2バイト多く、NOTとPIのそれぞれが1バイトを使用します。

2
skaak

すべてのコンピューターアーキテクチャで数字をエンコードする方法は複数あります。 2の補数を使用する場合、これは常にtrue:~0 == -1になります。一方、一部のコンピューターは、~0 == -0であるため、上記の例が当てはまらない負の数のエンコードに1の補数を使用します。うん、1の補数には負のゼロがあり、それが非常に直感的でない理由です。

あなたの質問に

  • 〜0がマスクに割り当てられているため、マスク内のすべてのビットは1-> mask & sth == sthになります。
  • 〜0は、使用されるプラットフォームに関係なく、すべてのビットを1に等しくするために使用されます
  • コンピュータープラットフォームが2の補数エンコードを使用していることが確実な場合は、〜0の代わりに-1を使用できます

私個人の考え-コードをできるだけプラットフォームに依存しないようにします。コストは比較的小さく、コードはフェイルプルーフになります

0
bartop