Python, len, и размер ints

Так, cPython (2.4) имеет некоторое интересное поведение, когда длина чего-то добирается близко к 1 <<32 (размер интервала).

r = xrange(1<<30)
assert len(r) == 1<<30

прекрасен, но:

r = xrange(1<<32)
assert len(r) == 1<<32
ValueError: xrange object size cannot be reported`__len__() should return 0 <= outcome

wowrange Alex имеет это поведение также. wowrange(1<<32).l прекрасен, но len(wowrange(1<<32)) плохо. Я предполагаю, что существует некоторое поведение с плавающей точкой (считанный как отрицательное) действие, продолжающееся здесь.

  1. Что точно происходит здесь? (это вполне прилично решено ниже!)
  2. Как я могу обойти его? Longs?

(Мое определенное приложение random.sample(xrange(1<<32),ABUNCH)) если люди хотят заняться тем вопросом непосредственно!)

5
задан Community 23 May 2017 в 12:03
поделиться

3 ответа

Cpefhon предполагает, что списки входят в память. Это распространяется на объекты, которые ведут себя как списки, такие как xrange. По сути, функция Len ожидает, что способ __ Len __ ___ len __ , чтобы вернуть что-то, что конвертируется в Size_t , что не произойдет, если количество логических элементов слишком велико Даже если эти элементы на самом деле не существуют в памяти.

11
ответ дан 18 December 2019 в 09:50
поделиться

Вы обнаружите, что

xrange(1 << 31 - 1)

- последний, который ведет себя, как вы хотите. Это связано с тем, что максимально подписанный (32-битный) целое число составляет 2 ^ 31 - 1.

1 << 32 не является положительным подписанным 32-битным целым числом (Python's int dataType), Так вот почему вы получаете эту ошибку.

В Python 2.6 я не могу даже сделать xrange (1 << 32) или xrange (1 << 31) , не получая ошибку, намного меньше лен на результате.

Редактировать Если вы хотите немного больше деталей ...

1 << 31 представляет номер 0x80000000, который в 2-х представлении дополнения является самым низким представимым отрицательным числом (-1 * 2 ^ 31) Для 32-бита int . Итак, да, из-за битового представления чисел, с которыми вы работаете, он на самом деле становится негативным.

Для 32-битного номера дополнения 0x7FFFFFFF является самым высоким представимым целым числом (2 ^ 31 - 1), прежде чем «переполнить» в отрицательные числа.

Дальше чтение , если вы заинтересованы.

Обратите внимание, что, когда вы видите что-то вроде 2147483648L в приглашении, «L» в конце означает, что теперь его представлено как «длинное целое число» (обычно 64 бита, обычно я не могу сделать какие-либо обещания на том, как Python обрабатывает это, потому что я не читал на нем).

5
ответ дан 18 December 2019 в 09:50
поделиться

1 << 32 , При обработании как подписанное целое число отрицательно.

1
ответ дан 18 December 2019 в 09:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: