消除货币输入

时间:2012-11-06 20:38:02

标签: php

我正在使用货币输入。应使用小数点后仅两位数。我尝试将输入转换为浮动并乘以100,这可以正常工作,直到有人在十进制标记后输入两位数以上:

// Returns 6999.8 instead of 6999
$cents = floatval('69.998') * 100;

然后我尝试将结果转换为int,因此忽略小数点后的连续数字。它解决了上述问题('69 .998'变为6999),但是创建了一个带浮点到整数转换的新问题:

// Returns 6998 instead of 6999
$cents = intval(floatval('69.99') * 100);

我也考虑过floor(),但是它会触发与intval()相同的浮动问题。

这就是我正在考虑使用的方法:

$cents = intval((string)(floatval('69.99') * 100));

它适用于两种情况,但感觉就像一个黑客,它已经很晚了,我的头疼,所以也许我错过了一些明显的东西。有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

$cents = intval(round(floatval('69.99') * 100));

你需要什么?

您还可以指定精度。例如,在您提到的情况下,您提到要将原始数据舍入到两位小数:

$twodecimal = round(floatval('69.998'),2);//returns a float representation of 70

请务必查看这些docs

中的大红色通知

答案 1 :(得分:2)

这是因为69.99 * 100的{​​{3}}代表6998.9999999*(关闭:您也可以在javascript控制台上查看)。如果你想要准确,你应该使用带有php扩展名的floating-point号码,例如fixed-point - 或者,你可以为这个特定问题写一个简单的正则表达式

$amount = '69.99';

if (preg_match('/^(-?\d+)(\.(\d{1,2}))?/', $amount, $matches))
{
    $amount = (int) ($matches[1] . (isset($matches[3]) ? str_pad($matches[3], 2, '0') : '00'));
}
else
{
    $amount = ((int) $amount) * 100;
}

答案 2 :(得分:0)

$cents = intval(round(floatval('69.99') * 100));

这会正确地得到最接近的数字,这是因为浮动指针精度问题,因为69.99可能在内存中表示为69.9899999

intval只会截断小数的其余部分,因此69.989999 * 100变为6998.9999并被截断为6998

答案 3 :(得分:0)

我建议您使用整数来包含货币值。使用浮动可能会迅速导致舍入错误。

在我看过的应用程序中,使用带有假定小数点的整数。所有价值均以最接近的货币单位计算,例如美元或欧元的分数。有些货币没有小数点,并且有一些货币而不是两个小数位有三个小数位。

通过使用带有假定小数位的整数进行操作,您可以真正减少舍入误差和浮点可以看到的其他问题。

要进行转换,我建议使用字符串操作并使用字符串操作删除小数点,并执行检查以确保只输入所需数量的位置。

相关问题