PHP round()和14位小数浮点值的舍入不正确
我和我之前的许多人一样,有着由来已久的浮点舍入问题,但我似乎找不到一个很好的解决方案。我正在MySQL中进行一些数学运算,并将结果作为浮点返回给PHP,然后使用PHP round()和14位小数浮点值的舍入不正确,php,Php,我和我之前的许多人一样,有着由来已久的浮点舍入问题,但我似乎找不到一个很好的解决方案。我正在MySQL中进行一些数学运算,并将结果作为浮点返回给PHP,然后使用round()对结果进行四舍五入。我遇到的问题是像10.504999999977这样的数字似乎出现了round(),将数字四舍五入到10.5,而不是预期的10.51 有没有一致的方法让PHP正确地对这样的数字进行四舍五入?我找到了一个快速的解决方案,但我担心从长远来看,这是行不通的: echo round(10.5049999999997
round()
对结果进行四舍五入。我遇到的问题是像10.504999999977
这样的数字似乎出现了round()
,将数字四舍五入到10.5
,而不是预期的10.51
有没有一致的方法让PHP正确地对这样的数字进行四舍五入?我找到了一个快速的解决方案,但我担心从长远来看,这是行不通的:
echo round(10.50499999999977, 2, PHP_ROUND_HALF_UP); // 10.5
echo round(round(10.50499999999977, 5, PHP_ROUND_HALF_UP), 2); // 10.51
我特别担心的是,如果我使用这个解决方案,并尝试对一个像10.5044449
这样的数字进行四舍五入,结果会出现错误(10.5 vs 10.51)
那么,有没有一种解决方案可以让我用PHP获得一致正确的四舍五入数字呢?round()
正是按照您的要求进行的:
echo round(10.50499999999977, 2, PHP_ROUND_HALF_UP); // 10.5
你要求四舍五入到小数点后两位,四舍五入到“一半”以上
此处小数点后第三位小于“一半”(0.00499999777),因此向下四舍五入,得到10.500。尾随的零将被删除,因为它们没有意义。您将看到预期的行为:
php> echo round(10.50499999999977);
11
php > echo round(10.50499999999977, 1);
10.5
php > echo round(10.50499999999977, 2);
10.5
php > echo round(10.50499999999977, 3);
10.505
php > echo round(10.50499999999977, 4);
10.505
php > echo round(10.50499999999977, 6);
10.505
php > echo round(10.50499999999977, 7);
10.505
根据文件:
PHP_ROUND_HALF_UP
将val四舍五入到小数点后的精确位置(当val为0的一半时)。将1.5转换为2,将-1.5转换为-2
…049999不是“半途而废”。它低于0.5,所以php进行了四舍五入。试图关闭dupe:其他的因素将是操作系统和32位与64位的对比。^假设必须是这个问题的现有权威答案。@Dagon这是一个类似的问题,但更多的是关于浮点数的计算。在这里,我只是取一个现有的浮点数并将其舍入(可以说仍然是数学,但不同)。即使这样,也没有解决问题的方法。类似的问题:我理解,但我假设它会像你我一样绕着它走,从最右边开始,一直把它一直向左转,直到它达到2个小数点。如果不是这样的话,我怎样才能使它以我期望的方式更为四舍五入呢?忽略实际的小数点。“真的”是你让
round()
工作的地方。由于要四舍五入到2位,因此2
位置后面的数字才是最重要的。和49。。。小于50…,所以它向下取整。@Samsquanch取整根本不起作用。曾经也许这就是你对数字进行四舍五入的方式,但这样做绝对是不正确的。我希望你不是在和钱打交道。@Sammitch很不幸,我是在和一美分(十分之一到三分之一美分)的价格打交道的钱打交道,这就是产生这些数字的原因。基本上,任何超过一便士的0%都应该四舍五入到最接近的一便士,这与数据以前所在的旧系统类似。@Samsquanch嗯,您也不应该使用浮点数来存储货币价值。有几种方法可以处理这个问题,基本上是转换成以整数形式存储的基础货币单位[例如:便士],并以合理且定义明确的方式执行各种功能。