如何在Python中获取long的有符号整数值?

发布于 2024-08-03 08:32:50 字数 166 浏览 6 评论 0原文

如果 lv 存储一个 long 值,并且机器是 32 位,则以下代码:

iv = int(lv & 0xffffffff)

结果是一个 long 类型的 iv,而不是机器的 int。

在这种情况下如何获得(有符号)int 值?

If lv stores a long value, and the machine is 32 bits, the following code:

iv = int(lv & 0xffffffff)

results an iv of type long, instead of the machine's int.

How can I get the (signed) int value in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

伤感在游骋 2024-08-10 08:32:50
import ctypes

number = lv & 0xFFFFFFFF

signed_number = ctypes.c_long(number).value
import ctypes

number = lv & 0xFFFFFFFF

signed_number = ctypes.c_long(number).value
风追烟花雨 2024-08-10 08:32:50

本质上,问题是将符号从 32 位扩展到……无限位数,因为 Python 具有任意大的整数。通常,符号扩展是在转换时由 CPU 指令自动完成的,因此有趣的是,这在 Python 中比在 C 语言中更难。

通过尝试,我发现了类似于 BreizhGatch 函数的功能,但这不需要条件语句。 n & 0x80000000 提取32位符号位;然后,- 保留相同的 32 位表示形式,但对其进行符号扩展;最后,扩展符号位被设置在n上。

def toSigned32(n):
    n = n & 0xffffffff
    return n | (-(n & 0x80000000))

Bit Twiddling Hacks 建议了另一种可能更通用的解决方案。 n ^ 0x80000000 翻转32位符号位;那么 - 0x80000000 将符号扩展相反的位。另一种思考方式是,最初,负数位于正数之上(用 0x80000000 分隔); ^ 交换位置;然后 - 将负数移至 0 以下。

def toSigned32(n):
    n = n & 0xffffffff
    return (n ^ 0x80000000) - 0x80000000

Essentially, the problem is to sign extend from 32 bits to... an infinite number of bits, because Python has arbitrarily large integers. Normally, sign extension is done automatically by CPU instructions when casting, so it's interesting that this is harder in Python than it would be in, say, C.

By playing around, I found something similar to BreizhGatch's function, but that doesn't require a conditional statement. n & 0x80000000 extracts the 32-bit sign bit; then, the - keeps the same 32-bit representation but sign-extends it; finally, the extended sign bits are set on n.

def toSigned32(n):
    n = n & 0xffffffff
    return n | (-(n & 0x80000000))

Bit Twiddling Hacks suggests another solution that perhaps works more generally. n ^ 0x80000000 flips the 32-bit sign bit; then - 0x80000000 will sign-extend the opposite bit. Another way to think about it is that initially, negative numbers are above positive numbers (separated by 0x80000000); the ^ swaps their positions; then the - shifts negative numbers to below 0.

def toSigned32(n):
    n = n & 0xffffffff
    return (n ^ 0x80000000) - 0x80000000
醉态萌生 2024-08-10 08:32:50

您正在使用高级脚本语言;本质上,您所运行的系统的本机数据类型是不可见的。您无法使用这样的代码将其转换为本机有符号 int。

如果您知道希望将值转换为 32 位有符号整数(无论平台如何),您只需使用简单的数学运算即可进行转换:

iv = 0xDEADBEEF
if(iv & 0x80000000):
    iv = -0x100000000 + iv

You're working in a high-level scripting language; by nature, the native data types of the system you're running on aren't visible. You can't cast to a native signed int with code like this.

If you know that you want the value converted to a 32-bit signed integer--regardless of the platform--you can just do the conversion with the simple math:

iv = 0xDEADBEEF
if(iv & 0x80000000):
    iv = -0x100000000 + iv
日记撕了你也走了 2024-08-10 08:32:50

我可以建议这个吗:

def getSignedNumber(number, bitLength):
    mask = (2 ** bitLength) - 1
    if number & (1 << (bitLength - 1)):
        return number | ~mask
    else:
        return number & mask

print iv, '->', getSignedNumber(iv, 32)

Can I suggest this:

def getSignedNumber(number, bitLength):
    mask = (2 ** bitLength) - 1
    if number & (1 << (bitLength - 1)):
        return number | ~mask
    else:
        return number & mask

print iv, '->', getSignedNumber(iv, 32)
北凤男飞 2024-08-10 08:32:50

您可以使用struct库来转换这样的值。它很丑陋,但有效:

from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]

You may use struct library to convert values like that. It's ugly, but works:

from struct import pack, unpack
signed = unpack('l', pack('L', lv & 0xffffffff))[0]
提笔书几行 2024-08-10 08:32:50

一个快速但肮脏的解决方案(在我的例子中 x 永远不会大于 32 位)。

if x > 0x7fffffff:
    x = x - 4294967296

A quick and dirty solution (x is never greater than 32-bit in my case).

if x > 0x7fffffff:
    x = x - 4294967296
荒人说梦 2024-08-10 08:32:50

如果您知道原始值中有多少位,例如来自 I2C 传感器的字节或多字节值,那么您可以执行标准 二进制补码转换:

def TwosComp8(n):
    return n - 0x100 if n & 0x80 else n

def TwosComp16(n):
    return n - 0x10000 if n & 0x8000 else n

def TwosComp32(n):
    return n - 0x100000000 if n & 0x80000000 else n

If you know how many bits are in the original value, e.g. byte or multibyte values from an I2C sensor, then you can do the standard Two's Complement conversion:

def TwosComp8(n):
    return n - 0x100 if n & 0x80 else n

def TwosComp16(n):
    return n - 0x10000 if n & 0x8000 else n

def TwosComp32(n):
    return n - 0x100000000 if n & 0x80000000 else n
音栖息无 2024-08-10 08:32:50

如果该数字的十六进制表示为 4 个字节,则可以解决该问题。

def B2T_32(x):
  num=int(x,16)
  if(num & 0x80000000): # If it has the negative sign bit. (MSB=1)
    num -= 0x80000000*2
  return num
print(B2T_32(input("enter a input as a hex value\n")))

In case the hexadecimal representation of the number is of 4 bytes, this would solve the problem.

def B2T_32(x):
  num=int(x,16)
  if(num & 0x80000000): # If it has the negative sign bit. (MSB=1)
    num -= 0x80000000*2
  return num
print(B2T_32(input("enter a input as a hex value\n")))
雨后彩虹 2024-08-10 08:32:50

任意位长度数字的最简单解决方案

为什么有符号整数的语法对人类来说如此难以理解。因为这是机器的想法。 :-)
让我们解释一下。
双向 7 位计数器

如果我们有一个初始状态为000 0000 的

,我们会得到一个用于向后计数输入的脉冲。那么下一个要数的数字将是

111 1111

人们说:

嘿,计数器我们需要知道这是一个负重载。你
应该添加一个标志让您知道这一点。

柜台补充道:

1111 1111

人们问,

我们如何计算这是-1。

计数器回答:找一个比读数大一的数,减去它,就得到结果。

   1111 1111
 -10000 0000
____________
(dec)     -1




def sigIntFromHex(a):  # a = 0x0xffe1
    if a & (1 << (a.bit_length()-1)):  # check if highest bit is 1 thru & with 0x1000
        return a - (1 << (a.bit_length()))  # 0xffe1 - 0x10000 
    else:
        return a

###and more elegant:###

def sigIntFromHex(a):
    return a - (1 << (a.bit_length())) if a & (1 << (a.bit_length()-1)) else a
        
b = 0xFFE1
print(sigIntFromHex(b))

我希望我有帮助

Simplest solution with any bit-length of number

Why is the syntax of a signed integer so difficult for the human mind to understand. Because this is the idea of machines. :-)
Let's explain.
If we have a bi-directional 7-bit counter with the initial state

000 0000

and we get a pulse for the back count input. Then the next number to count will be

111 1111

And the people said:

Hey, the counter we need to know that this is a negative reload. You
should add a sign letting you know about this.

And the counter added:

1111 1111

And people asked,

How are we going to calculate that this is -1.

The counter replied: Find a number one greater than the reading and subtract it and you get the result.

   1111 1111
 -10000 0000
____________
(dec)     -1




def sigIntFromHex(a):  # a = 0x0xffe1
    if a & (1 << (a.bit_length()-1)):  # check if highest bit is 1 thru & with 0x1000
        return a - (1 << (a.bit_length()))  # 0xffe1 - 0x10000 
    else:
        return a

###and more elegant:###

def sigIntFromHex(a):
    return a - (1 << (a.bit_length())) if a & (1 << (a.bit_length()-1)) else a
        
b = 0xFFE1
print(sigIntFromHex(b))

I hope I helped

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文