私は配列で孤独な整数を見つけるためのアルゴリズムを研究していましたが、ここに実装があります:
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
などのデータ型で表現できない潜在的に大きな整数になります。私の質問は:
XOR
はint
型に格納できないような大きな整数値を生成する可能性さえありますか?XOR
は、ビットを結合し、以前にビットが設定されていない新しいビットを作成しないため、範囲外になることはありません。
結果 5
正しい。値のバイナリ表現とXOR
結果を見てください
10 00001010
20 00010100
30 00011110
5 00000101
20 00010100
10 00001010
30 00011110
--------------
00000101 => 5
多くのXOR
ed値の結果を計算するための簡単なヘルプは次のとおりです。結果には、奇数のビットが組み合わされたビットセットがあり、偶数のビットにはビットが設定されません。
これが発生する可能性がない場合、その証拠はありますか?
XOR
は、個々のビットを繰り越さない加算と同等です。キャリーなしでビットを追加すると、オーバーフローは発生しないため、int
値が範囲外になることはありません。
演算は新しいビットを生成せず、オペランドのビット値を結合するように定義されているため、結果がint
が提供するよりも多くのビットを必要とするという意味で「大きすぎる」ことはありません。おそらくより良い質問かもしれませんが、結果はint
の有効な値表現以外のものになる可能性がありますか?
符号なし整数の場合、いいえ。すべてのビットパターン、したがってすべてのビット演算の結果は、有効な値表現です。
符号付き整数の場合、負の値の実装定義の表現に依存します。遭遇する可能性のあるすべての実装は、2の補数を使用します。この場合も、すべてのビットパターンが有効です。そのため、ビット演算の結果は有効な表現になります。
ただし、この規格では、1つ以上の無効なビットパターンが存在する可能性がある他の表現も許可されています。その場合、2つの有効なオペランドを使用したビットごとの演算でそのパターンを生成し、無効な結果を生成する可能性があります。
(この投稿は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つのint
sでの^
の可能な結果は次のとおりです。
int
値(おそらく、同じ値の他のバージョンとは異なるがトラップされないパディングビットを持つ)厳密に言えば、XOR 2つの整数はできません。XOR 2つの整数サイズのビットバッグ、およびこれらのビットバッグを他の場合は整数として扱い、他の場合はallで整数として扱うこともできます。
ただし、XOR演算を実行する時点では、整数または偶数とはまったく異なるものとして扱っています。それ自体:これらはビットの2つのシーケンスであり、対応するビットが比較されます。オーバーフローの概念はそれには適用されないため、結果を次のように扱う場合整数、オーバーフローもできません。
XORがint型に格納できないような大きな整数値を生成する可能性はありますか?
オペランドがint
の場合、いいえ。
これが発生する可能性がない場合、その証拠はありますか?
まあ、それは定義からささいなことです。これは数学的に厳密な証明ではありませんが、XORの出力のビットは、オペランドの1つがその位置に1を持っている場合にのみ1になると考えることができます。オペランドに1を指定することはできません。範囲外の値1の出力ビットはありません。
XOR、AND、OR、NOTおよびその他のビット演算子は、結果のビットが入力のまったく同じ位置にあるビットから結合された、ビットごとの結果を生成します。それで、nビット入力は上位ビットなしでnビットを生成します。
いいえ、できません。他の回答とは異なり、私のものは数学的証明になります。
XOR
はexclusive 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.
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
はビット単位操作であるため、もちろんオーバーフローすることはありません。
仮に
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;
限界にあります。 :)
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のようなビット単位の演算です。