我有这个代码点似乎可以用纯数学(也许是logarigthms?)来做得更干净。你能救我一下吗?
代码发现2的第一个幂大于给定的输入。例如,如果你给它500,它返回9,因为2 ^ 9 = 512> 500.2 ^ 8 = 256,因为它小于500,所以太小了。
function getFactor($iMaxElementsPerDir)
{
$aFactors = range(128, 1);
foreach($aFactors as $i => $iFactor)
if($iMaxElementsPerDir > pow(2, $iFactor) - 1)
break;
if($i == 0)
return false;
return $aFactors[$i - 1];
}
以下是正确的
getFactor(500) = 9
getFactor(1000) = 10
getFactor(2500) = 12
getFactor(5000) = 13
答案 0 :(得分:4)
你可以通过将输入中的位移到右边并检查0来获得相同的效果。像这样。
i = 1
while((input >> i) != 0)
i++
return i
答案 1 :(得分:2)
如果您正在寻找"仅数学"解决方案(即单个表达式或公式),您可以使用log()
然后获取其结果的上限值:
$factors = ceil(log(500) / log(2)); // 9
$factors = ceil(log(5000) / log(2)); // 13
我似乎没有注意到这个函数接受了第二个参数(自PHP 4.3开始),您可以使用它来指定基数;虽然internally执行相同的操作,但确实使代码更短:
$factors = ceil(log(500, 2)); // 9
要考虑一些不准确之处,您可能需要进行一些调整:
$factors = floor(log($nr - 1, 2)) + 1;
答案 2 :(得分:2)
与千斤顶相同但更短。使用base 2的log是2 ^ x的反函数。
echo ceil(log(500, 2));
答案 3 :(得分:1)
有几种方法可以做到这一点。
将数字中最重要的一点归零,可能是这样的:
while (x & x-1) x &= x-1;
并在表格中查找答案。使用长度为67的表格,将你的2的力量调整为67。
二进制搜索高位。
如果您正在使用浮点数,请检查指数字段。此字段包含1023加上您的答案,除非数字是2的完美幂。您可以通过检查有效位字段是否正好为零来检测完美的电源情况。
如果您不使用浮点数,请将其转换为浮点数,并像3中一样查看指数。通过测试(x & x-1) == 0
而不是查看,检查幂为2在有意义的;当x
是2的幂时,这是正确的。
请注意,log(2^100)
与double
的{{1}}相同,因此基于浮点自然对数的任何解决方案都将失败。
这是4(
)的(不一致的C ++,而不是PHP)代码log(nextafter(2^100, 1.0/0.0))