我使用Money类,要求所有货币都在int
中才能实例化它。发生了什么事情,我遇到了一个特定的号码(我已经尝试过各种其他数字,一切都按预期工作),从float
到{{1 },具有不同的值。
由于一般浮点数的性质,我可能会从一个非常高的精度数中得到这个,但这没有任何意义,这就是我如何重现错误...
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);
希望能帮助别人!
答案 0 :(得分:2)
PHP使用浮点数的指数表示,因此它不精确。阅读docs:
浮点数的精度有限。虽然这取决于 在系统中,PHP通常使用IEEE 754双精度格式, 由于订单的舍入,这将产生最大的相对误差 1.11e-16。非基本算术运算可能会更大 错误,当然,必须考虑错误传播 几个操作复杂化。
另外,理性数字 可以完全表示为基数10中的浮点数,例如 0.1或0.7,没有精确表示为基数2中的浮点数,它在内部使用,无论大小如何 尾数。因此,它们无法转换为内部二进制文件 对应物没有精确的损失。这可能会导致 令人困惑的结果:例如,楼层((0.1 + 0.7)* 10)通常会 返回7而不是预期的8,因为内部表示 将是像7.9999999999999991118 ....
<强> UPDv1:强>
注意PHP math extensions:BCMath和GMP。