And*_* K. 5 php subtraction floating-point-precision
例如...
$aa = 10694994.89;
$bb = 10696193.86;
$ab = $aa - $bb;
// result is:-1198.9699999988 not the -1198,97
Run Code Online (Sandbox Code Playgroud)
但在此示例中:
$cc = 0.89;
$dd = 0.86;
$cd = $cc - $dd;
//Result is: 0.03
Run Code Online (Sandbox Code Playgroud)
为什么与示例有所不同?缺乏精度?
代码中的任何数字都不能用二进制浮点数精确表示。它们都以某种方式四舍五入。问题是为什么其中一个结果(似乎)四舍五入为两位小数,而不是另一个。答案在于浮点数的精度和准确度与 PHP 用于打印它们的精度之间的差异。
浮点数由范围 中的有效数(或尾数)表示,[1, 2)通过将其乘以 2 的幂来缩放。(这就是浮点数中的“浮动”的意思)。的精度的数量是通过在数字的数目来确定有效数。该精度是多少这些数字实际上是正确的决定。请参阅:浮点数如何存储在内存中?更多细节。
当您echo在 PHP 中浮点数时,它们首先使用precision配置设置转换为字符串,默认为 14。(在Zend/zend_operators.c)
要查看实际情况,您必须使用更高的精度打印数字:
$aa = 10694994.89;
$bb = 10696193.86;
$ab = $aa - $bb;
printf ("\$aa: %.20G\n", $aa);
printf ("\$bb: %.20G\n", $bb);
printf ("\$ab: %.20G\n\n", $ab);
$cc = 0.89;
$dd = 0.86;
$cd = $cc - $dd;
printf ("\$cc: %.20G\n", $cc);
printf ("\$dd: %.20G\n", $dd);
printf ("\$cd: %.20G\n", $cd);
Run Code Online (Sandbox Code Playgroud)
输出:
$aa: 10694994.890000000596
$bb: 10696193.859999999404
$ab: -1198.9699999988079071
$cc: 0.89000000000000001332
$dd: 0.85999999999999998668
$cd: 0.030000000000000026645
Run Code Online (Sandbox Code Playgroud)
初始数字的精度约为 16 到 17 位。减去时$aa-$bb,前 4 位数字相互抵消。结果(虽然仍然具有大约 16 到 17 位的精度),但现在只能精确到大约 12 位。当使用 14 位精度打印结果时,会出现这种较低的精度。
另一个减法 ( $cc-$dd) 仅损失一位数的精度,当以 14 位精度打印时,这一点并不明显。
| 归档时间: |
|
| 查看次数: |
3289 次 |
| 最近记录: |