0

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

我的目标是更熟悉位操作,例如xor,and以及移位。

我面临的问题是,即使某些数字不以小数位结尾,也会设置最低有效位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

1

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

在http://fayazkadir.com/blog/?p=2439有一个 VHDL 的按位版本

它……很长。但我认为移植会给你你想要的。

于 2013-10-04T00:51:58.337 回答
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 操作:)

于 2013-10-10T15:47:50.627 回答
0

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

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

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

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

于 2013-10-04T01:01:31.063 回答
-1

如果没有找到至少某种方法来做到这一点,我就不能放手,所以我采取了作弊手段,因为你在 Python 中。请不要杀我。

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

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

于 2013-10-04T01:29:35.977 回答