Why does 1 - 2/3 - 1/3 not equal zero?

Try this:
>> 1 - 2/3 - 1/3
MATLAB gets the wrong answer:
5.5511e-017

 採用された回答

Matt Fig
Matt Fig 2011 年 1 月 20 日

6 投票

Ned! I am sure you know that the reason why (1 - 2/3 - 1/3) ~=0 is that MATLAB does its work in floating point arithmetic, not in exact arithmetic.

1 件のコメント

Ned Gulley
Ned Gulley 2011 年 1 月 20 日
Hi Matt: Yes, this is an obvious one to get the ball rolling. By the way, I changed the formatting of your answer slightly to make the link a little clearer.

サインインしてコメントする。

その他の回答 (3 件)

Doug Hull
Doug Hull 2011 年 1 月 21 日

6 投票

As is mentioned frequently in the newsgroup, some floating point numbers can not be represented exactly in binary form. So that's why you see the very small but not zero result. See EPS.
The difference is that 0:0.1:0.4 increments by a number very close to but not exactly 0.1 for the reasons mentioned below. So after a few steps it will be off whereas [0 0.1 0.2 0.3 0.4] is forcing the the numbers to their proper value, as accurately as they can be represented anyway.
a=[0 0.1 0.2 0.3 0.4];
b=[0:.1:.4];
as=sprintf('%20.18f\n',a)
as =
0.000000000000000000 % ==
0.100000000000000010 % ==
0.200000000000000010 % ==
0.299999999999999990 % ~= bs !
0.400000000000000020 % ==
bs=sprintf('%20.18f\n',b)
bs =
0.000000000000000000 % ==
0.100000000000000010 % ==
0.200000000000000010 % ==
0.300000000000000040 % ~= as !
0.400000000000000020 % ==
% -and-
format hex;
hd=[a.',b.']
hd =
0000000000000000 0000000000000000 % ==
3fb999999999999a 3fb999999999999a % ==
3fc999999999999a 3fc999999999999a % ==
3fd3333333333333 3fd3333333333334 % ~= !
3fd999999999999a 3fd999999999999a % ==
If you're trying to compare two floating-point numbers, be very careful about using == to do so. An alternate comparison method is to check if the two numbers you're comparing are "close enough" (as expressed by a tolerance) to one another:
% instead of a == b
% use:
areEssentiallyEqual = abs(a-b) < tol
% for some small value of tol relative to a and b
% perhaps defined using eps(a) and/or eps(b)
You can see this same sort of behavior outside MATLAB. Using pencil and paper (or a chalkboard, or a whiteboard, etc.) compute x = 1/3 to as many decimal places as you want. The number of decimal places must be finite, however. Now compute y = 3*x. In exact arithmetic, y would be exactly 1; however, since x is not exactly one third but is a rounded approximation to one third, y will not be exactly 1.
For a readable introduction to floating point arithmetic, look at Cleve's Corner article from 1996: Floating Points (PDF)
For more rigorous and detailed information on floating point arithmetic, read the following paper: What Every Computer Scientist Should Know About Floating Point Arithmetic.
Another resource is Technical Note 1108 on the Support section of The MathWorks website.

5 件のコメント

Amir
Amir 2011 年 7 月 15 日
how to fix this problem on tf objects?
Z= tf([1 1],1,-1,'variable','z')-1 ;
>> Z-(1/3)*Z-(2/3)*Z Transfer function: 1.11e-016 z
>> abs(H) ??? Undefined function or method 'abs' for input arguments of type 'tf'.
Walter Roberson
Walter Roberson 2011 年 7 月 15 日
Try (3*Z-Z-2*Z)/3
Amir
Amir 2011 年 7 月 28 日
that's just an example to for the case. I need a solution to work with any given system!(G/H) wherever I do a simple arithmetic with my tf's it does not zero out when its necessary.
Amir
Amir 2011 年 7 月 29 日
basically many arithmetic functions dont work for tf objects.
Amir
Amir 2011 年 7 月 29 日
I wrote my code wondering if matlab must have it!
function [am] = cancelout(a,tol) %for small gain probelm
for k=1:size(a,1)
for m=1:size(a,2)
[z,gain] =zero(a(k,m));
if ( abs(gain)<tol)
a(k,m)=0;
end
gain=NaN;
end
end
am=a;

サインインしてコメントする。

Derek O'Connor
Derek O'Connor 2011 年 7 月 29 日

1 投票

Ned,
Let me add to the confusion by asking
1. Why does en1 = (1 - 2/3) - 1/3 = 5.5511e-017 = 2^(-54) = eps/2^2?
2. Why does en2 = 1 - (2/3 + 1/3) = 0?
3. Why does Kahan's
a = 4/3; b = a-1; c = b+b+b; ek = 1-c = 2.2204e-016 = 2^(-52) = eps?
An explanation of Kahan's result is given on page 7 of:
The difficulties in defining machine precision are discussed by Nick Higham and Cleve Moler here:
Derek O'Connor
Skaletki Liviu
Skaletki Liviu 2020 年 12 月 7 日

0 投票

how I write this expression |n-(N-1)/2| ?

カテゴリ

製品

質問済み:

2011 年 1 月 13 日

編集済み:

2020 年 12 月 7 日

Community Treasure Hunt

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

Start Hunting!

Translated by