You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP使用in_array()在range(0,40,0.01)中找不到30.33是什么原因

问题原因

所有采用IEEE 754标准存储浮点数的语言都存在该问题,PHP也不例外:0.01、30.33这类十进制小数无法被二进制精确表示,使用range()累加步长的过程中会产生微小的精度误差,最终生成的数组中对应的数值和你直接写的字面量30.33的实际存储值存在差异,因此无论是松散比较还是严格比较的in_array()都无法匹配到对应值。你遇到的其他值能正常找到只是巧合,本质是那些值的累加误差刚好和字面量存储值一致,并非只有30.33会出问题。

解决方案
  • 方案1:转整数处理(最推荐,性能最好)
    把所有数值放大100倍转为整数,完全规避浮点数精度问题,后续需要用到小数时再除以100即可。
// 放大100倍,步长变为1,范围变为0~4000
$range = range(0, 4000, 1);
// 目标值同样放大100倍后取整
$target = (int)round(30.33 * 100);
if(in_array($target, $range)){
    echo 'Found';
} else {
    echo 'Not Found';
}
  • 方案2:自定义精度比较遍历
    如果需要保留浮点数格式,就不要直接用in_array(),自己遍历数组通过精度阈值判断是否相等。
$range = range(0, 40, 0.01);
$target = 30.33;
$found = false;
// 可根据业务需要调整精度阈值,1e-8表示误差小于0.00000001即判定相等
$epsilon = 1e-8;
foreach($range as $val){
    if(abs($val - $target) < $epsilon){
        $found = true;
        break;
    }
}
echo $found ? 'Found' : 'Not Found';
  • 方案3:转字符串统一格式后比较
    把数组元素和目标值都转为固定保留2位小数的字符串,再进行匹配。
// 生成数组时统一转为保留2位小数的字符串
$range = array_map(fn($v) => sprintf("%.2f", $v), range(0, 40, 0.01));
$target = sprintf("%.2f", 30.33);
if(in_array($target, $range)){
    echo 'Found';
} else {
    echo 'Not Found';
}

内容的提问来源于stack exchange,提问作者Ofori Kingsford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 09:54:05