我得到fmod返回错误的结果,我做错了什么?
for($i = 0.00; $i < 1; $i = $i + 0.05) {
var_dump($i." = ".fmod($i, 0.05));
}
输出:
0.= 0
0.05 = 0
0.1 = 0
0.15 = 1.3877787807814E-17
0.2 = 0
0.25 = 0.05
0.3 = 0.05
0.35 = 0.05
0.4 = 0.05
0.45 = 0.05
0.5 = 0.05
0.55 = 0.05
0.6 = 0.05
0.65 = 0.05
0.7 = 2.7755575615629E-17
0.75 = 6.9388939039072E-17
0.8 = 1.1102230246252E-16
0.85 = 1.5265566588596E-16
0.9 = 1.942890293094E-16
0.95 = 2.3592239273285E-16
我期待每个结果都是一样的:0。
答案 0 :(得分:1)
首先,fmod
是准确的。因为它可以:当x
和y
是浮点数时,fmod(x,y)
的数学结果可以完全表示为浮点数。
第二,当你写0.05
时,你没有得到那个数字,因为另一方面5/100不能完全表示为浮点数;当你写+
时,你通常不会得到数学加法,因为这个数学加法的结果不能总是表示为浮点数(*)。
从0.0开始并重复添加0.05将很快进入不准确的+
区域,因为在二进制中,0.05的最佳表示具有许多数字。随着总和变大,最后的数字必须逐渐丢弃。这就是+
的不准确性来自的地方,最终导致fmod
无法提供您期望的结果。
如果将0.05
重复添加到零,那么0.05
不完全是5/100并不重要。但由于浮点数0.05
有二进制数(而不是十进制数),并且因为计算y
的倍数时必须丢失其中一些数字,所以大多数倍数得到的值0.05
计算fmod(y, 0.05)
时0.05
的{{1}} {1}}不是零,而是表示适当整数乘以y
的数学乘法与该数字的近似值{{1}}之间的差值。
(*)当数学和可以表示时,数学和就是你得到的,但有时它不能。
答案 1 :(得分:0)
https://stackoverflow.com/revisions/28372286/1
一切正常!你可以自己计算:
fmod(0.5, 0.25);
fmod(0.5, 0.23);
fmod(0.5, 0.20);
0.25 * 2 = 0.50 | Rest 0.00
0.23 * 2 = 0.46 | Rest 0.04
0.20 * 2 = 0.40 | Rest 0.10