web-dev-qa-db-ja.com

2つの整数のXORは範囲外になりますか?

私は配列で孤独な整数を見つけるためのアルゴリズムを研究していましたが、ここに実装があります:

int arr[] = {10, 20, 30, 5, 20, 10, 30};
int LonelyInteger = 0;
for(int i=0; i< 7; i++)
{
    LonelyInteger = LonelyInteger ^ arr[i];
}

結果は5

私の質問は-おそらく整数(XOR操作によって生成される)は大きすぎるこの操作のためです:

LonelyInteger ^ arr[i]

この場合、intなどのデータ型で表現できない潜在的に大きな整数になります。私の質問は:

  1. XORint型に格納できないような大きな整数値を生成する可能性さえありますか?
  2. これが発生する可能性がない場合、その証拠はありますか?
51
Expert Novice

XORは、ビットを結合し、以前にビットが設定されていない新しいビットを作成しないため、範囲外になることはありません。

結果 5 正しい。値のバイナリ表現とXOR結果を見てください

10    00001010
20    00010100
30    00011110
 5    00000101
20    00010100
10    00001010
30    00011110
--------------
      00000101 => 5

多くのXORed値の結果を計算するための簡単なヘルプは次のとおりです。結果には、奇数のビットが組み合わされたビットセットがあり、偶数のビットにはビットが設定されません。

これが発生する可能性がない場合、その証拠はありますか?

XORは、個々のビットを繰り越さない加算と同等です。キャリーなしでビットを追加すると、オーバーフローは発生しないため、int値が範囲外になることはありません。

120
schnaader

演算は新しいビットを生成せず、オペランドのビット値を結合するように定義されているため、結果がintが提供するよりも多くのビットを必要とするという意味で「大きすぎる」ことはありません。おそらくより良い質問かもしれませんが、結果はintの有効な値表現以外のものになる可能性がありますか?

符号なし整数の場合、いいえ。すべてのビットパターン、したがってすべてのビット演算の結果は、有効な値表現です。

符号付き整数の場合、負の値の実装定義の表現に依存します。遭遇する可能性のあるすべての実装は、2の補数を使用します。この場合も、すべてのビットパターンが有効です。そのため、ビット演算の結果は有効な表現になります。

ただし、この規格では、1つ以上の無効なビットパターンが存在する可能性がある他の表現も許可されています。その場合、2つの有効なオペランドを使用したビットごとの演算でそのパターンを生成し、無効な結果を生成する可能性があります。

37
Mike Seymour

(この投稿はC++ではなくCに適用されます)

無効なパディングビットを設定するため、ビット演算子はトラップ表現を引き起こすことができません。C116.2.6.2/1脚注を参照してください。

...有効な値に対する算術演算はトラップ表現を生成できません...

(「算術演算」の意味 不明 ですが、インデックスはXORの定義である6.5.11にリンクしています)。

ただし、Cでは、負のゼロが生成される可能性があります。 2の補数には負のゼロはありません。しかし、1の補数を持つシステムにいるとすると、^を介して負のゼロを生成でき、トラップ表現が発生する可能性があります。 6.2.6.2/3は、これが可能であると明示的に述べています。

実装が負のゼロをサポートする場合、それらは以下によってのみ生成されます:

—そのような値を生成するオペランドを持つ&、|、^、〜、<<、および>>演算子。

最後に、6.2.6.2/2は、INT_MAXを超える整数を表す値ビットの組み合わせを持つことができないことを意味します(とにかく確信しています)。


要約すると、2つのintsでの^の可能な結果は次のとおりです。

  • 別の有効なint値(おそらく、同じ値の他のバージョンとは異なるがトラップされないパディングビットを持つ)
  • 負のゼロ。トラップを引き起こす場合としない場合があります
26
M.M

厳密に言えば、XOR 2つの整数はできません。XOR 2つの整数サイズのビットバッグ、およびこれらのビットバッグを他の場合は整数として扱い、他の場合はallで整数として扱うこともできます。

ただし、XOR演算を実行する時点では、整数または偶数とはまったく異なるものとして扱っています。それ自体:これらはビットの2つのシーケンスであり、対応するビットが比較されます。オーバーフローの概念はそれには適用されないため、結果を次のように扱う場合整数、オーバーフローもできません。

20
The Spooniest

XORがint型に格納できないような大きな整数値を生成する可能性はありますか?

オペランドがintの場合、いいえ。

これが発生する可能性がない場合、その証拠はありますか?

まあ、それは定義からささいなことです。これは数学的に厳密な証明ではありませんが、XORの出力のビットは、オペランドの1つがその位置に1を持っている場合にのみ1になると考えることができます。オペランドに1を指定することはできません。範囲外の値1の出力ビットはありません。

11
eerorika

XOR、AND、OR、NOTおよびその他のビット演算子は、結果のビットが入力のまったく同じ位置にあるビットから結合された、ビットごとの結果を生成します。それで、nビット入力は上位ビットなしでnビットを生成します。

10
phuclv

いいえ、できません。他の回答とは異なり、私のものは数学的証明になります。

XORexclusive orまたはexclusive disjunction)のショートカットであり、次のように定義できます。

A ⊕ B = (A ∪ B)\(A ∩ B)

あなたの論文は

∃x: x ∉ A ∧ x ∉ B ∧ x ∈ (A ⊕ B)

だから最初の方程式から

x ∈ (A ∪ B)\(A ∩ B)

として表現できるもの

x ∈ (A ∪ B) ∧ x ∉ (A ∩ B)

2番目の部分は次のように表現できます。

x ∉ A ∧ x ∉ B

最初の部分は次のように表現できます。

x ∈ A ∨ x ∈ B

x ∉ A ∧ x ∉ Bという仮定と衝突するもの。したがって、すべてのAおよびBに対して論文は偽です。

Q.E.D.

10
Hauleth

GENERAL CASEでは、説明されたアルゴリズムは実際に配列内の孤独な整数を見つけることができません。本当に見つかったのは、そこに奇数回出現するすべての要素のXORです。

したがって、そこに「孤独な」要素が1つだけある場合、要素_'a'_と言い、他のすべての要素が配列内で偶数回出現すると、「必要に応じて」動作します->この孤独な要素を見つけます'a'_。

どうして?

アルゴリズムは、配列_(a ^ b ^ c ^ d ^ ...)_内のすべての要素のXORを実行します

XOR操作には、次のプロパティがあります。

1)a ^ a = 0 (non-equivalence)

2)a ^ 0 = a (neutrality of 0)

3)a ^ b = b ^ a (commutative property)

4)_(a ^ b) ^ c = a ^ (b ^ c) (associative property)_

たとえば、次の要素を持つ配列を想定しましょう:_{a, b, c, a, c, b, a, c}_

(要素_'a'_-3回、要素_'b'_-2回、要素_'c'_-3回)

次に、上記のXORプロパティに従って、アルゴリズムの結果

R = (((((((a ^ b) ^ c) ^ a) ^ c) ^ b) ^ a) ^ c)

次のように再配置できます。

R = (a ^ b) ^ (c ^ a) ^ (c ^ b) ^ (a ^ c) =

= (a ^ a) ^ (b ^ b) ^ (c ^ c) ^ (a ^ c) =

= 0 ^ 0 ^ 0 ^ (a ^ c) = (a ^ c)

すなわち、

a)...偶数回出現するすべての要素がゼロになる

b)...ODD number回はXORされる)発生するすべての要素最終結果を作成する

XORビット単位操作であるため、もちろんオーバーフローすることはありません。

7
Eric Best

仮に

int xor  = x^y;
Max value of int is x = 999999999;
Max value of Xor will come if y=0;
and Max Xor is 999999999;

限界にあります。 :)

3
Arun Tyagi

XORがint型に格納できないような大きな整数値を生成する可能性はありますか?

Data-Type3 = Data-Type1 operator Data-Type2

これが発生する可能性がない場合、その証拠はありますか?

Data-Type3整数の場合は、Data-Type1およびData-Type2加算または乗算の場合でも、サイズが大きくなります。

SIZE(Data-Type3) = MAX(SIZE(Data-Type1), SIZE(Data-Type2))

したがって、Data-Type1 = Data-Type2その後、それも戻り値の型です。

Short + Short   = Short
Short + Integer = Integer
Short + Long    = Long

Integer + Short   = Integer
Integer + Integer = Integer
Integer + Long    = Long

Long + Short   = Long
Long + Integer = Long
Long + Long    = Long

発生する可能性があるのはオーバーフローです。オーバーフローは、操作にキャリーがある場合に発生する可能性があります。 2の補数では、高次列へのキャリーが高次列からのキャリーと等しくない場合です。 続きを読む

ただし、XOR演算はオーバーフローできません。なぜなら、XOR演算はキャリーを生成しないため、XORはNOTのようなビット単位の演算です。

1
Khaled.K