Is there a bug in the if function
2 次查看(过去 30 天)
显示 更早的评论
for example
if 0.0001575*1800<=5*0.0567
1
else
0
end
The theoretical result should be 1, but the output is 0
1 个评论
Stephen23
2020-7-30
编辑:Stephen23
2020-7-30
"Is there a bug in the if function"
No.
"The theoretical result should be 1, but the output is 0"
No.
The effect of accumulated error with binary floating point numbers is very well documented:
This is worth reading as well:
The only bug here is code written as if floating point error does not exist.
回答(3 个)
Sriram Tadavarty
2020-7-30
HI Tianyuan,
The issue is not with the if condition, but the way the MATLAB deals with the floating point numbers. "Almost all operations in MATLAB are performed in double-precision arithmetic conforming to the IEEE standard 754"
If you evaluate the condition in command window, it provide value 0.
Here are few ways to avoid common problems using airthmetic floating point numbers, have a look here.
To solve this you can try round off for the condition and expect the valid condition.
Hope this helps.
Regards,
Sriram
0 个评论
Vladimir Sovkov
2020-7-30
This is not a bug in the if function but an artefact of the rounding of the matlab bit-wise arithmetics. To avoid this effect, several approaches can be used, e.g.,
if sym(0.0001575*1800)<=sym(5*0.0567)
...
end
although it would work slower than the purely numerical version.
0 个评论
Walter Roberson
2020-7-30
> 0.0001575*1800-5*0.0567
ans =
5.55111512312578e-17
> sym(0.0001575)*1800-5*sym(0.0567)
ans =
6777/576460752303423488000
> sym(1575)/sym(10000000)*1800-5*sym(567)/sym(10000)
ans =
0
> sym(0.0001575) - sym(1575)/sym(10000000)
ans =
753/115292150460684697600000
That one tells us that the approximation of 0.0001575 by the symbolic toolbox is not the same as 1575/10000000 .
> fprintf('%.999g\n', 0.0001575)
0.00015750000000000000653123388705267871046089567244052886962890625
... because the closest binary double precision representation to 0.0001575 is a number which is slightly larger than an exact fraction.
> sym('0.0001575')*1800-5*sym('0.0567')
ans =
0.0
So if you use the symbolic toolbox carefully you can get the comparison to work out.
But the problem is not with "if": it has to do with the way that binary double precision numbers are represented. double() does not use decimal representation internally (IEEE has defined an equivalent decimal standard to the very common binary standard, but the only vendor that I know of that implements the decimal hardware, is IBM in their z90 series.)
This is a very common issue to have show up. When you compare two double precision numbers that have been calculated through different paths, you should always take into account precision limitations. For equality comparisons, use ismembertol() . Otherwise, instead of testing A <= B, test A <= B + tolerance
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Special Values 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!