Получить размер целого числа в Python

Как узнать количество байтов, которое определенное количество занимает для хранения, например. для \x00 -\xFF Я ищу, чтобы получить 1 (байт),\x100 -\xffff даст мне 2 (байты) и так далее. Любая подсказка?

Ответ 1

Вы можете использовать простую математику:

>>> from math import log
>>> def bytes_needed(n):
...     if n == 0:
...         return 1
...     return int(log(n, 256)) + 1
...
>>> bytes_needed(0x01)
1
>>> bytes_needed(0x100)
2
>>> bytes_needed(0x10000)
3

Ответ 2

Если вы не имеете дело с array.array или numpy.array - размер всегда имеет объектные издержки. И поскольку Python имеет дело с BigInts естественно, это действительно, очень сложно сказать...

>>> i = 5
>>> import sys
>>> sys.getsizeof(i)
24

Итак, на 64-битной платформе требуется 24 байта для хранения того, что может быть сохранено в 3 битах.

Однако, если вы это сделали,

>>> s = '\x05'
>>> sys.getsizeof(s)
38

Итак, нет, на самом деле, у вас есть накладные расходы на память для определения object, а не для сырого хранилища...

Если вы затем выполните:

>>> a = array.array('i', [3])
>>> a
array('i', [3])
>>> sys.getsizeof(a)
60L
>>> a = array.array('i', [3, 4, 5])
>>> sys.getsizeof(a)
68L

Затем вы получаете то, что будет называться нормальными границами байтов и т.д. и т.д. и т.д.

Если вы просто хотите, чтобы "чисто" должно было быть сохранено - минус объект, а затем от 2. (6 | 7), вы можете использовать some_int.bit_length() (в противном случае просто сбрасывать бит, как показали другие ответы), а затем работать оттуда

Ответ 3

def byte_length(i):
    return (i.bit_length() + 7) // 8

Конечно, как отмечает Джон Клементс, это не размер фактического PyIntObject, который имеет заголовок PyObject, и сохраняет значение в качестве бигмама любым способом, с которым проще всего справиться, чем с большинством компактных, и у вас должен быть хотя бы один указатель (4 или 8 байт) поверх фактического объекта и т.д.

Но это длина байта самого числа. Это почти наверняка самый эффективный ответ и, вероятно, также самый легкий для чтения.

Или ceil(i.bit_length() / 8.0) более читаемый?

Ответ 4

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

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

a = 256
i = 0

while(a > 0):
    a = a >> 8;
    i += 1;

print (i)

Программа ведет себя следующим образом:

a 0000 0001 0000 0000 в двоичном каждый цикл цикла сдвинет это налево на 8:

loop 1:
0000 0001 >> 0000 0000
0000 0001 > 0 (1 > 0)

loop 2:

0000 0000 >> 0000 0001
0000 0000 > 0 (0 > 0)

END 0 is not > 0

поэтому для хранения номера необходимо 2 байта.

Ответ 5

в командной строке python, вы можете использовать размер функции

**$ import python 
$ import ctypes
$ ctypes.sizeof(ctypes.c_int)**

Ответ 6

# Python 3

import math

nbr = 0xff                 # 255 defined in hexadecimal
nbr = "{0:b}".format(nbr)    # Transform the number into a string formated as bytes.

bit_length = len(nbr)      # Number of characters
byte_length = math.ceil( bit_length/8 ) # Get minimum number of bytes

Ответ 7

Глядя на ответы на этот вопрос, некоторые люди, кажется, всегда вырабатывают самые сложные решения для любого типа проблемы.

Мое предложение будет использовать

val // 256 + 1

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