删除第一位

时间:2013-11-25 18:18:17

标签: c++ python

是否有一种有效的方法可以删除C ++ / Python中数字的第一位,假设您不知道该数字的大小或数据类型有多大?

我知道在Python中我可以通过获取bin(n),将字符串截断1,然后将其重新编译为int来实现,但我很好奇是否有更“数学”的方法来执行此操作。

e.g。说数字是6,二进制是110。切第一位,它变为10或2。

6 个答案:

答案 0 :(得分:2)

有一点麻烦,一次删除一点,直到只留下最高位:

def upper_bit(x):
    while x & (x - 1):
        x &= x - 1
    return x

现在你可以将它用作面具:

def mask_off(x, mask):
    return x & ~mask

>>> mask_off(6, upper_bit(6))
2

请注意,这仅适用于正数,因为Python内联具有无限的性质。

答案 1 :(得分:1)

查看110(小数点后6位)

最重要的位是100(4位小数) // - 请注意,这总是2的幂

创建一个掩码:比MSB少一个011(3个十进制)

使用按位屏蔽最高位 - 和110 & 011 = 10(2位小数)

计算MSB(最高有效位)已经在这里和其他地方经常处理

答案 2 :(得分:1)

好吧,您可以创建一个循环,在该循环中您可以在每次迭代中将某个变量(比如x)加倍,然后检查此变量是否大于您的数字。如果是,则将其除以2并减去您的数字。例如,如果您的号码是11:

- 第一次迭代:x = 1< 11,所以继续

- 第二次迭代:x = 2< 11,所以继续

- 第三次迭代:x = 4< 11,所以继续

- 第四次迭代:x = 8< 11,所以继续

-fifth iteration:x = 16> 11,因此将x除以2:x = 8。然后从你的号码中减去8并得到答案:

11-8 = 3。

答案 3 :(得分:1)

如果您使用支持__builtin_clz的C编译器,并且您将自己限制为__builtin_clz支持的类型,则可以执行以下操作:

unsigned int chopWithBuiltin(unsigned int x) {
  //get number of leading redundant sign bits,
  //which is one less than the position of the MSB
  int msb_idx = __builtin_clz(x);
  //now make a mask that is all the bits below the MSB
  int mask = UINT_MAX >> (msb_idx+1);
  return x & mask;
}

这使用__builtin_clz,希望在汇编时快速映射到某个东西而不是循环来检测MSB。

对于负数,您可以使用__builtin_clrsb构建类似的内容,但它会变得复杂。

答案 4 :(得分:0)

在Python中,我会做其中一个:

def chop_msb(i):
    return i >> 1 & i
print chop_msb(6)
> 2
print chop_msb(12)
> 4
print chop_msb(32)
> 0

def chop_msb2(i):
    return 2**(i.bit_length()-1) ^ i

print chop_msb2(6)
> 2
print chop_msb2(12)
> 4
print chop_msb2(32)
> 0

说明:

  • 第一:

这与@ Glenn的解决方案完全相同,但它可以更有效地计算遮罩。

  • 第二

这会将i的MSB与i进行异或。通过计算2到(i - 1的位长度)来计算MSB(在这种情况下)。

XOR返回在第一个值或第二个值中设置的所有位,但不在两者中。这意味着在这种情况下基本上将MSB设置为0:

6:    110  XOR   100  =  010   = 2
12:  1100  XOR  1000  =  0100  = 4
32: 100000 XOR 100000 = 000000 = 0

答案 5 :(得分:0)

首先在n的以2为底的对数中通过log2(n)对数找到二进制数的长度

n = 6
l = int(log(n, 2)) + 1

由于您的数字为6,即二进制数110,因此请找到MSB 100(十进制为4)。

mask = 2**(l-1) #msb will always be 2^(length-1)

现在只需使用XOR运算符删除MSB

res = n^mask

一行中的代码为

n = 2**int(log(n,2)) ^ n