Не понимаю, почему (5 | -2)> 0 - Ложь, где (5 или -2)> 0 - Истина - программирование
Подтвердить что ты не робот

Не понимаю, почему (5 | -2)> 0 - Ложь, где (5 или -2)> 0 - Истина

Это довольно тривиальный вопрос, на который я так и не смог найти ответ.

Здесь проблема. У меня есть следующий массив:

vals = [-5, 2]

И я хочу проверить, больше ли val[0] или val[1] чем 0. Если либо true, то я должен вывести True.

Моей непосредственной мыслью было использовать; (vals[1] or vals[0]) > 0) но я нахожу, что (5 | -2) > 0 - False, где (5 or -2) > 0 - True

Любое разъяснение будет высоко ценится.

4b9b3361

Ответ 1

В чем разница между or и | ?

or является логическим или и | является побитовым или логическим включением или.

Логический или

Логическое или в Python возвращает первое значение, которое является истинным.

Пример:

>>> None or False or 5
5
>>> -5 or 2
-5

Побитовое или логическое включение или

Побитовый или логический включительно или представлен символом | Оператор в Python и создает число, где установлены все биты, которые установлены по крайней мере в одном из заданных номеров.

Пример:

  • 2 находится в двоичном формате 0010
  • 4 в двоичном коде 0100

Логическое или между двумя результатами в 0110 который равен 6.

>>> 2 | 4
6

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

Это число в побитовых или двух других числах по-прежнему приводит к отрицательному числу:

>>> -5 | 2
-5

Ни один из двух не решает вашу проблему

При использовании

(vals[1] or vals[0]) > 0

Кажется, работает, он не работает, когда вы переворачиваете значения:

>>> vals = [2, -5]
>>> (vals[1] or vals[0]) > 0
False

Вы должны проверить оба значения отдельно

>>> vals = [-5, 2]
>>> vals[0] > 0 or vals[1] > 0
True

Для большего ввода это может быть неудобно. Вы должны использовать любой с выражением генератора:

>>> any(x > 0 for x in vals)
True

Ответ 2

Вы хотите any функцию:

>>> any(x > 0 for x in vals)

x | y x | y вычисляет побитовое OR двух значений, в то время как x or y вычисляет первое "истинное" значение. В обоих случаях результат сравнивается с 0: (x or y) > 0 и (x | y) > 0.

Что вы хотите сравнить каждое значение до нуля (при необходимости), с

vals[0] > 0 or vals[1] > 0

Если бы у вас было три значения, вы бы написали

vals[0] > 0 or vals[1] > 0 or vals[2] > 0

any функция обобщает это для списка любого размера, без необходимости решать, сколько терминов or вместе на основе размера списка.

Ответ 3

Чтобы ответить на этот вопрос, я должен объяснить о двух дополнениях.

Двоичное представление чисел

Итак, вы знаете, как внутри целое число, подобное 5, представляется в виде двоичной строки

00000000000000000000000000000101

Как вы себе представляете отрицательное число?

Ну, вот что мы хотим сделать:

  • Сложение должно работать одинаково с отрицательными числами и положительными числами; то есть вы делаете те же шаги, чтобы добавить 4 + 9 к 4 + -9.

  • Целочисленное переполнение не должно нарушать математику; т.е. MAX_VALUE + 1 == MIN_VALUE, MIN_VALUE - 1 == MAX_VALUE

То, что мы делаем, называется "Два дополнения".

ДВА КОМПЛЕМЕНТА

Чтобы представить отрицательное число, возьмите его абсолютное значение, сдвиньте каждый бит и добавьте 1.

Так что, если положительное число 5

00000000000000000000000000000101

отрицательное число -5

11111111111111111111111111111011

По сути, это означает, что мы выбираем число 01111111111111111111111111111111 как наибольшее положительное число, и все числа после этого являются отрицательными.

ТАК ЧТО ОЗНАЧАЕТ (5 | -2)?

| является побитовым или оператором. Учитывая два числа, он берет каждый бит и/или их вместе, создавая новое число, где цифра равна 1, если цифра в этой позиции в холке или обоих из двух исходных чисел равна 1, и 0 в противном случае. Расчет выглядит так:

   5 -> 00000000000000000000000000000101
| -2 -> 11111111111111111111111111111110
----    --------------------------------
        11111111111111111111111111111111 -> -1

Итак, как вы можете видеть, 5 | -2 = -1 <0.

О чем (5 или -2)?

Оператор "или" принимает два значения, приводит их к логическим значениям и/или к ним вместе. Это важно: это не так или значения, он возвращает первое значение, которое является "правдивым" - иными словами, если вы поместите его в оператор if, он запустится.

Единственное целое число, которое не является "правдивым", равно 0. Поэтому (5 или -2) возвращает первое ненулевое целое число 5 и 2, которое равно 5> 0. Таким образом, 5 или -2 = 5> 0.

Ответ 4

| является побитовым ИЛИ, и Python использует два представления дополнения для целых чисел. Оценка 5 | -2 5 | -2 дает:

  ... 0000 0000 0000 0101 (+5)
| ... 1111 1111 1111 1110 (-2)
──────────────────────────────
= ... 1111 1111 1111 1111 (-1)

И -1 не больше нуля, поэтому (5 | -2) > 0 ложно.

or является логическим ИЛИ. В отличие от других языков, где этот оператор возвращает логическое (True/False) значение, Python определяет x or y как эквивалентное x if x else y (за исключением того, что x вычисляется только один раз). Обратите внимание, что любое ненулевое числовое значение является "правдивым" в Python, поэтому, если x ≠ 0, то x or y оценивается как x.

>>> 5 or -2
5
>>> -2 or 5
-2

То, что (5 or -2) > 0 оценивается как "Истина", было удачей, если сначала было положительное число. В другом порядке вы бы получили Ложь.

В целом (x or y) > 0 не эквивалентно (x > 0) or (y > 0), что вы и имели в виду.

Ответ 5

Когда вы делаете (5 | -2), вы делаете побитовое ИЛИ. Это сохранит бит отрицания в числах. Поэтому у вас все равно будет отрицательное число.

(5 or -2) - это логическое ИЛИ, интерпретатор Python распространит его на следующий логический оператор (больше, чем).

Ответ 6

Это две совершенно разные операции, так что это ожидаемо.

Для иллюстрации приведем небольшой журнал оболочки:

In [1]: 5 or -2
Out[1]: 5

In [2]: 5 | -2
Out[2]: -1

Оператор or возвращает первое non- нулевое (non- None, non- False и т.д.) Значение.

| оператор делает побитовый или. Проиллюстрировать:

In [3]: bin(5)
Out[3]: '0b101'

In [4]: bin(-2)
Out[4]: '-0b10'

In [5]: bin(5 | -2)
Out[5]: '-0b1'