【发布时间】:2011-04-19 22:29:29
【问题描述】:
考虑到浮点数不精确并且我应该使用 BCMath 函数来获得精确结果的事实,是否真的有必要在 PHP 中使用价格字符串并在制作“简单”购物车时将它们与 bcadd 相加?
鉴于以下示例,我为什么不应该使用圆角浮点数?
我正在寻找计算购物车订单总额的最佳做法。
$floatTotal = 0.00;
$stringTotal = '0.00';
for($i=0; $i<1000; $i++) {
$floatTotal += 0.1;
}
echo "float value: ";
printf('%.40f', $floatTotal); //99.9999999999985931253831950016319751739502
echo "<br>\n";
echo "rounded float value: ". round($floatTotal); //100
echo "<br>\n";
for($i=0; $i<1000; $i++) {
$stringTotal = bcadd($stringTotal, '0.1', 2);
}
echo 'string value: '.$stringTotal.'<br>'; //100.00
【问题讨论】:
-
将您的货币金额存储为便士。然后转换为常规美元值是除以 100 的简单问题,并且还消除了任何浮点错误。
-
但是相对简单的购物车有多大必要呢?您是否遇到过舍入错误?
-
如果您正在处理货币价值,那么不要使用浮点数,句点。无论多么复杂或多么简单。要么将货币值作为便士存储在 INT 字段中,要么使用数据库的“十进制”类型,即 FIXED 点存储。这不是问题或浮点错误有多频繁/罕见。它存在,除非你想成为 IEEE 754 方面的专家,否则不要使用它们
-
@Marc B:他的问题并没有专门针对持久性存储。 185 美分的 25% 产生 46.25 的折扣。浮点数会抬起他们丑陋的脑袋,不管是不是小单位。
-
无论如何你都必须四舍五入,但存储为 penny-ints 可以消除至少一个浮点引起的错误来源。对于“小”错误,差异可能只出现一分钱,但在某个地方有人在看超人三世并邪恶地咯咯笑。
标签: php