7 views (last 30 days)

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.

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

More about

>> 4.8/1.6

ans =

3.0000

>> ans==3

ans =

logical

0

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.

Sign in to comment.

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.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500256-why-4-8-1-6-is-not-equal-to-3#comment_786119

⋮## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500256-why-4-8-1-6-is-not-equal-to-3#comment_786119

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500256-why-4-8-1-6-is-not-equal-to-3#comment_786141

⋮## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500256-why-4-8-1-6-is-not-equal-to-3#comment_786141

Sign in to comment.