使用PHP in_array()查找range生成的浮点数时结果不一致问题
PHP中range(0, 1, 0.1)生成数组后in_array查找浮点数异常的解决办法
这个问题的核心是浮点数的二进制精度限制——像0.1、0.3这类十进制小数,无法用二进制浮点数精确表示。当你用range(0, 1, 0.1)生成数组时,每一步的累加都会积累微小的误差,导致数组里的元素并不是你直觉中的精确值。比如:
$arr = range(0, 1, 0.1); var_dump($arr[3]); // 输出 float(0.29999999999999993) 而非精确的0.3
当你用in_array(0.3, $arr)查找时,实际上是拿精确的0.3(同样是二进制近似值,但和数组里的近似值存在差异)去匹配,自然找不到。哪怕显式转float或关闭strict参数也没用,因为两个值的二进制存储本身就有偏差,松散比较也无法忽略这种精度问题。
解决办法
1. 用整数替代浮点数运算(推荐)
把所有数值放大为整数,彻底避开浮点数精度问题:
// 生成0到10的整数数组(对应原0.0到1.0,步长0.1) $intArr = range(0, 10, 1); $target = 0.7; // 把目标值转为对应整数 $targetInt = (int)($target * 10); if (in_array($targetInt, $intArr)) { echo 'in array'; } else { echo 'not in array'; }
2. 允许误差范围的浮点数比较
遍历数组,用极小的误差阈值判断两个浮点数是否相等(通常用1e-9作为精度阈值):
$floatArr = range(0, 1, 0.1); $target = 0.7; $found = false; foreach ($floatArr as $num) { // 比较两个数的差值是否小于极小值 if (abs($num - $target) < 1e-9) { $found = true; break; } } echo $found ? 'in array' : 'not in array';
3. 对浮点数进行四舍五入后再比较
把数组元素和目标值都保留指定小数位,消除精度误差:
$floatArr = array_map(function($num) { return round($num, 1); }, range(0, 1, 0.1)); $target = round(0.7, 1); if (in_array($target, $floatArr)) { echo 'in array'; } else { echo 'not in array'; }
内容的提问来源于stack exchange,提问作者Uriahs Victor
相关产品推荐
相关产品推荐

