我使用的 Money 类要求所有货币都位于 int
中为了实例化它。发生的事情是我遇到了一个特定的数字(我尝试过各种其他数字,一切都按预期工作),当从 float
进行类型转换时至int
,具有不同值。
由于 float 的一般性质,我可能期望这是一个非常高精度的数字,但这没有任何意义,这是我重现错误的方法...
$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 使用 float 的指数表示,因此并不精确。阅读 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。
关于php - PHP中简单数字的float到int改变值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32794614/