PHP 中简单数字的浮点数变化值

Float to int changing value of simple number in PHP

我使用的货币 class 要求所有货币都在 int 中才能实例化它。发生的事情是我 运行 跨越了一个特定的数字(我尝试了各种其他数字并且一切都按预期工作)当类型从 float 转换为 int 时,有不同的值。

由于一般浮点数的性质,我可能希望这是一个非常高精度的数字,但这没有任何意义,这是我重现错误的方法...

$value = (float)9.78;
var_dump($value );
$prec = (int)(100);
var_dump($prec);
$value = $value * $prec;
var_dump($value);
var_dump((int)($value));

... 产生以下输出 ...

float(9.78)  /* $value as a float */
int(100)     /* $prec as an int */
float(978)   /* $value * $prec as a float, all going well... */
int(977)     /* $value type cast to an int ???????? */

...这到底是怎么回事? 为什么在这种情况下将 $value 类型转换为 int 会产生不同的值?


编辑: 我不接受这个重复的原因是因为我不需要在另一个线程中出现的答案。在这里:我必须像这样申请 round()...

$dec_precision = strlen((string)($prec)-1);
$value = round($value * $prec, $dec_precision);

希望对某人有所帮助!

PHP使用浮点数的指数表示,所以不精确。阅读 docs:

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. Non elementary arithmetic operations may give larger errors, and, of course, error propagation must be considered when several operations are compounded.

Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. 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.9999999999999991118....

UPDv1:

注意 PHP math extensions:BCMath 和 GMP。