0

So I am reading 16 bit modbus registers to get a signed 32 int, currently I am doing this:

bits = (regs[0] << 16) + regs[1]

where regs is the array of registers which in pythons are handle as an int array

and it works for most cases, however when the number is negative then i get an underflow

For example a negative number may read as the registers being:

[65535, 65385]

which then is returned as

4294967145

Is there an easy way to fix this? Should I just be checking if the value is greater than INT32 MAX / 2 and if it is then subtract INT32 MAX? Or is there a better way?

The problem seems to be I am expecting a unsigned 32 bit int, but it should be a signed 32bit int

3
  • Several libraries have fixed-width integers, e.g. ctypes and numpy. Frankly, any sufficiently-large program will probably benefit from numpy so you might as well use it. Commented Jul 11, 2021 at 21:52
  • 1
    @o11c if you're into Weird Expressions like that, you can use (x ^ 0x80000000) - 0x80000000 Commented Jul 11, 2021 at 21:58
  • Thanks, I think i got it working with your suggestions Commented Jul 11, 2021 at 22:01

1 Answer 1

2

You can use the struct module to do a series of two conversions - first from unsigned 16-bit integers to bytes, then from bytes to signed 32-bit integer.

>>> regs = [65535, 65385]
>>> import struct
>>> b = struct.pack('>2H', *regs)
>>> b
b'\xff\xff\xffi'
>>> struct.unpack('>l', b)[0]
-151
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.