【问题标题】:Explanation for computing the nearest power of two greater than the argument using bit twiddling使用位旋转计算大于参数的 2 的最接近幂的说明
【发布时间】:2017-09-17 21:00:52
【问题描述】:

这是一个众所周知的函数,用于计算正参数的下一个最接近的 2 次幂。但是,我没有太多经验来探索它背后的逻辑/理论。您能解释一下为什么以及如何工作吗?特别是,选择 1,2,4,8,16 进行移位,如果参数的范围更大,那么将使用什么,例如,long?为什么是逻辑移位而不是算术移位,最后,ORing 移位 arg 完成了什么?

static int lowestPowerOfTwoGreaterThan(int arg) {
    arg |= (arg >>>  1);
    arg |= (arg >>>  2);
    arg |= (arg >>>  4);
    arg |= (arg >>>  8);
    arg |= (arg >>> 16);
    return ++arg;
}

【问题讨论】:

  • 您可以选择一些小的随机数字。用二进制写...自己算算...
  • 谢谢,我做到了,但看不出这种概括的模式。顺便说一句,我希望你没有改变标题。这不是要求一种计算方法,而是要求该函数如何工作。这里也没有掩蔽。
  • 欢迎edit你的问题来纠正我犯的任何错误

标签: java bit-manipulation


【解决方案1】:

如果您跟踪值的变化,这真的很简单。 2 的幂只有一个设置位,例如 1001000000010000000000,这意味着 2 的幂减一是一序列,例如10000 - 1 = 1111。因此,该函数所做的是将任何数字更改为一系列 1(不移动其最高 1 位),然后添加一个,例如它将10000001000111001 (66105) 更改为11111111111111111 (131071) 并添加一个以使100000000000000000 (131072)。

首先,它自己将值向右移动 1 位进行 OR 运算。这具有延长值中1 的所有运行的效果。

   10000001000111001
OR 01000000100011100
   =================
   11000001100111101

您现在注意到,每次运行的零之前至少有两个 1,因此我们可以通过移动两位而不是一位来加快处理速度,而不是再次移位一位。

   11000001100111101
OR 00110000011001111
   =================
   11110001111111111

现在,每次运行的 0 前面至少有四个 1,所以这次我们移动 4,然后再次 OR 值。

   11110001111111111
OR 00001111000111111
   =================
   11111111111111111

重复这个逻辑,下一个移位距离将是 8,然后是 16(对于 32 位值在此停止),然后是 32(对于 64 位值在此停止)。对于此示例,由于结果已经是一个序列,因此对于进一步的移位,结果保持不变。

此方法将任何二进制数更改为一序列。如前所述,将其加 1 会产生下一个最大的 2 次幂。

【讨论】:

  • 您的意思是“......这意味着 2 的幂,减一,是 ~~zeros~~ 的序列......”?
猜你喜欢
  • 2019-11-07
  • 2014-02-21
  • 2015-01-13
  • 2011-05-05
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多