【问题标题】:Shopping basket rounding购物篮四舍五入
【发布时间】:2015-12-10 16:08:45
【问题描述】:

我正在尝试找到计算篮子价格和总数的最佳方法。 所有产品价格均由带 2 个小数点的数字表示,但是,当将折扣添加到例如 50% 的篮子中时,例如价格为 37.27 美元,最终数字为 18.635 美元,具有 3 个小数位。现在我希望计算准确,但四舍五入的小数点后 3 位并不总能得出预期的结果。

场景

我的购物篮中有 5 件产品,原价如下:

  • $80.00
  • 189.62 美元
  • 37.27 美元
  • 43.75 美元
  • 105.34 美元

给我们总共$455.98

当我添加 50% 的全球折扣时 - 将上述数字加起来,这将给我$227.99。现在,如果在应用折扣后我不必获取每件商品的数字,这会很好 - 当我想将商品传递给 PayPal Express Checkout 时就是这种情况。除非 total 等于篮子中所有项目的总和,否则请求将失败。

以上各除以2(50%)后的数字为:

  • 40.00 美元
  • 94.81 美元
  • 18.635 美元
  • 21.875 美元
  • 52.67 美元

给我们的总数与我们将总数除以 2 时完全相同。 问题是我不想在我的篮子里放 3 个小数,所以将它们四舍五入,结果变成:

  • 40.00 美元
  • 94.81 美元
  • 18.64 美元
  • 21.88 美元
  • 52.67 美元

加起来是$228,当乘以 2 时,我们得到的数字与我们最初在篮子中没有应用折扣的数字不同。

解决这种情况的最佳方法是什么?

【问题讨论】:

  • 不要用四舍五入的数字计算...保留原始数字并用这些数字计算..
  • 当您在网站上只能显示 2 位小数时,这并不总是一种选择。
  • 回答更广泛的问题:要么计算第二种方式折扣后的价格,然后将其显示给客户"Total after discount: $288.00" 要么只是向贝宝发送一个带有 orderid 和相关成本的对象 - 没有具体需要详细说明每个产品
  • 我假设有一个协议来描述必须如何处理这些事情。如果您必须单独计算每个折扣,请执行此操作,然后对 dicsounted 值求和。否则,计算总和。
  • @Steve - 我最初就是这么想的,但我认为客户在 PayPals 门户网站上看到他们实际同意购买的东西可能会很好。

标签: php floating-point decimal e-commerce


【解决方案1】:

这是一个很好的问题。我的投票是对每件商品应用 50% 的折扣——使用数字格式将该数字四舍五入到小数点后 2 位——并将该数字保存为购物车订单记录的一部分,即使您没有向客户展示。然后像往常一样将这些数字相加以获得购物车产品总数。

原因:在某些时候,有人会需要一个明确的为每种产品收取的金额。并考虑回报。如果您不必纠正 0.01 的差异,它将使退货变得更加容易。

【讨论】:

  • 谢谢@cartalot - 我最终做的是通过折扣百分比运行每个产品并将每个产品的输出四舍五入到小数点后两位。之后,我从打折产品中得到了小计。
【解决方案2】:

您可以使用bcmul(),它会确保您的数字是准确的。

如果您想确保价格始终保留两位小数,您可以使用number_format()

http://php.net/manual/en/function.bcmul.php

http://php.net/manual/en/function.number-format.php

【讨论】:

  • 我使用的 number_format() 有两位小数,这就是导致实际问题的原因。我会看看 bcmul() 看看我会得到什么结果。
  • 好吧,通常你只会在应用数学之后才使用number_format,以确保它有2个小数,因为10.1(例如)不会有尾随零。
  • 我试过 bcdiv 将给定的数字除以 2 (50%),但这只是减少了小数点的第三位而没有实际四舍五入 - 所以最后我得到了结果低于原来的所以不是我所追求的功能集。我认为除了让它保留更多的小数位或在所有后续产品的价格在折扣后四舍五入后简单地求和之外,别无他法。
  • 如果您要查找的只是受控舍入,round() 有一个允许您设置模式的参数。例如,PHP_ROUND_HALF_UPphp.net/manual/en/function.round.php
  • round() 与模式标志一起使用会得到相同的结果。无论我使用什么,它总是会上升或下降$0.01
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 2012-08-04
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
相关资源
最近更新 更多