Try using the struct module:

import struct
# read 2 bytes from hardware as a string
s = hardware.readbytes(2)
# h means signed short
# < means "little-endian, standard size (16 bit)"
# > means "big-endian, standard size (16 bit)"
value = struct.unpack("<h", s) # hardware returns little-endian
value = struct.unpack(">h", s) # hardware returns big-endian
Answer from ASk on Stack Overflow
🌐
Readthedocs
iec104-python.readthedocs.io › latest › python › number › int16.html
Signed Integer (16-bit) — iec104-python 2.2 documentation
c104 python module · Number · Signed Integer (16-bit) View page source · class c104.Int16 · __init__(self, value: int) → None · create a fixed-length integer instance · Parameters: value (int) – the value · Raises: OverflowError – cannot convert value to fixed-length integer ·
🌐
w3reference
w3reference.com › blog › receiving-16-bit-integers-in-python
How to Read 16-bit Signed Integers from Serial Port in Python: Properly Handling LSB and MSB — w3reference.com
Using two’s complement (the standard for signed integers), the range of a 16-bit signed integer is -32768 to 32767. ... Serial ports transmit data as a stream of bytes (8 bits each).
Top answer
1 of 1
3

This result is even more wild than the first. I know my approach is wrong... but can't work out where i'm wrong.

The problem is in the conversion to bytes. Let's look at it a step at a time:

int(x, 2)

Fine; we treat the string as a base-2 representation of the integer value, and get that integer. Only problem is it's a) unsigned and b) big-endian.

hex(int(x,2))

What this does is create a string representation of the integer, in base 16, with a 0x prefix. Notably, there are two text characters per byte that we want. This is already heading is down the wrong path.

You might have thought of using hexadecimal because you've seen \xAB style escapes inside string representations. This is a completely different thing. The string '\xAB' contains one character. The string '0xAB' contains four.

From there, everything else is still nonsense. Converting to bytes with a text encoding just means that the text character 0 for example is replaced with the byte value 48 (since in UTF-8 it's encoded with a single byte with that value). For this data we get the same results with UTF-8 that we would by assuming plain ASCII (since UTF-8 is "ASCII transparent" and there are no non-ASCII characters in the text).


So how do we do it?

We want to convert the integer from the first step into the bytes used to represent it. Just as there is a .from_bytes class method allowing us to create an integer from underlying bytes, there is an instance method allowing us to get the bytes that would represent the integer.

So, we use .to_bytes, specifying the length, signedness and endianness that was assumed when we created the int from the binary string - that gives us bytes that correspond to that string. Then, we re-create the integer from those bytes, except now specifying the proper signedness and endianness. The reason that .to_bytes makes us specify a length is because the integer doesn't have a particular length - there are a minimum number of bytes required to represent it, but you could use as many more as you like. (This is especially important if you want to handle signed values, since it will do sign-extension automatically.)

Thus:

for i in input_data:
    values = [int(x,2) for x in i]
    as_bytes = [x.to_bytes(2, byteorder='big', signed=False) for x in values]
    reinterpreted = [int.from_bytes(x, byteorder='little', signed=True) for x in as_bytes]
    results_2.append(reinterpreted)

But let's improve the organization of the code a bit. I will first make a function to handle a single integer value, and then we can use comprehensions to process the list. In fact, we can use nested comprehensions for the nested list.

def as_signed_little(binary_str):
    # This time, taking advantage of positional args and default values.
    as_bytes = int(binary_str, 2).to_bytes(2, 'big')
    return int.from_bytes(as_bytes, 'little', signed=True)

# And now we can do:
results_2 = [[as_signed_little(x) for x in i] for i in input_data]
🌐
Reddit
reddit.com › r/learnprogramming › combining two 16 bit signed integer numbers to produce the 32 bit integer equivalent using python 3.
r/learnprogramming on Reddit: Combining two 16 bit signed integer numbers to produce the 32 bit integer equivalent using Python 3.
October 18, 2019 -

I have a 32 bit number A = A3A2A1A0 that has been given to me in the form of A = B1B0 where B1 = A3A2 and B0 = A1A0. B1 and B0 are each 16 bit numbers. I now want to use B1 and B0 to get A in an unsigned integer format.

I tried using the 2's complement representation of B1 and B0 but am still not clear as to how I would "add" those two binary numbers.

I also tried using the bin(integer) function in Python to get the binary representation of both B1 and B0 in a list format and then concatenated the two lists to give me A. However, that didn't seem to work if either of B1 or B0 were negative.

I'm not quite understanding how B1 is getting affected when B0 goes into the overflow, i.e crosses 32768 to give a negative number.

If anyone could give me few examples taking B1 and B0 to be positive and negative both, with the final answer A as well that would be great. Any hints and suggestions would be appreciated. Thank you.

🌐
Reddit
reddit.com › r/learnpython › declaring an unsigned integer 16 in python for bit shift operation
r/learnpython on Reddit: Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
October 29, 2023 -

SOLVED: 3 Solutions:

  1. using Numpy : np.uint16()

  2. Using CTypes : ctypes.c_uint16()

  3. Using Bitwise : & 0xFFFF


Hi, I'm trying to convert this code to Python from Go / C. It involves declaring a UInt16 variable and run a bit shift operation. However cant seem to create a variable with this specific type. Need some advise here.

Go Code:

package main

import "fmt"

func main() {

var dx uint16 = 38629

var dy uint16 = dx << 8

fmt.Println(dy) //58624 -> Correct value

}

Python Code:

dx = 38629

dy = (dx << 8)

print(dy) # 9889024 -> not the expected value

print(type(dx)) # <class 'int'>

print(type(dy)) # <class 'int'>

I cant seem to figure out a way to cast or similar function to get this into an Unsigned Int 16.\

Please help.

🌐
Python
mail.python.org › pipermail › python-list › 2003-April › 211404.html
hex -> 16bit signed int (newbie)
April 15, 2003 - (Though you should be aware that the meaning of 'i' is machine-dependent; on my machine it's 32 bits, for example. If you want 16-bit unsigned on all machines, you want '>h' or some such. See the struct module's documentation.) -- Steven Taschuk 7\ 7'Z {&~ . staschuk at telusplanet.net Y r --/hG- (__/ )_ 1^1` Previous message (by thread): hex -> 16bit signed int (newbie)
🌐
Data-apis
data-apis.org › array-api › 2022.12 › API_specification › data_types.html
Data Types — Python array API standard 2022.12 documentation
A 64-bit signed integer whose values exist on the interval [−9,223,372,036,854,775,807, +9,223,372,036,854,775,807]. An 8-bit unsigned integer whose values exist on the interval [0, +255]. A 16-bit unsigned integer whose values exist on the interval [0, +65,535].
Find elsewhere
Top answer
1 of 2
2

Let's define a conversion function:

>>> def f(x):
...    r = int(x, 16)
...    return r if r < 2**15 else r - 2**16
... 

Now, let's test the function against the values that the datahsheet provided:

>>> f('1FFE')
8190
>>> f('E002')
-8190

The usual convention for signed numbers is that a number is negative if the high bit is set and positive if it isn't. Following this convention, '0000' is zero and 'FFFF' is -1. The issue is that int assumes that a number is positive and we have to correct for that:

  • For any number equal to or less than 0x7FFF, then high bit is unset and the number is positive. Thus we return r=int(x,16) if r<2**15.

  • For any number r-int(x,16) that is equal to or greater than 0x8000, we return r - 2**16.

  • While your sensor may only produce 14-bin data, the manufacturer is following the standard convention for 16-bit integers.

Alternative

Instead of converting x to r and testing the value of r, we can directly test whether the high bit in x is set:

>>> def g(x):
...    return int(x, 16) if x[0] in '01234567' else int(x, 16) - 2**16
... 
>>> g('1FFE')
8190
>>> g('E002')
-8190

Ignoring the upper bits

Let's suppose that the manufacturer is not following standard conventions and that the upper 2-bits are unreliable. In this case, we can use modulo, %, to remove them and, after adjusting the other constants as appropriate for 14-bit integers, we have:

>>> def h(x):
...    r = int(x, 16) % 2**14
...    return r if r < 2**13 else r - 2**14
... 
>>> h('1FFE')
8190
>>> h('E002')
-8190
2 of 2
1

There is a general algorithm for sign-extending a two's-complement integer value val whose number of bits is nbits (so that the top-most of those bits is the sign bit).

That algorithm is:

  1. treat the value as a non-negative number, and if needed, mask off additional bits
  2. invert the sign bit, still treating the result as a non-negative number
  3. subtract the numeric value of the sign bit considered as a non-negative number, producing as a result, a signed number.

Expressing this algorithm in Python produces:

from __future__ import print_function

def sext(val, nbits):
    assert nbits > 0
    signbit = 1 << (nbits - 1)
    mask = (1 << nbits) - 1
    return ((val & mask) ^ signbit) - signbit

if __name__ == '__main__':
    print('sext(0xe002, 14) =', sext(0xe002, 14))
    print('sext(0x1ffe, 14) =', sext(0x1ffe, 14))

which when run shows the desired results:

sext(0xe002, 14) = -8190
sext(0x1ffe, 14) = 8190
🌐
GitHub
gist.github.com › 711360947b40e8cc404e
Convert int to 16 bits in python · GitHub
Convert int to 16 bits in python. GitHub Gist: instantly share code, notes, and snippets.
🌐
Readthedocs
mypyc.readthedocs.io › en › latest › int_operations.html
Native integer operations - mypyc 2.4.0+dev.8b3e7d8b9f63543374e53d1c389ea443dd65bc46 documentation
i16 (16-bit signed integer) u8 (8-bit unsigned integer) i64, i32, i16 and u8 are native integer types and are available in the mypy_extensions module. int corresponds to the Python int type, but uses a more efficient runtime representation (tagged pointer). Native integer types are value types.
🌐
Quora
quora.com › How-can-I-compress-a-16-bit-integer-to-an-8-bit-size-integer-in-Python
How to compress a 16-bit integer to an 8-bit size integer in Python - Quora
As Tony Flury points out, though, ... to do in Python - you would be better off trying it in C, which is well suited to working with bits at a low level. Is it worth doing? For one single number, it isn’t - you would save 8 bits, and probably use up several hundred bytes (at least) on the compression code, even using C. If you had a large number of small values it might be worth doing. ... Compressing a 16-bit signed or unsigned integer into 8 bits ...
🌐
Reddit
reddit.com › r/learnpython › converting integer to 16-bit hexadecimal in big-endain form
r/learnpython on Reddit: Converting integer to 16-bit hexadecimal in Big-endain form
March 6, 2014 -

I'm trying to take a number (such as -200) and send it to a robot. The number must be converted to big-endian and sent in two bytes. WolframAlpha does this (the result I need to send is 38ff) but I haven't found a way to do this in python.

🌐
Data-apis
data-apis.org › array-api › 2023.12 › API_specification › data_types.html
Data Types — Python array API standard 2023.12 documentation
The default integer data type should be the same across platforms, but the default may vary depending on whether Python is 32-bit or 64-bit.
🌐
Readthedocs
iec104-python.readthedocs.io › latest › python › number › uint16.html
Usigned Integer (16-bit) — iec104-python 2.2 documentation
c104 python module · Number · Usigned Integer (16-bit) View page source · class c104.UInt16 · __init__(self, value: int) → None · create a fixed-length integer instance · Parameters: value (int) – the value · Raises: ValueError – cannot convert value to fixed-length integer ·
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › python
signed int - Raspberry Pi Forums
RPi Information Screen: plugin ... 22, 2017 1:09 pm · read_registers(registeraddress, numberOfRegisters, functioncode=3)[source] Read integers from 16-bit registers in the slave....
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-convert-signed-to-unsigned-integer-in-python
How to convert signed to unsigned integer in Python ? - GeeksforGeeks
April 5, 2021 - Python provides a single int type for integers and does not have separate signed and unsigned integer data types. Unlike languages such as C and C++, Python integers are not restricted to 32 bits.