Subtract 256 if over 127:
unsigned = ord(character)
signed = unsigned - 256 if unsigned > 127 else unsigned
Alternatively, repack the byte with the struct module:
from struct import pack, unpack
signed = unpack('B', pack('b', unsigned))[0]
or directly from the character:
signed = unpack('B', character)[0]
Answer from Martijn Pieters on Stack OverflowSubtract 256 if over 127:
unsigned = ord(character)
signed = unsigned - 256 if unsigned > 127 else unsigned
Alternatively, repack the byte with the struct module:
from struct import pack, unpack
signed = unpack('B', pack('b', unsigned))[0]
or directly from the character:
signed = unpack('B', character)[0]
from ctypes import c_int8
value = c_int8(191).value
use ctypes with your ord() value - should be -65 in this case
ex. from string data
from ctypes import c_int8
data ='BF'
value1 = int(data, 16) # or ord(data.decode('hex'))
value2 = c_int8(value1).value
value1 is 16bit integer representation of hex 'BF' and value2 is 8bit representation
Use the struct module.
import struct
value = struct.unpack('B', data[0:1])[0]
We have to specify a range of 1 (0:1), because Python 3 converts automatically to an integer otherwise.
Note that unpack always returns a tuple, even if you're only unpacking one item.
Also, have a look at this SO question.
bytes/bytearray is a sequence of integers. If you just access an element by its index you'll have an integer:
>>> b'abc'
b'abc'
>>> _[0]
97
By their very definition, bytes and bytearrays contain integers in the range(0, 256). So they're "unsigned 8-bit integers".
ctypes - Convert a string to an 8-bit signed integer in python - Stack Overflow
A 1 byte (8 bit) value is treating what is typically an unsigned value as a signed value and creating an inaccurate number. How do I fix this?
Simulating C#'s sbyte (8 bit signed integer) casting in Python - Stack Overflow
Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
You could use ctypes:
>>> from ctypes import cast, pointer, POINTER, c_char, c_int
>>>
>>> def convert(c):
... return cast(pointer(c_char(c)), POINTER(c_int)).contents.value
...
>>> map(convert, 'test string')
[116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103]
Which (as I just found out) matches the output of ord:
>>> map(ord, 'test string')
[116, 101, 115, 116, 32, 115, 116, 114, 105, 110, 103]
Although your data type definitions list it as a char, not a char*, so I'm not sure how you'd handle that.
Your interface takes char* which are C strings. The equivalent ctypes type is c_char_p. Use:
import ctypes
lib = ctypes.WinDLL('example.dll')
VCS_OpenDevice = lib.VCS_OpenDevice
VCS_OpenDevice.argtypes = [ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p]
DeviceName ='EPOS2'
ProtocolStackName = 'MAXON SERIAL V2'
InterfaceName = 'USB'
PortName = 'USB0'
print VCS_OpenDevice(DeviceName,ProtocolStackName,InterfaceName,PortName)
Also, WinDLL is normally only needed for Windows system DLLs. If your interfaces are declared __stdcall in the C header file, WinDLL is correct; otherwise, use CDLL.
Additionally, your return code is documented as a DWORD*, which is a bit strange. Why not DWORD? If DWORD* is correct, to access the value of the DWORD pointed to by the return value, you can use:
VCS_OpenDevice.restype = POINTER(c_uint32)
retval = VCS_OpenDevice(DeviceName,ProtocolStackName,InterfaceName,PortName)
print retval.contents.value
A 1byte (8 bit) value is treating what is typically an unsigned value as a signed value and creating an inaccruate number. How do I fix this?
I am receiving an 8 bit number (outside of my control) and it is treating values like
0b11000011
would be
0xc3
but it's being interpreted as
-0x3d
I want it to be treated as 0xc3 and not 0x3d.
If you're thinking you're using the wrong language, you're right. I am. I don't have control over that. Second, I am using python 2. I know. It's EOL and doesn't receive security updates. I'm aware. I shouldn't. It's out of my control.
If you have guidance, let me know.
edit: would something like (but do let me know if there are any traps or pitfalls I'm inducing by doing this)
new_unsigned_value = c_uint8(signed_value).value
With ctypes:
from ctypes import cast, pointer, c_int32, c_byte, POINTER
cast(pointer(c_int32(arg1)), POINTER(c_byte)).contents.value
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