the way I do this (and its usually to ensure a fixed width integer before sending to some hardware) is via ctypes
from ctypes import c_ushort
def hex16(self, data):
'''16bit int->hex converter'''
return '0x%004x' % (c_ushort(data).value)
#------------------------------------------------------------------------------
def int16(self, data):
'''16bit hex->int converter'''
return c_ushort(int(data,16)).value
otherwise struct can do it
from struct import pack, unpack
pack_type = {'signed':'>h','unsigned':'>H',}
pack(self.pack_type[sign_type], data)
Answer from Naib on Stack OverflowGoing through the docs I didn't find a definite answer
If I do
x = 234234 sys.getsizeof(x)
It returns 28, so that's 224 bits ?
Apparently getsizeof() returns the size of an object in bytes, is this size consistent across all int's in python though?
I know that there are long ints, and that they are converted automatically to long ints at a certain value in python, but I'm just wondering about ints for now.
In Java the size that I got was 32 bit, so 4 bytes.
Is this correct, that :
python int = 224 bits java int = 32 bits
And is this because the python int has more methods etc?
Basically what I was trying to state was that across programming languages the data type sizes were fairly conventional and that an int in C# would be the same size as an int in Python / Java. I think this might be wrong though.
Thanks!
In Python, integers have arbitrary magnitude. You need not worry about how many bits are used in memory to store the integer; integers can be arbitrarily large (or large negative).
In this case, the 224 bits you are seeing are not all used to represent the integer; a lot of that is overhead of representing a Python object (as opposed to a native value in C-like languages).
EDIT: See also: https://docs.python.org/3/library/stdtypes.html#typesnumeric
is this because the python int has more methods etc?
Almost but not quite.
Internally, all python objects contain at least a reference count used by the garbage collector and a pointer to a [statically-allocated] type object (which is essentially an array of function pointers to the methods available on objects of that type). Objects with variable size (like lists, dicts, and python 3's variable-precision ints) also contain a size value.
So that's 3 values stored in the "header" of each python object. On a 32-bit platform these 3 values will most likely take 3*32 bits, and on a 64-bit platform they will take 3*64 bits. So any variable-size python object with zero size is going to take at least 24 bytes on a 64-bit machine.
Beyond that, the value of a python long integer is actually stored in an array of 15- or 30-bit chunks (depending on your build). On my 64-bit build, you can see the size of integers increase steadily as I increase their size by increments of 30 bits.
>>> [sys.getsizeof(2**(n*30) - 1) for n in range(100)]
[24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96,
100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156,
160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216,
220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 260, 264, 268, 272, 276,
280, 284, 288, 292, 296, 300, 304, 308, 312, 316, 320, 324, 328, 332, 336,
340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380, 384, 388, 392, 396,
400, 404, 408, 412, 416, 420]
And there you have it, demystified I hope.
the way I do this (and its usually to ensure a fixed width integer before sending to some hardware) is via ctypes
from ctypes import c_ushort
def hex16(self, data):
'''16bit int->hex converter'''
return '0x%004x' % (c_ushort(data).value)
#------------------------------------------------------------------------------
def int16(self, data):
'''16bit hex->int converter'''
return c_ushort(int(data,16)).value
otherwise struct can do it
from struct import pack, unpack
pack_type = {'signed':'>h','unsigned':'>H',}
pack(self.pack_type[sign_type], data)
You can use struct.pack with the I modifier (unsigned int). This function will warn when the integer does not fit in four bytes:
>>> from struct import *
>>> pack('I', 1000)
'\xe8\x03\x00\x00'
>>> pack('I', 10000000)
'\x80\x96\x98\x00'
>>> pack('I', 1000000000000000)
sys:1: DeprecationWarning: 'I' format requires 0 <= number <= 4294967295
'\x00\x80\xc6\xa4'
You can also specify endianness.
Python 3
In Python 3, this question doesn't apply. The plain int type is unbounded.
However, you might actually be looking for information about the current interpreter's word size, which will be the same as the machine's word size in most cases. That information is still available in Python 3 as sys.maxsize, which is the maximum value representable by a signed word. Equivalently, it's the size of the largest possible list or in-memory sequence.
Generally, the maximum value representable by an unsigned word will be sys.maxsize * 2 + 1, and the number of bits in a word will be math.log2(sys.maxsize * 2 + 2). See this answer for more information.
Python 2
In Python 2, the maximum value for plain int values is available as sys.maxint:
>>> sys.maxint # on my system, 2**63-1
9223372036854775807
You can calculate the minimum value with -sys.maxint - 1 as shown in the docs.
Python seamlessly switches from plain to long integers once you exceed this value. So most of the time, you won't need to know it.
If you just need a number that's bigger than all others, you can use
float('inf')
in similar fashion, a number smaller than all others:
float('-inf')
This works in both python 2 and 3.