# Is there a bug in the if function

3 views (last 30 days)
tianyuan wang on 30 Jul 2020
Edited: Stephen on 30 Jul 2020
for example
if 0.0001575*1800<=5*0.0567
1
else
0
end
The theoretical result should be 1, but the output is 0

Sriram Tadavarty on 30 Jul 2020
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

Vladimir Sovkov on 30 Jul 2020
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.

Walter Roberson on 30 Jul 2020
> 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