double — PHP по модулю и 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 :/
}

1

Решение

% предназначен для использования только с целыми числами. Результат его использования на числах с плавающей запятой несколько непредсказуем. И хотя результат pow(125, 1/3) может показаться целым числом, он хранится внутри как с плавающей запятой (есть интересный статья от NikiC если вы хотите узнать больше о внутренностях).

Одним из быстрых решений является использование fmod() вместо этого, который является версией с плавающей запятой.

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

Другие решения

При работе с любыми значениями типа float / double существует вероятность того, что сохранится некоторая небольшая разница во внутреннем представлении и фактическом значении. Также вы можете использовать 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
1

По вопросам рекламы [email protected]