Python 按位操作一元(反转)

Python 按位操作一元(反转),python,bit-manipulation,Python,Bit Manipulation,我被~操作符弄糊涂了。代码如下: a = 1 ~a #-2 b = 15 ~b #-16 ~是如何工作的 我想,~a应该是这样的: 0001 = a 1110 = ~a 为什么不呢?你完全正确。这是一个整数表示的工件 在16位中,1表示为0000 0001。相反,您将得到1111111111111110,即-2。同样,15是0000 0000 1111。相反,您将得到11111111110000,即-16 一般来说,~n=-n-1你完全正确。这是一个整数表示的工件 在16位中,1表示为

我被
~
操作符弄糊涂了。代码如下:

a = 1
~a  #-2
b = 15
~b  #-16
~
是如何工作的

我想,
~a
应该是这样的:

0001 = a
1110 = ~a 

为什么不呢?

你完全正确。这是一个整数表示的工件

在16位中,1表示为
0000 0001
。相反,您将得到
1111111111111110
,即-2。同样,15是
0000 0000 1111
。相反,您将得到
11111111110000
,即-16


一般来说,
~n=-n-1

你完全正确。这是一个整数表示的工件

在16位中,1表示为
0000 0001
。相反,您将得到
1111111111111110
,即-2。同样,15是
0000 0000 1111
。相反,您将得到
11111111110000
,即-16


通常,
~n=-n-1

将“~”运算符定义为: “x的位反转定义为-(x+1)。它仅适用于整数。”

这句话的重要部分是,这与“整数”(也称为整数)有关。您的示例表示一个4位数字

'0001' = 1 
4位数字的整数范围为'-8..0..7'。另一方面,您可以使用不包含负数的“无符号整数”,4位数字的范围为“0..15”

由于Python对整数进行操作,因此您描述的行为是预期的。整数用2的补码表示。对于4位数字,如下所示

 7 = '0111'
 0 = '0000'
-1 = '1111'
-8 = '1000'
Python使用32位表示整数,以防您有32位操作系统。您可以使用以下选项检查最大整数:

sys.maxint # (2^31)-1 for my system
如果您希望为4位数字返回一个无符号整数,则必须屏蔽

'0001' = a   # unsigned '1' / integer '1'
'1110' = ~a  # unsigned '14' / integer -2

(~a & 0xF) # returns 14
如果要获得无符号8位数字范围(0..255),只需使用:

(~a & 0xFF) # returns 254

“~”运算符定义为: “x的位反转定义为-(x+1)。它仅适用于整数。”

这句话的重要部分是,这与“整数”(也称为整数)有关。您的示例表示一个4位数字

'0001' = 1 
4位数字的整数范围为'-8..0..7'。另一方面,您可以使用不包含负数的“无符号整数”,4位数字的范围为“0..15”

由于Python对整数进行操作,因此您描述的行为是预期的。整数用2的补码表示。对于4位数字,如下所示

 7 = '0111'
 0 = '0000'
-1 = '1111'
-8 = '1000'
Python使用32位表示整数,以防您有32位操作系统。您可以使用以下选项检查最大整数:

sys.maxint # (2^31)-1 for my system
如果您希望为4位数字返回一个无符号整数,则必须屏蔽

'0001' = a   # unsigned '1' / integer '1'
'1110' = ~a  # unsigned '14' / integer -2

(~a & 0xF) # returns 14
如果要获得无符号8位数字范围(0..255),只需使用:

(~a & 0xFF) # returns 254

您还可以使用未签名的int(例如来自numpy包)来实现预期的行为

>>> import numpy as np
>>> bin( ~ np.uint8(1))
'0b11111110'

您还可以使用未签名的int(例如来自numpy包)来实现预期的行为

>>> import numpy as np
>>> bin( ~ np.uint8(1))
'0b11111110'

看起来我找到了一个更简单的解决方案,可以实现所需的功能:

uint8: x ^ 0xFF
uint16: x ^ 0xFFFF
uint32: x ^ 0xFFFFFFFF
uint64: x ^ 0xFFFFFFFFFFFFFFFF

看起来我找到了一个更简单的解决方案,可以实现所需的功能:

uint8: x ^ 0xFF
uint16: x ^ 0xFFFF
uint32: x ^ 0xFFFFFFFF
uint64: x ^ 0xFFFFFFFFFFFFFFFF

Python的一元反转运算符~x=-(x+1),这与翻转内存中的每一位相同:

乙二醇

-0b111
是内存中的
1 | 001
。您不应该将-ve二进制数表示解释为存储在内存中的内容,这与正二进制数不同

‡注意:二进制计数中的负数向后计算,因此,如果为0,则每个-ve位位置仅对构成int的整数进行计数,并且必须将-1添加到最终结果中:

# in-memory  = int  (displayed as)
1|11..111    = -1   (-0b1)
1|11..110    = -2   (-0b10)
1|11..101    = -3   (-0b11)
1|11..100    = -4   (-0b100)
# and so on...

Python的一元反转运算符~x=-(x+1),这与翻转内存中的每个位相同:

乙二醇

-0b111
是内存中的
1 | 001
。您不应该将-ve二进制数表示解释为存储在内存中的内容,这与正二进制数不同

‡注意:二进制计数中的负数向后计算,因此,如果为0,则每个-ve位位置仅对构成int的整数进行计数,并且必须将-1添加到最终结果中:

# in-memory  = int  (displayed as)
1|11..111    = -1   (-0b1)
1|11..110    = -2   (-0b10)
1|11..101    = -3   (-0b11)
1|11..100    = -4   (-0b100)
# and so on...

问题在于,应用~的结果表示的数字没有得到很好的定义,因为它取决于用于表示原始值的位数。例如:

5 = 101
~5 = 010 = 2

5 = 0101
~5 = 1010 = 10

5 = 00101
~5 = 11010 = 26
但是,在所有情况下,~5的两个补码是相同的:

two_complement(~101) = 2^3 - 2 = 6
two_complement(~0101) = 2^4 - 10 = 6
two_complement(~00101) = 2^5 - 26 = 6

并假定两个补码被用来表示负值,将5作为补码的负值,6是有意义的。 因此,更正式地说,为了达到这一结果,我们有:

  • 翻转的0和1(相当于取1的补码)
  • 取二的补码
  • 应用负号
  • 如果x是n位数字:

    ~x = - two_complement(one_complement(x)) = - two_complement(2^n - 1 - x) = - (2^n - (2^n - 1 - x)) = - (x + 1)
    

    问题在于,应用~的结果表示的数字没有得到很好的定义,因为它取决于用于表示原始值的位数。例如:

    5 = 101
    ~5 = 010 = 2
    
    5 = 0101
    ~5 = 1010 = 10
    
    5 = 00101
    ~5 = 11010 = 26
    
    但是,在所有情况下,~5的两个补码是相同的:

    two_complement(~101) = 2^3 - 2 = 6
    two_complement(~0101) = 2^4 - 10 = 6
    two_complement(~00101) = 2^5 - 26 = 6
    

    并假定两个补码被用来表示负值,将5作为补码的负值,6是有意义的。 因此,更正式地说,为了达到这一结果,我们有:

  • 翻转的0和1(相当于取1的补码)
  • 取二的补码
  • 应用负号
  • 如果x是n位数字:

    ~x = - two_complement(one_complement(x)) = - two_complement(2^n - 1 - x) = - (2^n - (2^n - 1 - x)) = - (x + 1)
    

    例如:。例如:。我如何在python 3中获得该位表示字符串?在python交互式shell中,尝试将其作为print(int('0001',2))引用:这是Janus希望我相信的相反函数。
    int('00101010',2)
    的倒数就是
    f'{42:08b}
    。格式