tags:

views:

72

answers:

5

In C#, I can cast things to 8bit signed ints like so:

(sbyte)arg1;

which when arg1 = 2, the cast returns 2 also. However, obviously casting 128 will return -128. More specifically casting 251 will return -5.

What's the best way to emulate this behavior?

Edit: Found a duplicate question: http://stackoverflow.com/questions/385572/need-help-typecasting-in-python

s8 = (i + 2**7) % 2**8 - 2**7      // convert to signed 8-bit
+1  A: 

I'd use the struct module of the Python standard library, which, as so often, comes in handy for turning values into bytes and viceversa:

>>> def cast_sbyte(anint):
    return struct.unpack('b', struct.pack('<i', anint)[0])[0]
... ... 
>>> cast_sbyte(251)
-5
Alex Martelli
Hmm this is slower then the method I found in my OP :S.
Dominic Bou-Samra
A: 

struct module can help you, e.g. here is a way to convert int(4 bytes) to 4 signed bytes

>>> import struct
>>> struct.pack('i',251)
'\xfb\x00\x00\x00'
>>> s=struct.pack('i',251)
>>> print struct.unpack('bbbb',s)
(-5, 0, 0, 0)
Anurag Uniyal
A: 
>>> from numpy import int8
>>> int8(251)
-5
Ignacio Vazquez-Abrams
Any ideas off the top of your head how fast this would be compared with other solutions? Never used numpy.
Dominic Bou-Samra
Loading NumPy takes a few seconds, but its routines are implemented in C and Fortran.
Ignacio Vazquez-Abrams
Hmm oddly this is slower then Alex's method, and the one I found in the OP
Dominic Bou-Samra
+2  A: 

With ctypes:

from ctypes import cast, pointer, c_int32, c_byte, POINTER
cast(pointer(c_int32(arg1)), POINTER(c_byte)).contents.value
Matthew Flaschen
A: 

Try one of the following:

>>> sbyte=lambda n:(255 & n^128)-128 
>>> # or sbyte=lambda n:(n+128 & 255)-128

>>> sbyte(251)
-5
>>> sbyte(2)
2
Nas Banov