Checking if an int fits in 32 bits?

R

Roy Smith

I'm working with marshaling data over a binary wire protocol. I'm
using struct.pack() to handle the low-level encoding of ints. One of
the things I need to do is make sure an int can be represented in 4
bytes. Is there a portable way to do that? For now, I'm doing signed
ints, but I'll certainly have to do unsigned 32-bit ints (and 64-bit
ints) at some point. Not to mention shorts and chars.

At first I thought pack() might raise an exception on a value
overflow, that but doesn't seem to be the case:
[hex(ord(c)) for c in struct.pack('!i', 999999999999999999999L)]
['0xde', '0x9f', '0xff', '0xff']

Should I be thinking more along the lines of bit masking (and worrying
about all the niggling 2-complement issues) in the Python code? Or is
there some cleaner way to do this?
 
T

Thomas Heller

Roy said:
I'm working with marshaling data over a binary wire protocol. I'm
using struct.pack() to handle the low-level encoding of ints. One of
the things I need to do is make sure an int can be represented in 4
bytes. Is there a portable way to do that? For now, I'm doing signed
ints, but I'll certainly have to do unsigned 32-bit ints (and 64-bit
ints) at some point. Not to mention shorts and chars.

At first I thought pack() might raise an exception on a value
overflow, that but doesn't seem to be the case:
[hex(ord(c)) for c in struct.pack('!i', 999999999999999999999L)]
['0xde', '0x9f', '0xff', '0xff']

Should I be thinking more along the lines of bit masking (and worrying
about all the niggling 2-complement issues) in the Python code? Or is
there some cleaner way to do this?

You could try something like this:

import ctypes
def int_fits_in_32bit(value):
return ctypes.c_int32(value) == value

and similar for signed/unsigned short/int/long. Packing and unpacking with
the struct module, however, does basically the same.

Thomas
 
R

Roy Smith

You could try something like this:

import ctypes
def int_fits_in_32bit(value):  
  return ctypes.c_int32(value) == value

Good idea! It turns out you've got to do types.c_int32(value).value()
== value, but that does indeed seem to do exactly what I want.
Thanks.
 
J

John Machin

At first I thought pack() might raise an exception on a value
overflow, that but doesn't seem to be the case:
[hex(ord(c)) for c in struct.pack('!i', 999999999999999999999L)]

['0xde', '0x9f', '0xff', '0xff']

Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit
(Intel)] on win32
import struct
[hex(ord(c)) for c in struct.pack('!i', 999999999999999999999L)]
__main__:1: DeprecationWarning: struct integer overflow masking is
deprecated
['0xde', '0x9f', '0xff', '0xff']

You must be using an older version of Python.

I'd go with Jean-Paul's suggestion of (inline no-function-call-
overhead portable no-bit-twiddling) bounds checking.

Cheers,
John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top