Подтвердить что ты не робот

Может ли 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]

Это приводит к потенциально большому целому числу, которое в этом случае не может быть представлено типом данных say int. Мои вопросы:

  • Возможно ли, что XOR будет генерировать такое большое целочисленное значение, которое не может быть сохранено в типе int?
  • Если это невозможно, это может быть доказано для этого?
4b9b3361

Ответ 1

XOR никогда не выйдет за пределы, потому что он объединяет биты и не создает новые биты, где ранее не были установлены биты.

Результат 5 правильный. Посмотрите на двоичное представление вашего значения и результат XOR

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

Легкая справка для вычисления результата многих значений XOR ed: Результат будет иметь бит, в котором нечетное число бит объединяется, а бит не установлен для четного количества бит.

Если это невозможно, это может быть доказано для этого?

XOR эквивалентно добавлению без переноса отдельных битов. Когда вы добавляете биты без переноса, переполнение не может произойти, поэтому значение int не может выйти за пределы.

Ответ 2

Результат никогда не может быть "слишком большим" в смысле его представления, требующего больше битов, чем int, поскольку операция определена для объединения значений битов своих операндов, а не для создания каких-либо новых бит. Возможно, лучшим может быть вопрос, может ли результат быть чем-то иным, чем действительное представление значения int?

Для целых чисел без знака нет. Все битовые шаблоны и, следовательно, результат всех побитовых операций, являются допустимыми представлениями.

Для целых чисел со знаком, это зависит от представления отрицательных значений, определенных реализацией. Каждая реализация, с которой вы, вероятно, столкнетесь, использует 2'-дополнение, в котором снова используется каждый бит-шаблон; так что результат любой побитовой операции будет корректным представлением.

Однако стандарт также допускает другие представления, в которых может быть один или несколько недопустимых битовых шаблонов. В этом случае возможна побитовая операция с двумя действительными операндами для создания этого шаблона и, следовательно, получение недопустимого результата.

Ответ 3

(Это сообщение относится к C, а не С++)

Побитовые операторы не могут вызвать представление ловушки из-за установки недопустимых битов заполнения, см. C11 6.2.6.2/1 сноска:

... никакая арифметическая операция над допустимыми значениями не может генерировать ловушку представление...

(Значение "арифметическая операция" неясно, но индекс ссылается на 6.5.11, который является определением XOR).

Однако в C они могут вызвать генерирование отрицательного нуля. В 2 дополнениях нет отрицательного нуля. Но скажите, что вы были в системе с 1 дополнением, тогда вы могли бы генерировать отрицательный ноль через ^, и это может вызвать представление ловушки. 6.2.6.2/3 явно говорит, что это возможно:

Если реализация поддерживает отрицательные нули, они должны быть сгенерированы только:

- операторы &, |, ^, ~, < < и → с операндами, которые создают такое значение;

Наконец, 6.2.6.2/2 подразумевает (я уверен, в любом случае), что невозможно иметь комбинацию битов значения, которая будет представлять собой целое число, превышающее INT_MAX


Подводя итог, возможные результаты ^ на двух int:

  • Еще одно допустимое значение int (возможно, с разными, но не улавливающими битами дополнения к другим версиям того же значения)
  • Отрицательный ноль, который может или не может вызвать ловушку

Ответ 4

Строго говоря, вы не можете XOR два целых числа. Вы можете XOR два целочисленных мешка с битами, и вы можете обрабатывать эти мешки с битами как целые числа в другое время. Вы можете даже рассматривать их как целые числа в любое другое время.

Но на данный момент вы выполняете операцию XOR, вы рассматриваете их как нечто совершенно отличное от целых чисел или даже чисел, как таковых: это всего лишь две последовательности бит, где соответствующие бит сравниваются. Концепция переполнения не применяется к этому, поэтому, если вы затем решите рассматривать результат как целое число, оно также не может переполняться.

Ответ 5

Возможно ли, что XOR будет генерировать такое большое целочисленное значение, которое не может быть сохранено в типе int?

Если операнды int, то нет.

Если это невозможно, это может быть доказано для этого?

Ну, это тривиально из определения. Это вряд ли является математически строгим доказательством, но вы можете подумать, что бит на выходе XOR будет равен 1, если один из операндов имеет 1 в этой позиции. Так как бит вне диапазона не может быть 1 в операндах, бит выхода со значением 1 не выходит за пределы диапазона.

Ответ 6

XOR, AND, OR и NOT производят побитовые результаты с битами в результате, объединенными из битов в точно такой же позиции на входах. Таким образом, n-битовые входы производят n-бит без какого-либо более высокого бита, поэтому как он может уйти с границ?

Ответ 7

Нет, не может. В отличие от других ответов мое было бы математическим доказательством.

XOR является ярлыком для эксклюзивной или эксклюзивной дизъюнкции () и может быть определен как:

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)

Вторая часть может быть выражена как:

x ∉ A ∧ x ∉ B

Первая часть может быть выражена как:

x ∈ A ∨ x ∈ B

Что противоречит нашему предположению, что x ∉ A ∧ x ∉ B, поэтому тезис неверен для любого набора A и B.

Q.E.D.

Ответ 8

В GENERAL CASE описанный алгоритм не может действительно найти одиночное целое число в массиве. На самом деле он находит XOR всех элементов, которые там встречаются нечетным числом.

Итак, если есть только один "одинокий" элемент, скажем, элемент 'a', а все остальные элементы имеют время EVEN в массиве, тогда он работает "по мере необходимости" → он находит этот одинокий элемент 'a'.

Почему?

Алгоритм выполняет XOR всех элементов массива (a ^ b ^ c ^ d ^ ...)

Операция 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' - дважды, элемент '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)... все элементы, которые имеют число EVEN, приводят к нулю

b)... все элементы, которые имеют время ODD, являются XOR-ed и создают окончательный результат

XOR - это бит-мудрая операция, поэтому она никогда не может переполняться, конечно.

Ответ 9

Предположим, что

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;

который находится в пределе.:)

Ответ 10

Возможно ли, что 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.