如何在 php 中处理浮点数时获得一致的结果

How to get consistent result while dealing with float in php

提问人:AzDesign 提问时间:2/7/2022 最后编辑:AzDesign 更新时间:2/8/2022 访问量:54

问:

代码如下:

$nums = ['3','3','5.26','3','9.11','9.11','9.11','9.11','9.11','9.11','9.11','9.11','9.11','1.25','1.25','1.25'];
$total = 0;
$accuracy = 0.00001;
foreach($nums as $num) {
    $total += floatval($num);
}

var_dump($total);                           //float(100)
var_dump($total == 100);                    //bool(false)
var_dump(abs($total - 100));                //float(1.4210854715202E-14)
var_dump(abs($total - 100) < $accuracy);    //bool(false)

$nums = ['3','3','5.23','3','13.67','13.67','13.67','13.67','13.67','13.67','1.25','1.25','1.25'];
$total = 0;
foreach($nums as $num) {
    $total += floatval($num);
}

var_dump($total);                           //float(100)
var_dump($total == 100);                    //bool(false)
var_dump(abs($total - 100));                //float(0)
var_dump(abs($total - 100) < $accuracy);    //bool(true)

如上图所示,有 2 组不同的数字。两者的总和都是 100。但是在处理浮点数时,结果可能不一致。

这是我的用例:

考试可以有很多问题,每个问题可以有不同的分数,但只有当分数总和正好为 100 时,考试才能激活。

一个考试可以处于活动状态,另一个考试不能。而且我设置了很多数字,PHP 有 50:50 的机会将它们视为“正好 100”。使用 float 持续获得 100 总和的最佳方法是什么?

PHP 浮点

评论

2赞 Rylee 2/7/2022
四舍五入到可接受的小数位数。如果只有 2 个是相关的,则可以使用 ,如果 3 个是相关的,则依此类推。您也可以使用该函数进行类似设置:round($num * 100) / 100round($num * 1000) / 1000powround($num * pow(10,$dp)) / pow(10,$dp)
0赞 Eric Postpischil 2/7/2022
当我获取第一个代码,添加一些语句以显示值并运行它时,这不会重现。例如,对于 ,输出为 “1”,表示 true,其中 question 表示它将为 false。编辑问题以提供最小的可重现示例,包括无需更改或添加即可执行的完整代码以重现问题。echo$b = abs($total - 100) < $accuracy; echo "$b <br>";
0赞 AzDesign 2/8/2022
@EricPostpischil用var_dump编辑了代码。在我的机器中,第一组结果为 false。我不知道你是怎么回事,但事实上$total - 100 在第一盘中不是 0,这意味着它有一些剩余部分。
0赞 Eric Postpischil 2/8/2022
我将您的代码粘贴到这个在线PHP编译器的和标记中,然后单击运行,它显示输出“float(100) bool(false) float(1.4210854715202E-14) bool(true)”。<?php?>

答: 暂无答案