2

何かが足りないのかもしれませんが、この単純なタスクを達成するための簡単な方法が見つかりません。「~」演算子を使用して 2 進数を否定すると、2 の補数により負の数が返されます。

>>> bin(~0b100010) # this won't return '0b011101'
'-0b100011'

従来の論理補数のように、0 を 1 に、またはその逆に切り替えたいだけの場合はどうでしょうか。

4

5 に答える 5

3
>>> bin(0b111111 ^ 0b100010)
'0b11101'
>>> 
于 2011-08-22T15:16:32.040 に答える
3

関数としてのあなたの答え:

def complement(n):
    size = len(format(n, 'b'))
    comp = n ^ ((1 << size) - 1)
    return '0b{0:0{1}b}'.format(comp, size)

>>> complement(0b100010)
'0b011101'

元のビット長を保持するようにしました。int コンストラクターは先行ゼロを気にしません。

>>> complement(0b1111111100000000)
'0b0000000011111111'

>> int(complement(0b1111111100000000), 2)
255
于 2011-08-23T05:34:37.330 に答える
1

超厄介:

>>> '0b' + ''.join('10'[int(x)] for x in format(0b100010,'b')).lstrip('0')
'0b11101'
于 2011-08-23T04:01:40.590 に答える
0

これは、私が出した数の補数を返す別の関数です。

ワンライナー:

def complement(c):
    return c ^ int('1'*len(format(c, 'b')), 2)

より数学的な方法:

def complement(c):
    n=0
    for b in format(c, 'b'): n=n<<1|int(b)^1
    return n

さらに、この最後のものを functools でワンライナー化します (そのようなバロック):

def complement(c):
    return functools.reduce( lambda x,y: x<<1|y, [ int(b)^1 for b in format(c, 'b') ])

最後に、math.log を使用して 2 進数をカウントする最初のものの無駄にオタクっぽいバリアント:

def complement(c):
    c ^ int('1' * math.floor(math.log((c|1)<<1, 2)), 2)
于 2011-08-24T11:46:30.050 に答える