Why 4.8/1.6 is not equal to 3?

1 次查看(过去 30 天)
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.
  2 个评论
Francesco Grasso
Francesco Grasso 2020-1-14
Thanks for this detailed reply.
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
KALYAN ACHARJYA 2020-1-14
编辑:KALYAN ACHARJYA 2020-1-14
Here "==" is logical equality check, if the Left Hand Side equal to Right Hand side, it gives logical 1 (True), else 0
More about
>> 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?
  6 个评论
Stephen23
Stephen23 2020-1-14
编辑:Stephen23 2020-1-14
"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.

请先登录,再进行评论。

更多回答(2 个)

John D'Errico
John D'Errico 2020-1-14
编辑:John D'Errico 2020-1-14
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 个评论
Francesco Grasso
Francesco Grasso 2020-1-14
Thanks for this detailed reply.
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.

请先登录,再进行评论。


Image Analyst
Image Analyst 2020-1-14

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by