我有:
$value = 0.57;
$step = 0.01;
我想检查$ value / $ step是否为整数。另外,有时$ value是负数。
我得到的是:
$value/$step -> 57
is_int($value/$step) -> false
and the best one:
floor($value/$step) -> 56 (I assume that 57 is really 56.9999999(9) )
$a - $b * floor($a / $b) -> 0.0099999(9)
($value/$step)%1 -> 0 (ok, but % doesn't work if it is really a float)
fmod($value/$step) -> 0.999999999(9)
任何想法?
答案 0 :(得分:1)
其他可能性:float as string modulo: - )
function float_modulo($value, $step) {
$str_value = strval($value);
$float_part_value = substr($str_value, strpos($str_value, ".") + 1);
$str_step = strval($step);
$float_part_step = substr($str_step, strpos($str_step, ".") + 1);
return intval($float_part_value) % intval($float_part_step);
}
答案 1 :(得分:0)
我不知道它是否足够有用,但我认为你可以从舍入值中减去除法结果并将其与epsilon值进行比较,如下所示:
$value = 0.57;
$step = 0.01;
$epsilon = 0.00000001; // less decimals means lower precision
var_dump(abs(round($value/$step) - $value/$step) < $epsilon);
将其包装在一个函数中,并将其称为test_integer,或者您想要它,看看它是否适合您。
LE:添加了abs()以使其适用于负数。
答案 2 :(得分:0)
OP解决方案
public static function isZero($number, $precision = 0.0000000001)
{
$precision = abs($precision);
return -$precision < (float)$number && (float)$number < $precision;
}
public static function isEqual($number1, $number2)
{
return self::isZero($number1 - $number2);
}
public static function fmod($number1, $number2)
{
//$rest = self::sfmod($number1, $number2);
if ($number2<0)
{
$rest = $number1 - $number2 * ceil($number1/$number2);
}
else if ($number2>0)
{
$rest = $number1-$number2*floor($number1/$number2);
}
if (self::isEqual($rest, $number2)) {
return 0.0;
}
if (mb_strpos($number1, ".") === false) {
$decimals1 = 0;
} else {
$decimals1 = mb_strlen($number1) - mb_strpos($number1, ".") - 1;
}
if (mb_strpos($number2, ".") === false) {
$decimals2 = 0;
} else {
$decimals2 = mb_strlen($number2) - mb_strpos($number2, ".") - 1;
}
return (float)round($rest, max($decimals1, $decimals2));
}