简体   繁体   English

在PHP中舍入

[英]Rounding in PHP

$a = ((0.1 + 0.7) * 10) == (int)((0.1 + 0.7) * 10);

PHP returns false. PHP返回false。

Could anybody explain me, why that happens? 任何人都可以解释一下,为什么会这样? First returns 8, second 7. 首先返回8,第二个7。

Quoting the big fat red warning in the PHP Manual on Floating Point Precision : 引用PHP浮点精度手册中大红色警告

It is typical that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a small loss of precision. 通常,像0.10.7这样的简单小数部分不能转换成它们的内部二进制对应,而不会有很小的精度损失。 This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8 , since the internal representation will be something like 7.9 . 这可能会导致混乱的结果:例如, floor((0.1+0.7)*10)通常会返回7而不是预期的8 ,因为内部表示将类似于7.9

This is due to the fact that it is impossible to express some fractions in decimal notation with a finite number of digits. 这是因为不可能用有限数字的十进制表示法表示一些分数。 For instance, 1/3 in decimal form becomes 0.3 . 例如,十进制形式的1/3变为0.3

So never trust floating number results to the last digit, and never compare floating point numbers for equality. 因此,永远不要将浮点数结果信任到最后一位,并且永远不要将浮点数与相等性进行比较。 If higher precision is necessary, the arbitrary precision math functions and gmp functions are available. 如果需要更高的精度,可以使用任意精度数学函数gmp函数。

Floating point arithmetic is not precise. 浮点运算不精确。 Instead of 8.0 exactly you can get 7.999... which gets truncated to 7 when cast to an integer. 而不是8.0,你可以获得7.999 ...当被转换为整数时被截断为7。

echo number_format((0.1 + 0.7) * 10, 20);

Result: 结果:

7.99999999999999911182

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

EDIT 编辑

$a = ((0.1 + 0.7) * 10) == 8;
var_dump($a);

echo '<br />';

define('PRECISION', 1.0e-08);

$a = (abs(((0.1 + 0.7) * 10) - 8) < PRECISION);
var_dump($a);

Mark's response hits the nail on the head, but I think instead of casting you want the round PHP function: 马克的反应击中了头部的钉子,但我认为而不是你需要圆形的PHP函数:

http://php.net/manual/en/function.round.php http://php.net/manual/en/function.round.php

From The Flaoting-Point Guide (click for detailed explanations): 来自The Flaoting-Point指南 (点击查看详细说明):

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all . 因为在内部,计算机使用的格式(二进制浮点),其不能准确地表示相同的0.1,0.2或0.3,在所有的数。

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens. 编译或解释代码时,“0.1”已经四舍五入到该格式中最接近的数字,即使在计算发生之前也会导致小的舍入误差。

因为在浮点数上运算不是100%准确,所以在从表达式转换值之前可能是类似于7.9999 ......

你可以这样做比较:

$a = round(((0.1 + 0.7) * 10), 1) == (int)round(((0.1 + 0.7) * 10), 1);

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

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