PHP模数和pow()

时间:2018-03-10 13:33:38

标签: php double modulus pow

这可以变得健壮吗?在不同的点上,我发现5 % 2 = 0 而且我从来没有遇到过这样的“怪癖”。之前,也许是由于对精度的无知:/

$checkPrimeCubeRoots = array(125, 124);

foreach ($checkPrimeCubeRoots as $int)
{
    $cubeRoot = pow($int, 1/3); // double
    // $int = 125, gives $cubeRoot = 5
    // $int = 124, gives $cubeRoot = 4.986....

    // some code that check for prime, but let's just check if divisble by 2

    echo $cubeRoot % 2;            // 0 -> yup 5 is divisible by 2
    echo intval($cubeRoot) % 2;    // 0 -> yup

    // try round -> but gives false positive for 124
    echo round ($cubeRoot) %2;     // 1 -> nope, but in both cases :/   
}

2 个答案:

答案 0 :(得分:1)

%仅用于整数。在浮点数上使用它的结果确实有些不可预测。即使pow(125, 1/3)的结果似乎是一个整数,它也会在内部存储为一个浮点(如果你想要的话, NikiC 有一个有趣的article了解更多关于内部的信息。)

一个快速的解决方案是使用fmod()代替,这是浮点版本。

echo fmod(pow(125, 1/3), 2); # 1
echo fmod(pow(124, 1/3), 2); # 0.98663095223865

答案 1 :(得分:1)

使用任何浮点/双精度值时,可能会存储内部表示和实际值的一些细微差别。您也可以使用fmod()更好地处理浮点数...

$checkPrimeCubeRoots = array(125, 124);

foreach ($checkPrimeCubeRoots as $int)
{
    $cubeRoot = pow($int, 1/3); // double
    // $int = 125, gives $cubeRoot = 5
    // $int = 124, gives $cubeRoot = 4.986....

    // some code that check for prime, but let's just check if divisble by 2

    echo "%=".$cubeRoot % 2 .PHP_EOL;;            // 0 -> yup 5 is divisible by 2
    echo "intval=".intval($cubeRoot) % 2 .PHP_EOL;;    // 0 -> yup
    echo "fmod()=".fmod($cubeRoot,2).PHP_EOL;
    // try round -> but gives false positive for 124
    echo round ($cubeRoot) %2 .PHP_EOL;     // 1 -> nope, but in both cases :/
}

这给了......

%=0
intval=0
fmod()=1
1
%=0
intval=0
fmod()=0.98663095223865
1