四舍五入到最近的分数(半数、四分之一等)

46

我需要创建以下函数,但是我没想到在PHP中不使用复杂的数学运算就能实现。

  • 将数值始终四舍五入到最近的小数点(1.81 = 1.90, 1.89 = 1.90, 1.85 = 1.90)
  • 将数值始终向下取整到最近的小数点(1.81 = 1.80, 1.89 = 1.80, 1.85 = 1.80)
  • 将数值始终四舍五入到最近的 x.25 / x.50 / x.75 / x.00(1.81 = 2,1.32 = 1.50)
  • 将数值始终向下取整到最近的 x.25 / x.50 / x.75 / x.00(1.81 = 1.75,1.32 = 1.25)
  • 将数值始终四舍五入到最近的 x.50 / 1(1.23 = 1.50,1.83 = 2)
  • 将数值始终向下取整到最近的 x.50 / 1(1.23 = 1,1.83 = 1.50)

我已经在谷歌上搜索了两个小时,唯一出现的结果是Excel论坛。是否有可能用一些简单的PHP代码来实现呢?


在 PHP.net 中查找 roundceil 等函数。 - fedorqui
我知道可以使用 round 和 ceil 函数,但是我不知道如何创建这些函数。 - user1649331
2
两个小时的谷歌搜索时间可以编写出一些可能比较复杂但是可用的算法。 - Catfish
2
这感觉像是作业。 - Catfish
@Wiseguy 你说得对。 - user1649331
@Catfish,实际上我需要这个功能用于网店中产品价格的四舍五入。 - user1649331
4个回答

132

如果你想要找到四分之一的数(.00, .25, .50, .75),先将你的数字乘以4,根据需要四舍五入到最近的整数(向下取整使用floor,向上取整使用ceil),然后再除以4。

1.32,向下取最近的四分之一:

1.32 * 4 = 5.28
floor(5.28) = 5.00
5.00 / 4 = 1.25

同样的方法适用于其他任何分数,比如三分之一或八分之一 (.0, .125, .25, .375, .5, .625, .75, .875)。例如:

1.77,向上取最近的八分之一:

1.77 * 8 = 14.16
ceil(14.16) = 15.00
15.00 / 8 = 1.875


只是为了好玩,你可以编写这样一个函数:

function floorToFraction($number, $denominator = 1)
{
    $x = $number * $denominator;
    $x = floor($x);
    $x = $x / $denominator;
    return $x;
}

echo floorToFraction(1.82);      // 1
echo floorToFraction(1.82, 2);   // 1.5
echo floorToFraction(1.82, 3);   // 1.6666666666667
echo floorToFraction(1.82, 4);   // 1.75
echo floorToFraction(1.82, 9);   // 1.7777777777778
echo floorToFraction(1.82, 25);  // 1.8

你们是我的英雄。谢谢。(我不知道现在我要接受哪一个作为答案)。 - user1649331
我会选择实际包含解决方案代码的答案,而不仅仅是指向其他地方的链接。或者你可以接受最先发布的答案。 - Barmar
我希望我能为你这个发言献上数百个赞! - Horst
1
对于现在正在查看此内容的任何人:只需使用PHP的round函数 - James Spence
1
@James 单独使用 round() 无法解决 OP 的问题。 - aequalsb

5
请注意,答案并不是完全可靠的。由于我们在处理浮点数,所以不能保证当您将四舍五入的数字除以分母时会返回一个整齐的圆整数。它可能返回1.499999999999而不是1.5。这是浮点数的本质。
在从函数返回数字之前,需要进行另一轮四舍五入。
以防万一有人像我一样从谷歌上来到这里 :)

1
能否添加一个例子? - Simon
4
@Simon round(round(2.24 * 4) / 4, 2):内部的round函数使其接近最近的整数。除法可能会产生奇怪的小数,所以外部的round函数将其舍入到2位小数。 - okdewit
1
@Fx32,你的小片段非常好用——也许你应该提醒用户根据需要更改位置(例如:round(round(2.24 * 8) / 8, 3)),以获得正确的结果,如0.125、0.875,以将其转换为最接近的1/8分数英寸。 - aequalsb

4
根据Excel中的mround()函数:
function MRound($num,$parts) {
    $res = $num * $parts;
    $res = round($res);
    return $res /$parts;
}
echo MRound(-1.38,4);//gives -1.5
echo MRound(-1.37,4);//gives -1.25
echo MRound(1.38,4);//gives 1.5
echo MRound(1.37,4);//gives 1.25

2

你们是我的英雄。谢谢。(我不知道现在我要接受哪一个作为答案)。 - user1649331

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接