0

基本的なビット演算子のみを使用して、21、81、35、123 などの任意の数値を指定して、10 進数の最後の桁が 1 であるかどうかを判断するにはどうすればよいですか?

私の目的は、シフトだけでなくxor、などのビット操作に慣れることです。and

私が直面している問題は、10 進数で終わっていなくても、一部の数値に最下位ビットが設定されていることですone。それ以外の場合、最後の桁は次のようなマスクで決定できます。

>>> '{0:08b}'.format( 5 & 1)
'00000001'
>>> '{0:08b}'.format( 500231 & 1)
'00000001'

明らかに、私は少し混乱しており、この問題を解決する方法についていくつかの指針が欲しい. サンプル コードは Python で書かれていますが、提案と考えられる回答は、自然な英語を含む任意の言語で行うことができます。

私がこれまでに試したこと:

>>> def go():
...     for i in [35,123,01,11,21,31,41,51,61,71,81,91,101]:
            endswith1(i)

def endswith1(code):
    #   ...
    #   xxxxx
    # & 00111
    # ^ 00001
    #   00000
    filter = code & 7
    isone = filter ^ 1
    a =  'and 7: {0:08b}'.format( filter)
    x =  'xor 1: {0:08b}'.format( isone )
    b =  '{0:08b}'.format( code)
    one = isone == 0
    print '%3d:%s %12s %12s %s' %( code,b,  a,x, one) 
    #return ((code & 7) ^ 1 ) == 0

>>> go()
 35:00100011 and 7: 00000011 xor 1: 00000010 False
123:01111011 and 7: 00000011 xor 1: 00000010 False
  1:00000001 and 7: 00000001 xor 1: 00000000 True
 11:00001011 and 7: 00000011 xor 1: 00000010 False
 21:00010101 and 7: 00000101 xor 1: 00000100 False
 31:00011111 and 7: 00000111 xor 1: 00000110 False
 41:00101001 and 7: 00000001 xor 1: 00000000 True
 51:00110011 and 7: 00000011 xor 1: 00000010 False
 61:00111101 and 7: 00000101 xor 1: 00000100 False
 71:01000111 and 7: 00000111 xor 1: 00000110 False
 81:01010001 and 7: 00000001 xor 1: 00000000 True
 91:01011011 and 7: 00000011 xor 1: 00000010 False
101:01100101 and 7: 00000101 xor 1: 00000100 False
4

4 に答える 4

0

この状況でビット単位の演算子を使用すると、効率が悪くなります。それらを使用して演習を行った後であれば、@DanielWeaver の回答を使用することをお勧めします。

このn % 10 == 1操作は、マシン上で単一の命令に変換される可能性があります。こことここに記載さdivている命令は、除算の残りをレジスターの上半分に配置します。ただし、@MatteoItalia が指摘するように、コンパイラは遅いため、この命令を回避します。コンパイラが行をどのように扱うかについては、以下の彼のコメントを参照してください。n % 10 == 1

代わりに、インライン アセンブリまたは @DanielWeaver の回答でこの遅い命令形式を使用できます。

@DanielWeaver が指摘するように、ビット演算子が理想的ではない理由は、生の2 進数を操作するためです。

于 2013-10-04T01:01:31.063 に答える
0

ここで解決策:モジュロ10は関係ありません

数値 617283950 = 100100110010110000000101101110 で作業します。

まず、数値を奇数ビットと偶数ビットに分割します (2 の偶数乗に対応するビットを「偶数」と呼んでいます)。

   100100110010110000000101101110
    0 1 0 1 0 0 1 0 0 0 1 1 0 1 0 even
   1 0 0 1 0 1 1 0 0 0 0 0 1 1 1  odd

次に、これらのそれぞれで、10 進数で 11 で割り切れるかどうかの標準テストのように、数字を交互に足したり引いたりします (右の足し算から始めます)。

   100100110010110000000101101110
   +0-1+0-1+0-0+1-0+0-0+1-1+0-1+0 = -2
  +1-0+0-1+0-1+1-0+0-0+0-0+1-1+1  =  1

奇数桁の合計を 2 倍にして、偶数桁の合計に追加します。

   2*1 + -2 = 0

この場合のように、結果が 5 で割り切れる場合、数値自体は 5 で割り切れます。

この数は2でも割り切れる(右端が0)ので、10でも割り切れる。

これが、コンパイラが(多くの場合)モジュロ10演算を最適化する方法です:)

于 2013-10-10T15:47:50.627 に答える
-1

少なくともこれを行う方法を考え出すことなくこれを手放すことはできませんでした。私を殺さないでください。

# Returns whether num ends with the digit ending
def endsInDigit(num, ending):
    return (int(str(i), 16) & 0xf) == ending

endsInDigit(17, 1) # False私たちの特定のユースケースでは、またはのようなことができますendsInDigit(51, 1) # True

于 2013-10-04T01:29:35.977 に答える