7

数値の2進表現の桁を逆にする滑らかな関数を探しています。

もしfそのような機能があったら、私は持っていただろう

int(reversed(s),2) == f(int(s,2))sが1で始まる0と1の文字列である場合は常に。

今使っていますlambda x: int(''.join(reversed(bin(x)[2:])),2)

簡潔さに関してはこれで問題ありませんが、これを行うにはかなり回りくどい方法のようです。

ビット単位の演算子を使用したより良い(おそらくより速い)方法があるかどうか疑問に思いました。

4

7 に答える 7

7

どうですか

int('{0:b}'.format(n)[::-1], 2)

また

int(bin(n)[:1:-1], 2)

2番目の方法は、2つのうちの方が速いようですが、どちらも現在の方法よりもはるかに高速です。

import timeit

print timeit.timeit("int('{0:b}'.format(n)[::-1], 2)", 'n = 123456')

print timeit.timeit("int(bin(n)[:1:-1], 2)", 'n = 123456')

print timeit.timeit("int(''.join(reversed(bin(n)[2:])),2)", 'n = 123456')
1.13251614571
0.710681915283
2.23476600647
于 2013-03-02T22:34:35.773 に答える
7

あなたはこのようなシフト演算子でそれを行うことができます:

def revbits(x):
    rev = 0
    while x:
        rev <<= 1
        rev += x & 1
        x >>= 1
    return rev

ただし、これはあなたの方法よりも速いようには見えません(実際、私にとっては少し遅いです)。

于 2013-03-02T23:09:53.230 に答える
2

これが私の提案です:

In [83]: int(''.join(bin(x)[:1:-1]), 2)
Out[83]: 9987

同じ方法ですが、少し簡略化されています。

于 2013-03-02T22:33:08.767 に答える
2

私はあなたの現在の方法は完全に問題ないと主張しますが、反復可能なものを受け入れるのでlist()、あなたは呼び出しを失う可能性があります:str.join()

def binary_reverse(num):
    return int(''.join(reversed(bin(num)[2:])), 2)

また、1回だけ使用される最も単純な関数以外には使用しないようにアドバイスしlambda、インライン化することで周囲のコードをより明確にします。

これがあなたのやりたいことを説明しているので、私がこれで問題ないと感じる理由は、数値の2進表現を取り、それを逆にしてから、再び数値を取得することです。それはこのコードを非常に読みやすくします、そしてそれは優先事項であるべきです。

于 2013-03-02T22:36:25.143 に答える
1

二項演算、ビットシフト、およびその他の機能を使用して、この問題(セクション7-1:ビットとバイトの反転)に専念するHacker'sDelightの半章全体があります。これらはすべてPythonで可能であり、binary-to-string-and-reverseメソッドよりもはるかに高速である必要があります。

この本は公開されていませんが、その一部について説明しているこのブログ投稿を見つけました。ブログ投稿に示されている方法は、本からの次の引用に従います。

以下に示すように、隣接するシングルビットを交換し、次に隣接する2ビットフィールドを交換するなどして、ビット反転を非常に効率的に行うことができます。これらの5つの割り当てステートメントは、任意の順序で実行できます。

http://blog.sacaluta.com/2011/02/hackers-delight-reversing-bits.html

于 2013-03-02T22:43:01.703 に答える
1
>>> def bit_rev(n):
...     return int(bin(n)[:1:-1], 2)
...
>>> bit_rev(2)
1
>>>bit_rev(10)
5
于 2013-05-30T03:41:44.073 に答える
0

特定のビット数に基づいてバイナリ値を逆にしたい場合、つまり1 = 2b'00000001の場合はどうなりますか?この場合、逆の値はそれぞれ2b'10000000または128(dec)0x80(hex)になります。

def binary_reverse(num, bit_length):
    # Convert to binary and pad with 0s on the left
    bin_val = bin(num)[2:].zfill(bit_length)
    return int(''.join(reversed(bin_val)), 2)
    # Or, alternatively:
    # return int(bin_val[::-1], 2)
于 2021-09-07T23:56:44.300 に答える