【问题标题】:PHP unexpected result of float to int type cast浮点到 int 类型转换的 PHP 意外结果
【发布时间】:2011-03-24 01:50:01
【问题描述】:

我正在尝试将浮点数转换为 php 中的 int 值:

var_dump((int)(39.3 * 100.0)); //Returns 3929 but should be 3930!
var_dump((int)(39.2 * 100.0)); //Returns 3920

我可以使用 ceil 使其工作,但有人可以向我解释一下吗?

var_dump((int)ceil(39.3 * 100.0)); //Returns 3930

【问题讨论】:

  • 一个简短的说明,希望您期待 3930,而不是 3939。

标签: php casting floating-point type-conversion


【解决方案1】:

这是因为在基数 10 中具有有限表示的数字在 PHP 使用的浮点表示中可能有也可能没有精确表示。

>php -r "echo var_dump(sprintf('%.40F', 39.3 * 100.0));" 字符串(45)“3929.9999999999995452526491135358810424804688”

由于int 总是将数字向下舍入,因此表示中的一个小错误会使强制转换将其向下舍入一个数字,而不是您所期望的。

考虑改用round

【讨论】:

  • 你不应该使用String和round,bcmul函数是有目的的。
【解决方案2】:

你应该看看这个页面:http://php.net/manual/en/language.types.float.php。 它描述了使用浮点数的陷阱。

【讨论】:

【解决方案3】:
// gives: int(3930)
var_dump(intval((39.3 * 100.0) . '')); 

或者,用于函数:

function floatToInteger ($fValue)
{
    return (intval(($fValue + 0) . ''));
}

// gives: int(3930)
var_dump(floatToInteger(39.3 * 100.0));

【讨论】:

    【解决方案4】:

    这可能会迟到,但正确的做法如下:

    (int) bcmul("39.3", "100.0"); // 3930
    (int) bcmul("39.2", "100.0"); // 3920
    

    对于处理浮点数的数字/计算,或任何涉及金钱交易的事情,你不应该直接使用乘法/除法+转换。

    也请参考:

    http://php.net/manual/en/book.bc.php

    注意:我的答案中的转换只是将 String 转换为 Int,(您不需要这样做)

    【讨论】:

    • 注意:bcmul 期望字符串作为参数,并且会抛出严格类型的 TypeError。
    • @SzabolcsPáll 感谢您的更正,在撰写本文时 PHP 5 仍然占主导地位,但您的评论在所有情况下都有效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多