Numerical error in addition within precision limit

I ran the simple piece of code and it generated the output shown below the code. All additions are within the precision limit but the output shows an accumulating error with each operation. I have verified that it is not a printing error. Any explanations on why this is happening? I am using Matlab Rev2014b.
tstep = 1E-10;
timenow = tstep;
while timenow < 1E-8
temp = sprintf('%.17e',timenow);
disp(temp);
timenow = timenow + tstep;
end
1.00000000000000000e-10
2.00000000000000010e-10
3.00000000000000000e-10
4.00000000000000010e-10
5.00000000000000030e-10
6.00000000000000000e-10
6.99999999999999960e-10
7.99999999999999930e-10
8.99999999999999890e-10
9.99999999999999860e-10
1.09999999999999990e-09
1.20000000000000000e-09
1.30000000000000010e-09
1.40000000000000010e-09
1.50000000000000020e-09
1.60000000000000030e-09
1.70000000000000030e-09
1.80000000000000040e-09
1.90000000000000050e-09
2.00000000000000050e-09
2.10000000000000060e-09
2.20000000000000070e-09
2.30000000000000070e-09
2.40000000000000080e-09
2.50000000000000090e-09
2.60000000000000090e-09
2.70000000000000100e-09
2.80000000000000110e-09
2.90000000000000120e-09
3.00000000000000120e-09
3.10000000000000130e-09
3.20000000000000140e-09
3.30000000000000140e-09
3.40000000000000150e-09
3.50000000000000160e-09
3.60000000000000160e-09
3.70000000000000170e-09
3.80000000000000180e-09
3.90000000000000180e-09
4.00000000000000190e-09
4.10000000000000200e-09
4.20000000000000200e-09
4.30000000000000210e-09
4.40000000000000220e-09
4.50000000000000220e-09
4.60000000000000230e-09
4.70000000000000240e-09
4.80000000000000240e-09
4.90000000000000250e-09
5.00000000000000260e-09
5.10000000000000270e-09
5.20000000000000270e-09
5.30000000000000280e-09
5.40000000000000290e-09
5.50000000000000290e-09
5.60000000000000300e-09
5.70000000000000310e-09
5.80000000000000310e-09
5.90000000000000320e-09
6.00000000000000330e-09
6.10000000000000330e-09
6.20000000000000340e-09
6.30000000000000350e-09
6.40000000000000350e-09
6.50000000000000360e-09
6.60000000000000370e-09
6.70000000000000370e-09
6.80000000000000380e-09
6.90000000000000390e-09
7.00000000000000400e-09
7.10000000000000400e-09
7.20000000000000410e-09
7.30000000000000420e-09
7.40000000000000420e-09
7.50000000000000430e-09
7.60000000000000350e-09
7.70000000000000280e-09
7.80000000000000200e-09
7.90000000000000130e-09
8.00000000000000050e-09
8.09999999999999970e-09
8.19999999999999900e-09
8.29999999999999820e-09
8.39999999999999750e-09
8.49999999999999670e-09
8.59999999999999590e-09
8.69999999999999520e-09
8.79999999999999440e-09
8.89999999999999370e-09
8.99999999999999290e-09
9.09999999999999220e-09
9.19999999999999140e-09
9.29999999999999060e-09
9.39999999999998990e-09
9.49999999999998910e-09
9.59999999999998840e-09
9.69999999999998760e-09
9.79999999999998680e-09
9.89999999999998610e-09
9.99999999999998530e-09

 Accepted Answer

"... All additions are within the precision limit ..."
What do you mean by that statement? You are doing floating point arithmetic, and the decimal numbers you are using are not exactly representable in IEEE double precision. So why is it surprising to you that there is an accumulation of "error" in the calculation? There are better schemes for getting a "close to" uniform spread of numbers across a range (e.g., linspace), but even that will not get you your decimal numbers exactly ... it will still be limited by the available IEEE double set.
tstep = 1E-10;
timenow = tstep;
while timenow < 1E-8
disp(num2strexact(timenow));
timenow = timenow + tstep;
end
1.0000000000000000364321973154977415791655470655996396089904010295867919921875e-10
2.000000000000000072864394630995483158331094131199279217980802059173583984375e-10
2.999999999999999980049621235082650538839033060867222957313060760498046875e-10
4.00000000000000014572878926199096631666218826239855843596160411834716796875e-10
5.0000000000000003114079572888992820944853434639298939146101474761962890625e-10
5.99999999999999996009924247016530107767806612173444591462612152099609375e-10
6.9999999999999996087905276514313200608707887795389979146420955657958984375e-10
7.999999999999999257481812832697339044063511437343549914658069610595703125e-10
8.9999999999999989061730980139633580272562340951481019146740436553955078125e-10
9.9999999999999985548643831952293770104489567529526539146900177001953125e-10
1.099999999999999923753143406777998958290254449821077287197113037109375e-9
1.19999999999999999201984849403306021553561322434688918292522430419921875e-9
1.3000000000000000602865535812881214727809719988727010786533355712890625e-9
1.40000000000000012855325866854318273002633077339851297438144683837890625e-9
1.50000000000000019681996375579824398727168954792432487010955810546875e-9
1.60000000000000026508666884305330524451704832245013676583766937255859375e-9
1.7000000000000003333533739303083665017624070969759486615657806396484375e-9
1.80000000000000040162007901756342775900776587150176055729389190673828125e-9
1.900000000000000469886784104818489016253124646027572453022003173828125e-9
2.00000000000000053815348919207355027349848342055338434875011444091796875e-9
2.1000000000000006064201942793286115307438421950791962444782257080078125e-9
2.20000000000000067468689936658367278798920096960500814020633697509765625e-9
2.3000000000000007429536044538387340452345597441308200359344482421875e-9
2.40000000000000081122030954109379530247991851865663193166255950927734375e-9
2.5000000000000008794870146283488565597252772931824438273906707763671875e-9
2.60000000000000094775371971560391781697063606770825572311878204345703125e-9
2.700000000000001016020424802858979074215994842234067618846893310546875e-9
2.80000000000000108428712989011404033146135361675987951457500457763671875e-9
2.9000000000000011525538349773691015887067123912856914103031158447265625e-9
3.00000000000000122082054006462416284595207116581150330603122711181640625e-9
3.10000000000000128908724515187922410319742994033731520175933837890625e-9
3.20000000000000135735395023913428536044278871486312709748744964599609375e-9
3.3000000000000014256206553263893466176881474893889389932155609130859375e-9
3.40000000000000149388736041364440787493350626391475088894367218017578125e-9
3.500000000000001562154065500899469132178865038440562784671783447265625e-9
3.60000000000000163042077058815453038942422381296637468039989471435546875e-9
3.7000000000000016986874756754095916466695825874921865761280059814453125e-9
3.80000000000000176695418076266465290391494136201799847185611724853515625e-9
3.900000000000001835220885849919714161160300136543810367584228515625e-9
4.00000000000000190348759093717477541840565891106962226331233978271484375e-9
4.1000000000000019717542960244298366756510176855954341590404510498046875e-9
4.20000000000000204002100111168489793289637646012124605476856231689453125e-9
4.300000000000002108287706198939959190141735234647057950496673583984375e-9
4.40000000000000217655441128619502044738709400917286984622478485107421875e-9
4.5000000000000022448211163734500817046324527836986817419528961181640625e-9
4.60000000000000231308782146070514296187781155822449363768100738525390625e-9
4.70000000000000238135452654796020421912317033275030553340911865234375e-9
4.80000000000000244962123163521526547636852910727611742913722991943359375e-9
4.9000000000000025178879367224703267336138878818019293248653411865234375e-9
5.00000000000000258615464180972538799085924665632774122059345245361328125e-9
5.100000000000002654421346896980449248104605430853553116321563720703125e-9
5.20000000000000272268805198423551050534996420537936501204967498779296875e-9
5.3000000000000027909547570714905717625953229799051769077777862548828125e-9
5.40000000000000285922146215874563301984068175443098880350589752197265625e-9
5.5000000000000029274881672460006942770860405289568006992340087890625e-9
5.60000000000000299575487233325575553433139930348261259496212005615234375e-9
5.7000000000000030640215774205108167915767580780084244906902313232421875e-9
5.80000000000000313228828250776587804882211685253423638641834259033203125e-9
5.900000000000003200554987595020939306067475627060048282146453857421875e-9
6.00000000000000326882169268227600056331283440158586017787456512451171875e-9
6.1000000000000033370883977695310618205581931761116720736026763916015625e-9
6.20000000000000340535510285678612307780355195063748396933078765869140625e-9
6.30000000000000347362180794404118433504891072516329586505889892578125e-9
6.40000000000000354188851303129624559229426949968910776078701019287109375e-9
6.5000000000000036101552181185513068495396282742149196565151214599609375e-9
6.60000000000000367842192320580636810678498704874073155224323272705078125e-9
6.700000000000003746688628293061429364030345823266543447971343994140625e-9
6.80000000000000381495533338031649062127570459779235534369945526123046875e-9
6.9000000000000038832220384675715518785210633723181672394275665283203125e-9
7.00000000000000395148874355482661313576642214684397913515567779541015625e-9
7.1000000000000040197554486420816743930117809213697910308837890625e-9
7.20000000000000408802215372933673565025713969589560292661190032958984375e-9
7.3000000000000041562888588165917969075024984704214148223400115966796875e-9
7.40000000000000422455556390384685816474785724494722671806812286376953125e-9
7.500000000000004292822268991101919421993216019473038613796234130859375e-9
7.6000000000000035339083615253293058078298827240359969437122344970703125e-9
7.70000000000000277499445405955669219366654942859895527362823486328125e-9
7.8000000000000020160805465937840785795032161331619136035442352294921875e-9
7.900000000000001257166639128011464965339882837724871933460235595703125e-9
8.0000000000000004982527316622388513511765495422878302633762359619140625e-9
8.099999999999999739338824196466237737013216246850788593292236328125e-9
8.1999999999999989804249167306936241228498829514137469232082366943359375e-9
8.299999999999998221511009264921010508686549655976705253124237060546875e-9
8.3999999999999974625971017991483968945232163605396635830402374267578125e-9
8.49999999999999670368319433337578328035988306510262191295623779296875e-9
8.5999999999999959447692868676031696661965497696655802428722381591796875e-9
8.699999999999995185855379401830556052033216474228538572788238525390625e-9
8.7999999999999944269414719360579424378698831787914969027042388916015625e-9
8.8999999999999936680275644702853288237065498833544552326202392578125e-9
8.9999999999999929091136570045127152095432165879174135625362396240234375e-9
9.099999999999992150199749538740101595379883292480371892452239990234375e-9
9.1999999999999913912858420729674879812165499970433302223682403564453125e-9
9.29999999999999063237193460719487436705321670160628855228424072265625e-9
9.3999999999999898734580271414222607528898834061692468822002410888671875e-9
9.499999999999989114544119675649647138726550110732205212116241455078125e-9
9.5999999999999883556302122098770335245632168152951635420322418212890625e-9
9.6999999999999875967163047441044199103998835198581218719482421875e-9
9.7999999999999868378023972783318062962365502244210802018642425537109375e-9
9.899999999999986078888489812559192682073216928984038531780242919921875e-9
9.9999999999999853199745823467865790679098836335469968616962432861328125e-9

6 Comments

Maybe I am missing something. 1E-10 has only 1 significant digit. 1E-10+1E-10 should give me 2E-10 and not 2.0000000000..1E-10. I can see how 1+1E-17 would give me 1 but not this scenario where all numbers are within precision
Thanks. Pretty fundamental, I think I knew this once.
The exact decimal number 1e-10 cannot be represented exactly in IEEE double precision, which represents numbers as a signed base binary mantissa times an integral power of 2. The closest IEEE double number to 1e-10, when converted to the exact decimal equivalent, is shown above:
1.0000000000000000364321973154977415791655470655996396089904010295867919921875e-10
This matches 1e-10 for 17 decimal digits, but is slightly greater than 1e-10. When you start adding this number up sequentially, the intermediate sums get differing amounts of rounding error, so the total sum at the end will not necessarily match the closest number you were expecting. E.g., take the 10th sum:
% Individually adding 10 numbers
>> num2strexact(1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10 + 1e-10)
ans =
9.9999999999999985548643831952293770104489567529526539146900177001953125e-10
% What you may have expected
>> num2strexact(1e-9)
ans =
1.0000000000000000622815914577798564188970686927859787829220294952392578125e-9
So the sum of the ten numbers did not equal the closest number to 1e-9 in the IEEE double set. That is to be expected when working with floating point arithmetic. You just need to get used to it, and use appropriate functions or coding methods if this makes a difference in your program. E.g., you have pretty much demonstrated that adding 1e-10 repeatedly is not the way to get the "best" uniform spread of numbers across a range. That is one of the reasons why function such as linspace exist.
Thanks again for the detailed answer. I followed up the links that you had posted and have come to understand this better now. The 1E-10 is a irrational number in the binary notation and leads to the error that I had posted. As per your suggestion, I think I can use linspace and iterate the elements of its vector to achive even and exact spacing for my function.
A nit on your wording. 1e-10 is not irrational in binary notation. It is the quotient of two integers, 1 / 10^10, so it is definitely rational. In decimal notation it has a representation that ends with an infinite string of 0's, and it also has a representation that ends with an infinite repeating pattern of 9's. In binary notation, however, it only has a representation that ends in a repeating pattern of "something in 1's and 0's" which I did not bother to work out for this post. It does not have a binary representation that ends in an infinite string of 0's hence the reason it cannot be represented by a finite number of digits such as IEEE double. ALL rational numbers have a representation in all base systems that end in a repeating pattern of some sort. Irrational numbers do not end in any repeating pattern and are not equal to the quotient of two integers, and that is the difference.
Thanks! Appreciate the insight

Sign in to comment.

More Answers (0)

Products

Tags

Asked:

on 21 May 2015

Commented:

on 22 May 2015

Community Treasure Hunt

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

Start Hunting!