用纯数学有没有聪明的方法来做到这一点

时间:2014-06-27 00:22:35

标签: php algorithm math

我有这个代码点似乎可以用纯数学(也许是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

4 个答案:

答案 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)

有几种方法可以做到这一点。

  1. 将数字中最重要的一点归零,可能是这样的:

    while (x & x-1) x &= x-1;

    并在表格中查找答案。使用长度为67的表格,将你的2的力量调整为67。

  2. 二进制搜索高位。

  3. 如果您正在使用浮点数,请检查指数字段。此字段包含1023加上您的答案,除非数字是2的完美幂。您可以通过检查有效位字段是否正好为零来检测完美的电源情况。

  4. 如果您不使用浮点数,请将其转换为浮点数,并像3中一样查看指数。通过测试(x & x-1) == 0而不是查看,检查幂为2在有意义的;当x是2的幂时,这是正确的。

  5. 请注意,log(2^100)double的{​​{1}}相同,因此基于浮点自然对数的任何解决方案都将失败。

    这是4(

    )的(不一致的C ++,而不是PHP)代码
    log(nextafter(2^100, 1.0/0.0))