views:

846

answers:

2

If lv stores a long value, and the machine is 32 bits, the following code:

iv = int(lv & 0xffffffff)

results an iv of type long, instead of the machine's int.

How can I get the (signed) int value in this case?

+4  A: 

You're working in a high-level scripting language; by nature, the native data types of the system you're running on aren't visible. You can't cast to a native signed int with code like this.

If you know that you want the value converted to a 32-bit signed integer--regardless of the platform--you can just do the conversion with the simple math:

iv = 0xDEADBEEF
if(iv & 0x80000000)
    iv = -0x100000000 + iv
Glenn Maynard
That is not accurate: all the calculations that fit into the machine's word are done in that level. For example, ~1 == -2. So I'm looking for a way to force the result into type int (which is not what int() does, apparently).
~1 == -2 in Python on *all* systems. If that's not the case on the native system, then a Python implementation must emulate it. (See http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy.) The only time the native word size can leak into Python is when the size of int is greater than 32-bits, which means you make the transtion from int to long later.
Glenn Maynard
You can't force Python to convert a long to an int when the value doesn't fit in an int; you can't write Python code as if you're in C. If you want to convert the unsigned 32-bit int value 0xFFFFFFFF to the signed two's-complement 32-bit integer represented by the same bit string, then I've given you the code. Otherwise, I'm not sure what you're trying to do.
Glenn Maynard
This is ugly and is probably not terribly efficient (though it's probably more efficient than the `struct` way)...
SamB
SamB: For the question (as I interpreted it--the OP never did the courtesy of responding), it's as clean and straightforward as this sort of conversion gets. It's much cleaner and more obvious than struct. Of course, it should still be tucked away in a function and documented.
Glenn Maynard
+1  A: 

You may use struct library to convert values like that. It's ugly, but works:

from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]
Tupteq
This works on 32-bit machines and fails on 64-bit
nailxx
This can be made portable if you use one of the order/size/alignment chars. For example, use `'=l'` and `'=L'` as the format strings.
SamB