web-dev-qa-db-fra.com

Obtenir la taille de l'entier en Python

Comment puis-je connaître le nombre d'octets nécessaires pour stocker, par exemple, un certain nombre pour\x00 -\xFF je cherche à obtenir 1 (octet),\x100 -\xffff me donnerait 2 (octets) et ainsi de suite. Un indice?

12
cerr

Vous pouvez utiliser des mathématiques simples:

>>> 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
7
stranac

Sauf si vous traitez avec un array.array ou un numpy.array - la taille a toujours une surcharge d'objet. Et comme Python traite naturellement BigInts, il est vraiment très difficile à dire ...

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

Donc, sur une plate-forme 64 bits, il faut 24 octets pour stocker ce qui pourrait être stocké en 3 bits.

Cependant, si vous le faisiez,

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

Donc non, pas vraiment - vous avez la surcharge de mémoire liée à la définition de la variable object plutôt que du stockage brut ...

Si vous prenez alors:

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

Ensuite, vous obtenez ce que l’on appelle les limites d’octets normales, etc., etc., etc.

Si vous voulez juste ce que "purement" devrait être stocké - moins la surcharge de l'objet, à partir de 2. (6 | 7), vous pouvez utiliser some_int.bit_length() (sinon, il suffit de le décaler comme d'autres réponses l'ont montré), puis de travailler à partir de là.

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

Bien sûr, comme le souligne Jon Clements, ce n'est pas la taille de la PyIntObject réelle, qui a un en-tête PyObject, et stocke la valeur sous forme de bignum de la manière la plus facile à gérer plutôt que la plus compacte, et que vous avez d'avoir au moins un pointeur (4 ou 8 octets) au-dessus de l'objet réel, etc.

Mais c'est la longueur en octets du nombre lui-même. C'est presque certainement la réponse la plus efficace et probablement aussi la plus facile à lire. 

Ou ceil(i.bit_length() / 8.0) est-il plus lisible?

16
abarnert

En utilisant une simple opération biwise pour déplacer tous les bits utilisés de plus d'un octet à chaque fois, vous pouvez voir le nombre d'octets nécessaires pour stocker un nombre.

Il est probablement intéressant de noter que même si cette méthode est très générique, elle ne fonctionnera pas sur les nombres négatifs et ne regardera que le binaire de la variable sans prendre en compte le contenu dans lequel elle est stockée.

a = 256
i = 0

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

print (i)

Le programme se comporte comme suit:

a est 0000 0001 0000 0000 en binaire chaque cycle de la boucle le décale de 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

il faut donc 2 octets pour enregistrer le numéro.

3
Serdalis
# 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
0
The Demz

sur l'invite de commande python, vous pouvez utiliser la taille de la fonction 

**$ import python 
$ import ctypes
$ ctypes.sizeof(ctypes.c_int)**
0
RICHA AGGARWAL