# Why 4.8/1.6 is not equal to 3?

7 views (last 30 days)
Francesco Grasso on 14 Jan 2020
Answered: Image Analyst on 14 Jan 2020
If I do these operations, I get two completely different results. Yet they could be operations that do not require checking of machine precision. How can this be remedied? Thank you.
>> (2*1.6)/1.6 == 2
ans =
logical
1
>> (3*1.6)/1.6 == 3
ans =
logical
0
>> (2*1.8)/1.8 == 2
ans =
logical
1
>> (3*1.8)/1.8 == 3
ans =
logical
1
My problem concerns the resolution of power flow problems in per-unit (p.u.) for which all numbers are in floating point. Since one of the constraints in solving these problems is that the sum of all the values present on a node of a network must be zero, because of these errors the sum is not always zero and this blocks some algorithms. In some cases, the problem was solved using ~= instead of == (1), but this can lead to other problems when the sum must be precisely ~= 0.
I was convinced that there was a way to eliminate this problem without having to think that the possible solution of a power flow problem could depend on the numbers involved or if the error in my answer is the result of round-off error or a bug. But I understood, thanks to the various references indicated, that this is not the case.

Francesco Grasso on 14 Jan 2020
My problem concerns the resolution of power flow problems in per-unit (p.u.) for which all numbers are in floating point. Since one of the constraints in solving these problems is that the sum of all the values present on a node of a network must be zero, because of these errors the sum is not always zero and this blocks some algorithms. In some cases, the problem was solved using ~= instead of == (1), but this can lead to other problems when the sum must be precisely ~= 0.
I was convinced that there was a way to eliminate this problem without having to think that the possible solution of a power flow problem could depend on the numbers involved or if the error in my answer is the result of round-off error or a bug. But I understood, thanks to the references indicated, that this is not the case.

KALYAN ACHARJYA on 14 Jan 2020
Edited: KALYAN ACHARJYA on 14 Jan 2020
Here "==" is logical equality check, if the Left Hand Side equal to Right Hand side, it gives logical 1 (True), else 0
>> 4.8/1.6
ans =
3.0000
>> ans==3
ans =
logical
0
Here floating point representation, is related to Precision, This is FAQ (Multiple Answered there)
More Detail (Detail Explanation by @Jan), also you can look here for Floating-Point Arithmetic in Matlab
Still any issue let us know?

KALYAN ACHARJYA on 14 Jan 2020
Great Going!
As we agreed
(1.6*3)/3==3
ans = logical
0
But here Here LHS is not equal to 3 Exactly (As floating number representation)
>> (1.8*3)/3
ans =
1.8000
>> ans==3
ans =
logical
0
Stephen Cobeldick on 14 Jan 2020
"The operations are both comparable and, a priori, there is no way to find out whether or not the result will be reliable."
An exact comparison is not the correct approach. The correct approach is to compare the absolute difference against a tolerance, which allows for accumulated floating point error.
"In other words, how can I make the two operations equivalent in a script without having to worry about machine precision?"
You can't. The fact is that operations on floating point numbers accumulate floating point error, and your code needs to be written to allow for this. The correct approach is to assume that your operations always accumulate floating point error and do not perform exact comparisons.
Francesco Grasso on 14 Jan 2020
Thanks.

John D'Errico on 14 Jan 2020
Edited: John D'Errico on 14 Jan 2020
While there has been a lot of good discussion in the other answer, let me add a few points.
When you type 4.8 in MATLAB, does MATLAB understand what that number really is, and store it as exactly 4.8? (NO.)
x = 4.8
x =
4.8
>> sprintf('%0.55f',x)
ans =
'4.7999999999999998223643160599749535322189331054687500000'
So, while MATLAB displays it as 4.8, in fact, it stores it as the closest number that it can find as a binary number. In fact, just as 1/3 is NOT representable exactly as a decimal number in a finite number of digits, the same is true for most such rational numbers.
The binary expansion of that number is an infinitely repeating binary fraction, represented as:
100.11001100110011001100110011001100110011001100110011...
But MATLAB can only store a finite number of bits.
1.6 is eactly the same thing.
sprintf('%0.55f',1.6)
ans =
'1.6000000000000000888178419700125232338905334472656250000'
Now, what happens when you take the ratio of those two numbers? The ratio cannot possibly end up as exactly 3.
sprintf('%0.55f',4.8/1.6)
ans =
'2.9999999999999995559107901499373838305473327636718750000'
Again, that result ends up stored as an infinite binary number, truncated to 52 bits.
10.111111111111111111111111111111111111111111111111111...
But just as 0.3333 is NOT the same thing as 1/3, no matter how many digits you type, 4/8/1/6 does not yield an exact value of 3.
Never trust the least significant bits of a floating point number, at least not unless you understand them so well that you would never have needed to ask the question you did ask.

#### 1 Comment

Francesco Grasso on 14 Jan 2020
The problem with floating point numbers is well known to me and I realize that I have incorrectly asked the question.
My problem concerns the resolution of power flow problems in per-unit (p.u.) for which all numbers are in floating point. Since one of the constraints in solving these problems is that the sum of all the values present on a node of a network must be zero, because of these errors the sum is not always zero and this blocks some algorithms. In some cases, the problem was solved using ~= instead of == (1), but this can lead to other problems when the sum must be precisely ~= 0.
I was convinced that there was a way to eliminate this problem without having to think that the possible solution of a power flow problem could depend on the numbers involved or if the error in my answer is the result of round-off error or a bug. But I understood, thanks to the references indicated, that this is not the case.