MATLAB showing two equal numbers as not equal to each other

19 Ansichten (letzte 30 Tage)
polynomial=[1,-L1,L2,-L3];
principal_stress=roots(polynomial);
principal_stress=sort(principal_stress)
principal_stress(1,1) == principal_stress(2,1)
This is my code and for certain input values, I got the principal_stress(after sorting) as:
principal_stress =
-1.0000
-1.0000
2.0000
ans =
logical
0
But the answer should be 1, as the 1st and 2nd values both are equal. What am I doing wrong?

Akzeptierte Antwort

John D'Errico
John D'Errico am 2 Feb. 2020
Bearbeitet: John D'Errico am 2 Feb. 2020
They LOOK equal, when written out as numbers with limited signifcant digits. Are they? Consider this example:
format short
x = 1 + eps
x =
1.0000
>> x == 1
ans =
logical
0
sprintf('%0.55f',x)
ans =
'1.0000000000000002220446049250313080847263336181640625000'
So, while MATLAB displays 1.0000, the number was not truly 1, at least not exactly so. It was reasonably close. But exactly equal?
I'd suggest you look far more carefully at those values. Decide if they truly are -1 and are both identically so, or if there is a tiny difference.
For example, you might try things like this:
principal_stress - (-1)
principal_stress(2) - principal_stress(1)
Do they show the two values are not equal? What is that difference? Are they truly both exactly -1?
One big clue is in just how MATLAB displayed them.
format short
x = [-1;-1;2]
x =
-1
-1
2
y = x;
y(2) = y(2) + eps
y =
-1.0000
-1.0000
2.0000
As you can see, when I created x here, the numbers were true integers. They are exactly representable in floating point arithmetic as such. (As long as an integer does not exceed 2^53-1, that will be true. That is not true of a number like 1/3 however, which is not exactly representable as a floating point number with a finite number of digits unless you are using a ternary numeric storage, or something similar. MATLAB, like most computer languages, uses a binary system. So MATLAB can represent reasonably small integers exactly, or purely binary fractions like 1/4. Fractions like 1/3 or even 1/10 are not representable in a finite number of binary bits.)
sprintf('%0.55f',1/4)
ans =
'0.2500000000000000000000000000000000000000000000000000000'
Note that x above was displayed without any trailing zeros. However, when I adulterated x by adding a tiny perturbation to even one of the numbers, MATLAB now displayed them as having trailing zeros. This could have been your first clue the elements of principal_stress were not truly what they seemed - those trailing zeros as displayed.
As for the question of what should be done to make them equal, the problem lies not in the numbers themselves, but in your understanding of floating point numbers. I would first do as I suggested. How different are they? Is the difference down in the limits of floating point trash? Thus, in the depths of the least significant bits of a floating point number? NEVER trust those least significant bits, at least not until you know comprehensively when you can trust them.
So you need to learn about tolerances, and how to apply them. You need to learn about floating point arithemetic in general, about how numbers are stored in a computer, how they are manipulated. Once you get to that point, then you have a better chance of knowing when to trust those least significant bits. Until then, ponder if the
0.9999999999999999999... (truncated at some point) is really identically equal to 1. Is a truncated 0.3333 really the same number as 1/3? Of course not.

Weitere Antworten (1)

dpb
dpb am 2 Feb. 2020
Not remembering floating point rounding.
Try
principal_stress(1,1) - principal_stress(2,1)
and see what the result is. You'll find it's small but nonzero so == rightfully says so.
Use ismembertol instead is one solution.

Kategorien

Mehr zu Matrix Indexing finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by