【问题标题】:PHP bcmath needed for whole cent values?整分值需要PHP bcmath?
【发布时间】:2016-09-13 20:59:03
【问题描述】:

在 PHP 中,我正在编写一个应用程序,该应用程序需要精确到货币小数点右侧的 2 位数字(例如:我关心 1.23 === 1.23,但没有更多的右侧数字)。

我知道浮点数通常被认为是不好的做法,因为基于从小数点右侧以 2 为基数转换为以 10 为基数的性质,它们的值不精确。但是,在我对处理货币值的最佳实践的研究中,我看到了一些论点,如果您需要大于整数值的精度,浮点数就不好。我显然不需要比整分值更高的精度。

那么我的问题是:

  1. 是否值得付出额外的努力将值存储为与bcmath 库一起使用的字符串?
  2. 如果使用 bcmath 库,我应该将 MySQL 数据库中的值存储为 MySQL 支持的字符串还是 decimal

谢谢!

【问题讨论】:

  • PS - 当然,在发布之前我已经对此进行了研究。有很多帖子都在讨论如何使用 bcmath 及其对精度的价值,但我找不到一个专门讨论它是否需要只跟踪整数值。
  • 使用整数美分而不是美元存储所有值,因此您可以将它们作为整数处理;并且只使用美元进行输入/输出
  • 正要提出同样的建议,@MarkBaker。 ;-)
  • 存储为整数美分并不是真正的额外工作,您需要的唯一额外工作是将美元/美分输入转换为美分,并将输出从美分装饰为美元/美分......使用 bcmath 将做更多的额外工作
  • 一般来说,除了最苛刻的数学之外,使用浮点数已经绰绰有余了;你只需要非常小心比较和四舍五入;但处理货币的一般方法是使用将使用的最低整数面额存储(并执行任何数学运算)而不是使用浮点数

标签: php decimal precision bcmath


【解决方案1】:

经过进一步挖掘,我在Should I use BCMath for values with about 1,2 or 3 decimals?找到了解决方案

根据给定帖子上接受的答案,浮点数不能保证小数点的任何精度。

就数据库中的存储而言,将其存储为字符串似乎是最简单的选择,因为 bcmath 库适用于字符串。

【讨论】:

  • 为什么忽略将$1.23 存储为整数值123 的选项然后您只需将结果通过/100 转换并输入为*100。然后,您可以对所有这些数字进行整数数学运算,并使用 =>=<= 等搜索数据库
  • @RiggsFolly 这是一个很好的建议,与上面的 Mark Ba​​ker 建议相同。我的问题不是列出所有选项,而是特别是如果绝对需要使用除浮点数(在本例中为 bcmath)以外的任何东西。
【解决方案2】:

使用它来修剪到小数点后两位而不四舍五入。

<?php
$a = 12.37675;
$a = floor($a * 100) / 100; // 12.37
echo $a;

<?php

function dollar($value) {
    return floor($value * 100) / 100;
}

$a = 12.37675;
echo dollar($a);

【讨论】:

  • 使用$c == $d比较浮点数可能会产生不正确的结果......请参阅PHP Documentation中的警告说明,以及它推荐的比较浮点数的方法
猜你喜欢
  • 1970-01-01
  • 2013-07-22
  • 2011-06-11
  • 2013-03-14
  • 1970-01-01
  • 2012-05-18
  • 2016-10-02
  • 1970-01-01
  • 2011-11-19
相关资源
最近更新 更多