stdcerr
stdcerr

Reputation: 15598

Get size in Bytes needed for an integer in Python

How can I find out the number of Bytes a certain integer number takes up to store?

E.g. for

and so on.

Any clue for hexadecimal or decimal format as the input?

Upvotes: 28

Views: 76093

Answers (6)

abarnert
abarnert

Reputation: 365697

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

Of course, as Jon Clements points out, this isn't the size of the actual PyIntObject, which has a PyObject header, and stores the value as a bignum in whatever way is easiest to deal with rather than most compact, and which you have to have at least one pointer (4 or 8 bytes) to on top of the actual object, and so on.

But this is the byte length of the number itself. It's almost certainly the most efficient answer, and probably also the easiest to read.

Or is ceil(i.bit_length() / 8.0) more readable?

Upvotes: 37

The Demz
The Demz

Reputation: 7362

# 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

Upvotes: 0

RICHA AGGARWAL
RICHA AGGARWAL

Reputation: 163

on python command prompt, you can use size of function

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

Upvotes: 3

Serdalis
Serdalis

Reputation: 10489

By using a simple biwise operation to move all the used bits over 1 byte each time you can see how many bytes are needed to store a number.

It's probably worth noting that while this method is very generic, it will not work on negative numbers and only looks at the binary of the variable without taking into account what it is stored in.

a = 256
i = 0

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

print (i)

The program behaves as follows:

a is 0000 0001 0000 0000 in binary each run of the loop will shift this to the left by 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

so there are 2 bytes needed to store the number.

Upvotes: 4

Jon Clements
Jon Clements

Reputation: 142136

Unless you're dealing with an array.array or a numpy.array - the size always has object overhead. And since Python deals with BigInts naturally, it's really, really hard to tell...

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

So on a 64bit platform it requires 24 bytes to store what could be stored in 3 bits.

However, if you did,

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

So no, not really - you've got the memory-overhead of the definition of the object rather than raw storage...

If you then take:

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

Then you get what would be called normal byte boundaries, etc.. etc... etc...

If you just want what "purely" should be stored - minus object overhead, then from 2.(6|7) you can use some_int.bit_length() (otherwise just bitshift it as other answers have shown) and then work from there

Upvotes: 30

stranac
stranac

Reputation: 28236

You can use simple math:

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

Upvotes: 16

Related Questions