[英]How to convert signed to unsigned integer in python
Let's say I have this number i = -6884376
.假设我有这个数字
i = -6884376
。 How do I refer to it as to an unsigned variable?我如何将它称为无符号变量? Something like
(unsigned long)i
in C.像 C 中的
(unsigned long)i
类的东西。
Assuming :假设:
(unsigned long)
you mean unsigned 32-bit integer,(unsigned long)
表示无符号 32 位整数, then you just need to add 2**32 (or 1 << 32)
to the negative value.那么您只需要将
2**32 (or 1 << 32)
到负值。
For example, apply this to -1:例如,将其应用于 -1:
>>> -1
-1
>>> _ + 2**32
4294967295L
>>> bin(_)
'0b11111111111111111111111111111111'
Assumption #1 means you want -1 to be viewed as a solid string of 1 bits, and assumption #2 means you want 32 of them.假设 #1 意味着您希望 -1 被视为 1 位的实心字符串,假设 #2 意味着您想要其中的 32 个。
Nobody but you can say what your hidden assumptions are, though.但是,除了您之外,没有人可以说出您隐藏的假设是什么。 If, for example, you have 1's-complement representations in mind, then you need to apply the
~
prefix operator instead.例如,如果您有 1 的补码表示,那么您需要应用
~
前缀运算符。 Python integers work hard to give the illusion of using an infinitely wide 2's complement representation (like regular 2's complement, but with an infinite number of "sign bits"). Python 整数努力给人一种使用无限宽 2 的补码表示的错觉(就像常规 2 的补码,但具有无限数量的“符号位”)。
And to duplicate what the platform C compiler does, you can use the ctypes
module:要复制平台 C 编译器的功能,您可以使用
ctypes
模块:
>>> import ctypes
>>> ctypes.c_ulong(-1) # stuff Python's -1 into a C unsigned long
c_ulong(4294967295L)
>>> _.value
4294967295L
C's unsigned long
happens to be 4 bytes on the box that ran this sample.在运行此示例的机器上,C 的
unsigned long
恰好是 4 个字节。
To get the value equivalent to your C cast, just bitwise and with the appropriate mask.要获得与 C 类型转换等效的值,只需按位并使用适当的掩码即可。 eg if
unsigned long
is 32 bit:例如,如果
unsigned long
是 32 位:
>>> i = -6884376
>>> i & 0xffffffff
4288082920
or if it is 64 bit:或者如果是 64 位:
>>> i & 0xffffffffffffffff
18446744073702667240
Do be aware though that although that gives you the value you would have in C, it is still a signed value, so any subsequent calculations may give a negative result and you'll have to continue to apply the mask to simulate a 32 or 64 bit calculation.请注意,虽然这为您提供了 C 中的值,但它仍然是一个带符号的值,因此任何后续计算都可能给出负结果,您必须继续应用掩码来模拟 32 或 64位计算。
This works because although Python looks like it stores all numbers as sign and magnitude, the bitwise operations are defined as working on two's complement values.这是有效的,因为尽管 Python 看起来像是将所有数字存储为符号和大小,但按位运算被定义为处理二进制补码值。 C stores integers in twos complement but with a fixed number of bits.
C 以二进制补码形式存储整数,但位数固定。 Python bitwise operators act on twos complement values but as though they had an infinite number of bits: for positive numbers they extend leftwards to infinity with zeros, but negative numbers extend left with ones.
Python 按位运算符作用于二进制补码值,但就好像它们有无限数量的位:对于正数,它们向左扩展到无穷大,带零,但负数向左扩展,带 1。 The
&
operator will change that leftward string of ones into zeros and leave you with just the bits that would have fit into the C value. &
运算符会将向左的 1 字符串更改为零,并只留下适合 C 值的位。
Displaying the values in hex may make this clearer (and I rewrote to string of f's as an expression to show we are interested in either 32 or 64 bits):以十六进制显示值可能会使这更清楚(我重写了 f 的字符串作为表达式,以表明我们对 32 位或 64 位感兴趣):
>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'
For a 32 bit value in C, positive numbers go up to 2147483647 (0x7fffffff), and negative numbers have the top bit set going from -1 (0xffffffff) down to -2147483648 (0x80000000).对于 C 中的 32 位值,正数最高可达 2147483647 (0x7fffffff),负数的最高位设置为从 -1 (0xffffffff) 到 -2147483648 (0x80000000)。 For values that fit entirely in the mask, we can reverse the process in Python by using a smaller mask to remove the sign bit and then subtracting the sign bit:
对于完全适合掩码的值,我们可以通过使用较小的掩码去除符号位然后减去符号位来反转 Python 中的过程:
>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376
Or for the 64 bit version:或者对于 64 位版本:
>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376
This inverse process will leave the value unchanged if the sign bit is 0, but obviously it isn't a true inverse because if you started with a value that wouldn't fit within the mask size then those bits are gone.如果符号位为 0,这个逆过程将使值保持不变,但显然它不是真正的逆,因为如果您从一个不适合掩码大小的值开始,那么这些位就消失了。
Python doesn't have builtin unsigned types. Python 没有内置的无符号类型。 You can use mathematical operations to compute a new int representing the value you would get in C, but there is no "unsigned value" of a Python int.
您可以使用数学运算来计算一个新的int,该 int 表示您将在 C 中获得的值,但 Python int 没有“无符号值”。 The Python int is an abstraction of an integer value, not a direct access to a fixed-byte-size integer.
Python int 是整数值的抽象,而不是对固定字节大小的整数的直接访问。
You could use the struct
Python built-in library:您可以使用
struct
Python 内置库:
Encode:编码:
import struct
i = -6884376
print('{0:b}'.format(i))
packed = struct.pack('>l', i) # Packing a long number.
unpacked = struct.unpack('>L', packed)[0] # Unpacking a packed long number to unsigned long
print(unpacked)
print('{0:b}'.format(unpacked))
Out:出去:
-11010010000110000011000
4288082920
11111111100101101111001111101000
Decode:解码:
dec_pack = struct.pack('>L', unpacked) # Packing an unsigned long number.
dec_unpack = struct.unpack('>l', dec_pack)[0] # Unpacking a packed unsigned long number to long (revert action).
print(dec_unpack)
Out:出去:
-6884376
[ NOTE ]: [注意]:
>
is BigEndian operation. >
是 BigEndian 操作。l
is long. l
很长L
is unsigned long. L
是无符号长整型。amd64
architecture int
and long
are 32bit, So you could use i
and I
instead of l
and L
respectively.amd64
架构中int
和long
是 32 位,所以你可以分别使用i
和I
而不是l
和L
Since version 3.2 :从 3.2 版开始:
def toSigned(n, byte_count):
return int.from_bytes(n.to_bytes(byte_count, 'little'), 'little', signed=True)
output :输出:
In [8]: toSigned(5, 1)
Out[8]: 5
In [9]: toSigned(0xff, 1)
Out[9]: -1
just use abs for converting unsigned to signed in python只需使用 abs 将未签名转换为已签名的 python
a=-12
b=abs(a)
print(b)
Output: 12输出:12
python does not have any builtin to convert int to unsigned int.Instead it is having long for longer range. python没有任何内置来将int转换为unsigned int.Instead它有更长的范围。
>>> val = 9223372036854775807 (maximum value of int 64)
>>> type(val)
<type 'int'>
>>> val += 1
>>> type(val)
<type 'long'>
By increasing the value of val by 1, I exceed the limit of a signed 64 bit integer and the value is converted to a long. 通过将val的值增加1,我超过了有符号64位整数的限制,并将该值转换为long。 If Python had used or converted to an unsigned integer, val would still have been an int.
如果Python使用或转换为无符号整数,则val仍然是int。 Or, not long.
或者,不久。
Signed integers are represented by a bit, usually the most significant bit, being set to 0 for positive numbers or 1 for negative numbers. 有符号整数由一个位表示,通常是最高位,对于正数设置为0,对于负数设置为1。 What val & 0xff does is actually val & 0x000000ff (on a 32 bit machine).
val和0xff实际上是val和0x000000ff(在32位机器上)。 In other words, the signed bit is set to 0 and an unsigned value is emulated.
换句话说,有符号位设置为0,并且模拟无符号值。
An example: 一个例子:
>>> val = -1
>>> val & 0xff
255
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.