Можно ли сделать это надежным? в разные моменты я нахожу, что 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 :/
}
%
предназначен для использования только с целыми числами. Результат его использования на числах с плавающей запятой несколько непредсказуем. И хотя результат pow(125, 1/3)
может показаться целым числом, он хранится внутри как с плавающей запятой (есть интересный статья от NikiC если вы хотите узнать больше о внутренностях).
Одним из быстрых решений является использование fmod()
вместо этого, который является версией с плавающей запятой.
echo fmod(pow(125, 1/3), 2); # 1
echo fmod(pow(124, 1/3), 2); # 0.98663095223865
При работе с любыми значениями типа 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