简体   繁体   English

从float转换为int时的舍入错误

[英]Rounding error when casting from float to int

We have an API that returns prices as string in EUR, eg 2.55 or 0.035 . 我们有一个API,以EUR字符串形式返回价格,例如2.550.035 Our database however saves this in cents, so I wrote a really simple method to transform this into cents by just doing 但是我们的数据库将其保存为美分,所以我写了一种非常简单的方法,只需执行以下操作即可将其转换为美分

$cents = (int) ((float) $value['value']['amount'] * 100)

So for this code 所以对于这段代码

echo (int) ((float) '2.55' * 100);

the result should be 255 , right? 结果应该是255 ,对吧? But somehow, it's 254 . 但是不知何故,它是254 You can test this on your CLI by simply doing 您只需执行以下操作即可在CLI上进行测试

php -r "echo (int) ((float) '2.55' * 100);"

When I get the result of (float) '2.55' * 100) it's simply 255 , and when I cast this to int it's 255 , why isn't it the same if I cast it to int in the same call? 当我得到(float) '2.55' * 100)的结果时,它只是255 ,而当我将其255为int时,它的值是255 ,如果我在同一调用中将其强制转换为int,为什么它不一样呢?

I mean, I could simply do '2.55' * 100 and the php casting would calculate this correctly, but I'm still curious why this happens? 我的意思是,我可以简单地执行'2.55' * 100 ,而php cast可以正确计算出这个值,但是我仍然很好奇为什么会这样?

Version: 版:

PHP 7.1.15-1+ubuntu16.04.1+deb.sury.org+2 (cli) (built: Mar 6 2018 11:10:13) ( NTS ) PHP 7.1.15-1 + ubuntu16.04.1 + deb.sury.org + 2(CLI)(内置:Mar 6 2018 11:10:13)(NTS)

It could be a floating point error. 可能是浮点错误。

In php, a float value like 255 could actually be something like 254.9999991. 在php中,像255这样的float值实际上可能像254.9999991。 You can round the value before converting to int . 您可以在转换为int之前round该值。

echo (int) ( round( (float) '2.55' * 100 ) );

This will result to 这将导致

255

From PHP Doc: 从PHP Doc:

Warning Floating point precision Floating point numbers have limited precision. 警告浮点数精度浮点数精度有限。 Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. 尽管它取决于系统,但PHP通常使用IEEE 754双精度格式,由于舍入为1.11e-16的顺序,它将提供最大的相对误差。 Non elementary arithmetic operations may give larger errors, and, of course, error propagation must be considered when several operations are compounded. 非基本算术运算可能会产生较大的错误,并且,当然,在合并多个运算时必须考虑错误传播。

http://php.net/manual/en/language.types.float.php http://php.net/manual/en/language.types.float.php

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM