{"id":51,"date":"2006-08-23T13:52:08","date_gmt":"2006-08-23T18:52:08","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=51"},"modified":"2018-01-08T16:16:58","modified_gmt":"2018-01-08T21:16:58","slug":"a-glimpse-into-floating-point-accuracy","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2006\/08\/23\/a-glimpse-into-floating-point-accuracy\/","title":{"rendered":"A Glimpse into Floating-Point Accuracy"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>There are frequent posts on the <a>MATLAB newsgroup<\/a> as well as lots of questions posed to Technical Support about the floating point accuracy of MATLAB.  Many people think they\r\n         have found a bug when some seemingly simple arithmetic doesn't give the intuitive answer.  The issue that arises has to do\r\n         with the finite number of bits that a computational device uses to store and operate on values.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Calculator Demo<\/a><\/li>\r\n         <li><a href=\"#7\">Accuracy in MATLAB<\/a><\/li>\r\n         <li><a href=\"#9\">Using Double Precision<\/a><\/li>\r\n         <li><a href=\"#12\">Typical MATLAB Pitfall<\/a><\/li>\r\n         <li><a href=\"#14\">Conclusions<\/a><\/li>\r\n         <li><a href=\"#15\">References<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Calculator Demo<a name=\"1\"><\/a><\/h3>\r\n   <p>Have you ever impatiently waited for an elevator and continued pushing the  <tt>UP<\/tt> button in the hopes that the elevator will arrive faster?  If so, you may also have impatiently pushed buttons repetitively\r\n      on a calculator (assuming you know what a calculator is!). It's not just MATLAB that computes values in a way that seems to\r\n      defy our expectations sometimes.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">clear\r\nformat <span style=\"color: #A020F0\">long<\/span><\/pre><p>Here's what I tried.  I put the number 7 into my calculator.  I think it calculates in single precision, but I'm not sure.\r\n       It shows 7 digits after the decimal point when I take the square root, and doing it several times, I get\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">sqrts7inSingle = single([7 2.6457513 1.6265765 1.275373])<\/pre><pre style=\"font-style:oblique\">sqrts7inSingle =\r\n   7.0000000   2.6457512   1.6265765   1.2753730\r\n<\/pre><p>Next, I take the final number and square it 3 times, yielding<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">squaringSqrt7inSingle = single([1.275373  1.6265762 2.6457501 6.99999935])<\/pre><pre style=\"font-style:oblique\">squaringSqrt7inSingle =\r\n   1.2753730   1.6265762   2.6457500   6.9999995\r\n<\/pre><p>Compare the difference between the original and final values.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">sqrts7inSingle(1)-squaringSqrt7inSingle(end)<\/pre><pre style=\"font-style:oblique\">ans =\r\n   4.7683716e-007\r\n<\/pre><p>This number turns out to be very interesting in this context.  Compare it to the distance between a single precision value\r\n      of 7 and its next closest value, also know as the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/eps.html\">floating-point relative accuracy<\/a>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">eps(single(7))<\/pre><pre style=\"font-style:oblique\">ans =\r\n   4.7683716e-007\r\n<\/pre><p>We get the same value!  So, we can demonstrate the effects of finite storage size for values on a handheld calculator.  Let's\r\n      try the equivalent in MATLAB now.\r\n   <\/p>\r\n   <h3>Accuracy in MATLAB<a name=\"7\"><\/a><\/h3>\r\n   <p>Let's do a similar experiment in MATLAB using single precision so we have a similar situation to the one when I used the calculator.\r\n       In this case, I am going to keep taking the square root until the value reaches 1.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">num = single(7);\r\ncount = 0;\r\ntol = eps(<span style=\"color: #A020F0\">'single'<\/span>);\r\ndnum = sqrt(num);\r\n<span style=\"color: #0000FF\">while<\/span> abs(dnum-1)&gt;=tol\r\n    count = count+1;\r\n    dnum = sqrt(dnum);\r\n<span style=\"color: #0000FF\">end<\/span>\r\ncount<\/pre><pre style=\"font-style:oblique\">count =\r\n    23\r\n<\/pre><p>So, it took 23 iterations before we reached the number 1.  But now we're in a funny situation. There is no way to square exactly\r\n      1 and ever reach our original value of 7.\r\n   <\/p>\r\n   <h3>Using Double Precision<a name=\"9\"><\/a><\/h3>\r\n   <p>Let's repeat the same experiment from the calculator in MATLAB using double precision.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">num = 7;\r\nsqrtd = sqrt(num);\r\nsqrtd(2) = sqrt(sqrtd(1));\r\nsqrtd(3) = sqrt(sqrtd(2))\r\nprods(1) = sqrtd(end);\r\nprods(2) = prods(1)^2;\r\nprods(3) = prods(2)^2\r\nfinalNum = prods(3)^2<\/pre><pre style=\"font-style:oblique\">sqrtd =\r\n   2.64575131106459   1.62657656169779   1.27537310685845\r\nprods =\r\n   1.27537310685845   1.62657656169779   2.64575131106459\r\nfinalNum =\r\n   7.00000000000001\r\n<\/pre><p>Find the difference between <tt>finalNum<\/tt> and <tt>num<\/tt> and compare to the proper relative floating-point accuracy:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">diffNum = finalNum-num\r\nacc = eps(num)*6\r\ndiffNum-acc<\/pre><pre style=\"font-style:oblique\">diffNum =\r\n    5.329070518200751e-015\r\nacc =\r\n    5.329070518200751e-015\r\nans =\r\n     0\r\n<\/pre><p>Why did I use 6 when I calculated <tt>acc<\/tt>?  Because I performed 6 floating point operations to get the my final answer, 3 <tt>sqrt<\/tt> applications, followed by squaring the answers 3 times.\r\n   <\/p>\r\n   <h3>Typical MATLAB Pitfall<a name=\"12\"><\/a><\/h3>\r\n   <p>The most common MATLAB pitfall I run across is when users check equality of values generated from the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/colon.html\"><tt>:<\/tt> operator<\/a>. The code starts innocently enough.  I've actually turned the logic around here a bit, so we will print out values in the\r\n      loop where the loop counter may not be exactly what the user expects.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">format <span style=\"color: #A020F0\">short<\/span>\r\n<span style=\"color: #0000FF\">for<\/span> ind = 0:.1:1;\r\n    <span style=\"color: #0000FF\">if<\/span> ind ~= fix(10*ind)\/10\r\n        disp(ind - fix(10*ind)\/10)\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><pre style=\"font-style:oblique\">  5.5511e-017\r\n  1.1102e-016\r\n  1.1102e-016\r\n<\/pre><p>And then the question is, why do <i>any<\/i> of the values print out?  It's because computers can't represent all numbers exactly given a fixed storage size such as double\r\n      precision.\r\n   <\/p>\r\n   <h3>Conclusions<a name=\"14\"><\/a><\/h3>\r\n   <p>This was a very simplified explanation about floating point, but one, I hope, that is easily understood. <a href=\"?p=51#respond\">Let me know.<\/a><\/p>\r\n   <h3>References<a name=\"15\"><\/a><\/h3>\r\n   <p>Here are some pointers to more resources.<\/p>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/content\/dam\/mathworks\/mathworks-dot-com\/company\/newsletters\/news_notes\/pdf\/Fall96Cleve.pdf\">Cleve's newsletter article<\/a><\/li>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/support\/solutions\/data\/1-16FOQ.html?solution=1-16FOQ\">How do I tell if the error in my answer is the result of round-off error or a bug?<\/a><\/li>\r\n         <li><a href=\"https:\/\/www.mathworks.com\/moler.html\"> Numerical Computing with MATLAB, Cleve's book<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n##### SOURCE BEGIN #####\r\n%% A Glimpse into Floating Point Accuracy\r\n% There are frequent posts on the\r\n% <http:\/\/.html MATLAB newsgroup>\r\n% as well as lots of questions posed to Technical Support about the\r\n% floating point accuracy of MATLAB.  Many people think they have found a\r\n% bug when some seemingly simple arithmetic doesn't give the intuitive\r\n% answer.  The issue that arises has to do with the finite number of bits\r\n% that a computational device uses to store and operate on values.  \r\n%% Calculator Demo\r\n% Have you ever impatiently waited for an elevator and continued pushing\r\n% the  |UP| button in the hopes that the elevator will arrive faster?  If\r\n% so, you may also have impatiently pushed buttons repetitively on a\r\n% calculator (assuming you know what a calculator is!).  \r\n% It's not just MATLAB that computes values in a way that seems to defy our\r\n% expectations sometimes.\r\nclear\r\nformat long\r\n%%\r\n% Here's what I tried.  I put the number 7 into my calculator.  I think it\r\n% calculates in single precision, but I'm not sure.  It shows 7 digits\r\n% after the decimal point when I take the square root, and doing it several\r\n% times, I get\r\nsqrts7inSingle = single([7 2.6457513 1.6265765 1.275373])\r\n%%\r\n% Next, I take the final number and square it 3 times, yielding\r\nsquaringSqrt7inSingle = single([1.275373  1.6265762 2.6457501 6.99999935])\r\n%%\r\n% Compare the difference between the original and final values.\r\nsqrts7inSingle(1)-squaringSqrt7inSingle(end)\r\n%%\r\n% This number turns out to be very interesting in this context.  Compare it\r\n% to the distance between a single precision value of 7 and its next\r\n% closest value, also know as the \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/eps.html floating-point relative accuracy>.\r\n%\r\neps(single(7))\r\n%%\r\n% We get the same value!  So, we can demonstrate the effects of finite storage\r\n% size for values on a handheld calculator.  Let's try the equivalent in\r\n% MATLAB now.\r\n\r\n%% Accuracy in MATLAB\r\n% Let's do a similar experiment in MATLAB using single precision so we have\r\n% a similar situation to the one when I used the calculator.  In this case, I\r\n% am going to keep taking the square root until the value reaches 1.\r\nnum = single(7);\r\ncount = 0;\r\ntol = eps('single');\r\ndnum = sqrt(num);\r\nwhile abs(dnum-1)>=tol\r\n    count = count+1;\r\n    dnum = sqrt(dnum);\r\nend\r\ncount\r\n%% \r\n% So, it took 23 iterations before we reached the number 1.  But now we're\r\n% in a funny situation. There is no way to square exactly 1 and ever reach\r\n% our original value of 7.\r\n%% Using Double Precision\r\n% Let's repeat the same experiment from the calculator in MATLAB using\r\n% double precision.\r\nnum = 7;\r\nsqrtd = sqrt(num);\r\nsqrtd(2) = sqrt(sqrtd(1));\r\nsqrtd(3) = sqrt(sqrtd(2))\r\nprods(1) = sqrtd(end);\r\nprods(2) = prods(1)^2;\r\nprods(3) = prods(2)^2\r\nfinalNum = prods(3)^2\r\n%%\r\n% Find the difference between |finalNum| and |num| and compare to the\r\n% proper relative floating-point accuracy:\r\ndiffNum = finalNum-num\r\nacc = eps(num)*6\r\ndiffNum-acc\r\n%%\r\n% Why did I use 6 when I calculated |acc|?  Because I performed 6 floating\r\n% point operations to get the my final answer, 3 |sqrt| applications,\r\n% followed by squaring the answers 3 times.\r\n%% Typical MATLAB Pitfall\r\n% The most common MATLAB pitfall I run across is when users check equality\r\n% of values generated from the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/colon.html |:| operator>.\r\n% The code starts innocently enough.  I've actually turned the logic around\r\n% here a bit, so we will print out values in the loop where the loop\r\n% counter may not be exactly what the user expects.\r\nformat short\r\nfor ind = 0:.1:1;\r\n    if ind ~= fix(10*ind)\/10\r\n        disp(ind - fix(10*ind)\/10)\r\n    end\r\nend\r\n%%\r\n% And then the question is, why do _any_ of the values print out?  It's\r\n% because computers can't represent all numbers exactly given a fixed\r\n% storage size such as double precision.\r\n%% Conclusions\r\n% This was a very simplified explanation about floating point, but one, I\r\n% hope, that is easily understood. <?p=51#respond Let me know.>  \r\n%% References\r\n% Here are some pointers to more\r\n% resources.\r\n%\r\n% * <https:\/\/www.mathworks.com\/content\/dam\/mathworks\/mathworks-dot-com\/company\/newsletters\/news_notes\/pdf\/Fall96Cleve.pdf Cleve's newsletter article>\r\n% * <https:\/\/www.mathworks.com\/support\/solutions\/data\/1-16FOQ.html?solution=1-16FOQ How do I tell if the error in my answer is the result of round-off error or a bug?>\r\n% * <https:\/\/www.mathworks.com\/moler.html  Numerical Computing with MATLAB, Cleve's book>\r\n\r\n\r\n##### SOURCE END #####\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      There are frequent posts on the MATLAB newsgroup as well as lots of questions posed to Technical Support about the floating point accuracy of MATLAB.  Many people think they\r\n        ... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/08\/23\/a-glimpse-into-floating-point-accuracy\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/51"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=51"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/51\/revisions"}],"predecessor-version":[{"id":2622,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/51\/revisions\/2622"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=51"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=51"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=51"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}