12

作为输入,我想接受以下任何一项:“$12.33”、“14.92”、“$13”、“17”、“14.00001”。作为输出,我分别想要 1233、1492、1300、1700 和 1400。这显然不像看起来那么容易:

<?php
$input = '$64.99';  // value is given via form submission
$dollars = str_replace('$', '', $input);  // get rid of the dollar sign
$cents = (int)($dollars * 100) // multiply by 100 and truncate
echo $cents;
?>

这将输出 6498 而不是 6499。

我认为这与浮点值的不准确性有关,避免这些是我首先转换为整数美分的全部原因。我想我可以使用类似“去掉 $ 符号,检查是否有小数点,如果有,检查在填充到两个并截断之后有多少个字符,然后删除句点,如果没有的话一个附加两个零并希望最好”,但为此使用字符串操作似乎很荒谬。

当然,从表单中获取货币价值并将其作为美分存储在数据库中是一种常见的用例。当然有一种“合理”的方式来做到这一点。

正确的?.....正确的?:<

4

7 回答 7

43

考虑使用BC Math扩展,它可以进行任意精度的数学运算。特别是bcmul()

<?php
$input = '$64.99';
$dollars = str_replace('$', '', $input);
$cents = bcmul($dollars, 100);
echo $cents;
?>

输出:

6499
于 2014-02-12T17:56:09.947 回答
4
$input[] = "$12.33";
$input[] = "14.92";
$input[] = "$13";
$input[] = "17";
$input[] = "14.00001";
$input[] = "$64.99";

foreach($input as $number)
{
    $dollars = str_replace('$', '', $number);
    echo number_format((float)$dollars*100., 0, '.', '');
}

给出:

1233
1492
1300
1700
1400
6499

注意像“0.125 美元”这样的极端情况。我不知道你想如何处理这些。

于 2014-02-12T18:13:47.457 回答
3

啊,我知道为什么了。当你施放它时(int)($dollars*100)它会掉一个小数。我不确定为什么,但删除 int 强制转换并修复它。

于 2014-02-12T17:56:20.953 回答
2

不要直接转换floatinteger.
转换floatstring,然后转换stringinteger

解决方案:

<?php
$input = '$64.99';
$dollars = str_replace('$', '', $input);
$cents = (int) ( (string) ( $dollars * 100 ) );
echo $cents;
?>

解释:

<?php
$input = '$64.99';  // value is given via form submission
$dollars = str_replace('$', '', $input);  // get rid of the dollar sign
$cents_as_float = $dollars * 100;  // multiply by 100 (it becomes float)
$cents_as_string = (string) $cents_as_float;  // convert float to string
$cents = (int) $cents_as_string;  // convert string to integer
echo $cents;
?>
于 2016-10-18T09:24:09.680 回答
2
$test[] = 123;
$test[] = 123.45;
$test[] = 123.00;
$test[] = 123.3210123;
$test[] = '123.3210123';
$test[] = '123,3210123';
$test[] = 0.3210;
$test[] = '00.023';
$test[] = 0.01;
$test[] = 1;


foreach($test as $value){
    $amount = intval(
                strval(floatval(
                    preg_replace("/[^0-9.]/", "", str_replace(',','.',$value))
                ) * 100));
    echo $amount;
}

结果:

12300
12345
12300
12332
12332
12332
32
2
1
100
于 2019-02-25T11:55:11.923 回答
1

删除美元符号,然后使用bcmul()进行乘法。

于 2014-02-12T17:58:04.113 回答
0

出现问题是因为转换为 int 执行截断而不是舍入。简单的修复:在铸造前将数字四舍五入。

<?php
$input = '$64.99';
$dollars = str_replace('$', '', $input);
$cents = (int) round($dollars * 100);
echo $cents;
?>

输出:6499

更长的解释:

当 PHP 看到字符串“64.99”并将其转换为(双精度)浮点时,浮点的实际值为:

64.9899999999999948840923025272786617279052734375

这是因为数字 64.99 不能精确地表示为浮点数,而上述数字是最接近 64.99 的可能浮点数。然后,将它乘以 100(这是完全可表示的),结果变为:

6498.9999999999990905052982270717620849609375

如果将其转换为 int,它将截断该数字,因此您会得到整数 6498,这不是您想要的。但是,如果您先将浮点数四舍五入,您会得到 6499 作为浮点数,然后将其转换为 int 会得到预期的整数。

于 2021-07-02T13:08:38.097 回答