使用按位运算符确定数字是否以“1”结尾

时间:2013-10-04 00:30:00

标签: bitwise-operators

如果仅使用基本位运算符,给定任意数字(如21,81,35,123),如何确定十进制数的最后一位是否为1?

我的目标是让xorand等位操作变得更加舒适。

我面临的问题是,即使一些数字不以十进制数字one结尾,也会设置最低有效位,否则最后一位数字可以用这样的掩码确定:< / p>

>>> '{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 个答案:

答案 0 :(得分:1)

我认为问题在于您尝试对十六进制值执行十进制运算。如果将十六进制数转换为BCD(二进制编码的十进制数),那么您将可以屏蔽0x0001并查看最后一位数是否为1。

http://fayazkadir.com/blog/?p=2439

的VHDL有一个按位版本

太长了......但我认为移植会给你你想要的东西。

答案 1 :(得分:0)

在这种情况下使用按位运算符效率低下。如果您正在练习使用它们,那么我建议使用@ DanielWeaver的答案。

n % 10 == 1操作可能会转换为您计算机上的单个指令。记录hereherediv指令会将除法的其余部分放在寄存器的上半部分。但是,正如@MatteoItalia指出的那样,编译器会避免使用此指令,因为它很慢。请参阅下面的评论,了解编译器如何处理n % 10 == 1行。

您可以在内联汇编或@ DanielWeaver的答案中使用这种较慢的指令形式。

正如@DanielWeaver指出的那样,按位运算符不理想的原因是因为它们在原始二进制数字上运行。

答案 2 :(得分: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

现在,在每个中,交替地加上和减去数字,如 十进制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*1 + -2 = 0

如果结果可以被5整除,就像在这种情况下,数字本身就是 可被5整除。

因为这个数字也可以被2整除(最右边的数字是 0),它可被10整除。

这就是你的编译器如何优化(在许多情况下)模10操作:)

答案 3 :(得分:-1)

我不能在没有弄清楚一些方式的情况下这样做,所以我使用作弊,因为你是在Python中。请不要杀了我。

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

在我们的特定用例中,您可以执行endsInDigit(17, 1) # FalseendsInDigit(51, 1) # True之类的操作。