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?
Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
Split an 8-bit integer into individual bits?
You don't need to use any string manipulation. At the simplest level you can just use bitwise operators.
Let's say you've got an arbitrary 8 bit register:
register = 0b00000000
You can visualize its state using a format string.
print(f"{register:08b}")
Now let's flip the 4th bit from the right... the bitwise OR augmented assignment operator (|=) will set to 1 in the register any bit that is 1 in either the register or the number to the right of the register, so we pass in a number that had a 1 in only the bit position we want to flip. Here I use the bitwise LSHIFT operator (<<) to put a 1 in the 4th bit position from the right:
register |= 1 << 4
print(f"{register:08b}")And the 6th bit from the right.
register |= 1 << 6
print(f"{register:08b}")
Now you receive that register, how do you read out the data in each bit? Well because each bit is the next power of 2 you can just compare the register with the appropriate power of 2 using bitwise AND (the & operator)... if the result is 0 the bit was 0, if the result is the power of 2 then the bit was 1.
bits = []
for i in range(8):
bit = 8 - i
state = bool(register & 1 << bit)
bits.append((bit, state))
print(bits)Takes a bit of getting used to, and you've got to be careful with byte ordering, but the basics are pretty simple.
Once you've got that idea down you'll find enum.Flag very useful if you're in Python 3.6 or greater.
from enum import Flag, auto
class Switch4(Flag):
UNSET = 0
A = auto()
B = auto()
C = auto()
D = auto()
ALLSET = A | B | C | D
register = Switch4.UNSET
print(register, f"{register.value:04b}")
register ^= Switch4.A
print(register, f"{register.value:04b}")
register ^= Switch4.C
print(register, f"{register.value:04b}")
register ^= Switch4.A
print(register, f"{register.value:04b}")
register |= Switch4.A | Switch4.B | Switch4.D
print(register, f"{register.value:04b}")
In the above I'm using bitwise XOR in augmented assignment (^=) to flip the bit to 0 of it was 1 or 1 of it was 0.
The enum.Flag has a bit of a learning curve, but can make it easier to model the state of your interaction with individual bits in a bitflag/bitfield.
More on reddit.comYou 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