{"id":2425,"date":"2017-04-10T12:00:51","date_gmt":"2017-04-10T17:00:51","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=2425"},"modified":"2017-04-09T15:28:29","modified_gmt":"2017-04-09T20:28:29","slug":"bank-format-and-metric-socket-wrenches","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2017\/04\/10\/bank-format-and-metric-socket-wrenches\/","title":{"rendered":"Bank Format and Metric Socket Wrenches"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>A report about a possible bug in <tt>format bank<\/tt> and a visit to a local hardware store made me realize that doing decimal arithmetic with binary floating point numbers is like tightening a European bolt with an American socket wrench.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#a71cc5e2-f167-4e23-bf4b-38ad283df287\">Tax Time<\/a><\/li><li><a href=\"#91505242-3086-47df-9eb3-b84595ae7afb\">Breaking Ties<\/a><\/li><li><a href=\"#ac5f9dcf-15ce-48a8-bed1-e9fafa8b5daf\">None of the above.<\/a><\/li><li><a href=\"#a060bc51-4ca7-4075-8b62-01f2d92c3401\">Symbolic Toolbox<\/a><\/li><li><a href=\"#ccb8f488-efe8-4b4d-8572-e6009c90d219\">Socket Wrenches<\/a><\/li><li><a href=\"#a2d4b74d-f7a4-482d-993b-350f0c33b52d\">10 millimeters<\/a><\/li><li><a href=\"#79ec4004-f8ff-4ce9-8925-2470a78ee898\">One-tenth<\/a><\/li><\/ul><\/div><h4>Tax Time<a name=\"a71cc5e2-f167-4e23-bf4b-38ad283df287\"><\/a><\/h4><p>It's mid-April and so those of us who file United States income taxes have that chore to do.  Years ago, I used MATLAB to help with my taxes.  I had a program named <tt>form1040.m<\/tt> that had one statement for each line on the tax form.  I just had to enter my income and deductions.  Then MATLAB would do all the arithmetic.<\/p><p>If we're really meticulous about our financial records, we keep track of things to the nearest penny.  So line 28 of <tt>form1040<\/tt> might have been something like<\/p><pre class=\"codeinput\">   interest = 48.35\r\n<\/pre><pre class=\"codeoutput\">interest =\r\n   48.3500\r\n<\/pre><p>I didn't like those trailing zeros in the output.  So I introduced<\/p><pre class=\"codeinput\">   format <span class=\"string\">bank<\/span>\r\n<\/pre><p>into MATLAB.  Now<\/p><pre class=\"codeinput\">   interest\r\n<\/pre><pre class=\"codeoutput\">interest =\r\n         48.35\r\n<\/pre><p>is printed with just two digits after the decimal point.<\/p><p><tt>format bank<\/tt> has turned out to be useful more broadly and is still in today's MATLAB.<\/p><h4>Breaking Ties<a name=\"91505242-3086-47df-9eb3-b84595ae7afb\"><\/a><\/h4><p>We recently had a user ask about the rounding rule employed by <tt>format bank<\/tt>.  What if a value fails halfway between two possible outputs?  Which is chosen and why?<\/p><p>Here's the example that prompted the user's query.  Start with<\/p><pre class=\"codeinput\">   format <span class=\"string\">short<\/span>\r\n<\/pre><p>so we can see four decimal places.<\/p><pre class=\"codeinput\">   x = (5:10:45)'\/1000\r\n\r\n   y = 1+x\r\n\r\n   z = 2+x\r\n<\/pre><pre class=\"codeoutput\">x =\r\n    0.0050\r\n    0.0150\r\n    0.0250\r\n    0.0350\r\n    0.0450\r\ny =\r\n    1.0050\r\n    1.0150\r\n    1.0250\r\n    1.0350\r\n    1.0450\r\nz =\r\n    2.0050\r\n    2.0150\r\n    2.0250\r\n    2.0350\r\n    2.0450\r\n<\/pre><p>These values appear to fall halfway between pairs of two-digit decimal fractions.  Let's see how the ties are broken.<\/p><pre class=\"codeinput\">   format <span class=\"string\">bank<\/span>\r\n\r\n   x\r\n\r\n   y\r\n\r\n   z\r\n<\/pre><pre class=\"codeoutput\">x =\r\n          0.01\r\n          0.01\r\n          0.03\r\n          0.04\r\n          0.04\r\ny =\r\n          1.00\r\n          1.01\r\n          1.02\r\n          1.03\r\n          1.04\r\nz =\r\n          2.00\r\n          2.02\r\n          2.02\r\n          2.04\r\n          2.04\r\n<\/pre><p>Look at the last digits. What mysterious hand is at work here?  Three of the <tt>x<\/tt>'s, <tt>x(1)<\/tt>, <tt>x(3)<\/tt>, and <tt>x(4)<\/tt>, have been rounded up.  None of the <tt>y<\/tt>'s have been rounded up.  Two of the <tt>z<\/tt>'s, <tt>z(2)<\/tt> and <tt>z(4)<\/tt>, have been rounded up.<\/p><p>Email circulated internally at MathWorks for a few days after this was reported suggesting various explanations. Is it a bug in <tt>format bank<\/tt>?  In the I\/O library? Does it depend upon which compiler was used to build MATLAB? Do we see the same behavior on the PC and the Mac?  Has it always been this way?  These are the usual questions that we ask ourselves when we see curious behavior.<\/p><p>Do you know what's happening?<\/p><h4>None of the above.<a name=\"ac5f9dcf-15ce-48a8-bed1-e9fafa8b5daf\"><\/a><\/h4><p>Well, none of the suspects I just mentioned is the culprit. The fact is none of the numbers fall exactly on a midpoint. Think binary, not decimal.  A value like 0.005 expressed as a decimal fraction cannot be represented exactly as a binary floating point number.  Decimal fractions fall in between the binary fractions, and rarely fall precisely half way.<\/p><h4>Symbolic Toolbox<a name=\"a060bc51-4ca7-4075-8b62-01f2d92c3401\"><\/a><\/h4><p>To understand what is going on, the Symbolic Toolbox function<\/p><pre>  sym(x,'e')<\/pre><p>is your friend.  The <tt>'e'<\/tt> flag is provided for this purpose.  The <tt>help<\/tt> entry says<\/p><pre>  'e' stands for 'estimate error'.  The 'r' form is supplemented by a\r\n  term involving the variable 'eps' which estimates the difference\r\n  between the theoretical rational expression and its actual floating\r\n  point value.  For example, sym(3*pi\/4,'e') is 3*pi\/4-103*eps\/249.<\/pre><p>To see how this works for the situation encountered here.<\/p><pre class=\"codeinput\">   symx = sym(x,<span class=\"string\">'e'<\/span>)\r\n\r\n   symy = sym(y,<span class=\"string\">'e'<\/span>)\r\n\r\n   symz = sym(z,<span class=\"string\">'e'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">symx =\r\n    eps\/2133 + 1\/200\r\n     3\/200 - eps\/400\r\n      eps\/160 + 1\/40\r\n (3*eps)\/200 + 7\/200\r\n 9\/200 - (3*eps)\/400\r\nsymy =\r\n 201\/200 - (12*eps)\/25\r\n 203\/200 - (11*eps)\/25\r\n     41\/40 - (2*eps)\/5\r\n  207\/200 - (9*eps)\/25\r\n  209\/200 - (8*eps)\/25\r\nsymz =\r\n 401\/200 - (12*eps)\/25\r\n (14*eps)\/25 + 403\/200\r\n     81\/40 - (2*eps)\/5\r\n (16*eps)\/25 + 407\/200\r\n  409\/200 - (8*eps)\/25\r\n<\/pre><p>The output is not as clear as I would like to see it, but I can pick off the sign of the error terms and find<\/p><pre>  x  + - + + -\r\n  y  - - - - -\r\n  z  - + - + -<\/pre><p>Or, I can compute the signs with<\/p><pre class=\"codeinput\">   format <span class=\"string\">short<\/span>\r\n\r\n   sigx =  sign(double(symx - x))\r\n\r\n   sigy =  sign(double(symy - y))\r\n\r\n   sigz =  sign(double(symz - z))\r\n<\/pre><pre class=\"codeoutput\">sigx =\r\n     1\r\n    -1\r\n     1\r\n     1\r\n    -1\r\nsigy =\r\n    -1\r\n    -1\r\n    -1\r\n    -1\r\n    -1\r\nsigz =\r\n    -1\r\n     1\r\n    -1\r\n     1\r\n    -1\r\n<\/pre><p>The sign of the error term tells us whether the floating point numbers stored in <tt>x<\/tt>, <tt>y<\/tt> and <tt>z<\/tt> are larger or smaller than the anticipated decimal fractions. After this initial input, there is essentially no more roundoff error. <tt>format bank<\/tt> will round up or down from the decimal value accordingly. Again, it is just doing its job on the input it is given.<\/p><h4>Socket Wrenches<a name=\"ccb8f488-efe8-4b4d-8572-e6009c90d219\"><\/a><\/h4><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/Craftsman-Max-Axess-Universal-Socket-Set.jpg\" alt=\"\"> <\/p><p>Photo credit: <a href=\"http:\/\/toolguyd.com\/\">http:\/\/toolguyd.com\/<\/a><\/p><p>A high-end socket wrench set includes both metric (left) and fractional inch (right) sizes.  Again, think decimal and binary.  Metric sizes of nuts and bolts and wrenches are specified in decimal fractions, while the denominators in fractional inch sizes are powers of two.<\/p><p>Conversion charts between the metric and fractional inch standards abound on the internet.  Here is a link to one of them: <a href=\"http:\/\/www.engineeringtoolbox.com\/wrenches-inches-metric-us-conversion-comparison-d_1607.html\">Wrench Conversion Chart<\/a>.<\/p><p>But we can easily compute our own conversion chart.  And in the process compute <tt>delta<\/tt>, the relative error made when the closest binary wrench is used on a decimal bolt.<\/p><pre class=\"codeinput\">   make_chart\r\n<\/pre><pre class=\"codeoutput\">          Inch              Metric       delta\r\n      1\/64    0.016\r\n      1\/32    0.031\r\n      3\/64    0.047      1mm   0.039    -0.191\r\n      1\/16    0.063\r\n      5\/64    0.078      2mm   0.079     0.008\r\n      3\/32    0.094\r\n      7\/64    0.109\r\n      1\/8     0.125      3mm   0.118    -0.058\r\n      9\/64    0.141\r\n      5\/32    0.156      4mm   0.157     0.008\r\n     11\/64    0.172\r\n      3\/16    0.188\r\n     13\/64    0.203      5mm   0.197    -0.032\r\n      7\/32    0.219\r\n     15\/64    0.234      6mm   0.236     0.008\r\n      1\/4     0.250\r\n      9\/32    0.281      7mm   0.276    -0.021\r\n      5\/16    0.313      8mm   0.315     0.008\r\n     11\/32    0.344      9mm   0.354     0.030\r\n      3\/8     0.375\r\n     13\/32    0.406     10mm   0.394    -0.032\r\n      7\/16    0.438\r\n     15\/32    0.469     12mm   0.472     0.008\r\n      1\/2     0.500\r\n      9\/16    0.563     14mm   0.551    -0.021\r\n      5\/8     0.625     16mm   0.630     0.008\r\n     11\/16    0.688     18mm   0.709     0.030\r\n      3\/4     0.750\r\n     13\/16    0.813     20mm   0.787    -0.032\r\n      7\/8     0.875     22mm   0.866    -0.010\r\n     15\/16    0.938     24mm   0.945     0.008\r\n       1      1.000\r\n<\/pre><p>Let's plot those relative errors.  Except for the small sizes, where this set doesn't have enough wrenches, the relative error is only a few percent.  But that's still enough to produce a damaging fit on a tight nut.<\/p><pre class=\"codeinput\">   bar(k,d)\r\n   axis([0 25 -.05 .05])\r\n   xlabel(<span class=\"string\">'millimeters'<\/span>)\r\n   ylabel(<span class=\"string\">'delta'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/sockets_01.png\" alt=\"\"> <p>You might notice that my conversion chart, like all such charts, and like the wrenches themselves, has a little bit of floating point character.  The spacing of the entries is not uniform.  The spacing between the binary values is 1\/64, then 1\/32, then 1\/16.  The spacing of the metric values is 1mm at the top of the chart and 2mm later on.<\/p><h4>10 millimeters<a name=\"a2d4b74d-f7a4-482d-993b-350f0c33b52d\"><\/a><\/h4><p>Suppose we want to tighten a 10mm nut and all we have are binary wrenches. The diameter of the nut in inches is<\/p><pre class=\"codeinput\">   meter = 39.370079;\r\n   d = 10*meter\/1000\r\n<\/pre><pre class=\"codeoutput\">d =\r\n    0.3937\r\n<\/pre><p>Consulting our chart, we see that a 13\/32 wrench is the best fit, but it's a little too large.  10mm lies between these two binary values.<\/p><pre class=\"codeinput\">   [floor(32*d) ceil(32*d)]\r\n   b1 = 12\/32;\r\n   b2 = 13\/32;\r\n   [b1 d b2]'\r\n<\/pre><pre class=\"codeoutput\">ans =\r\n    12    13\r\nans =\r\n    0.3750\r\n    0.3937\r\n    0.4063\r\n<\/pre><p>The fraction of the interval is<\/p><pre class=\"codeinput\">   f = (d - b1)\/(b2 - b1)\r\n<\/pre><pre class=\"codeoutput\">f =\r\n    0.5984\r\n<\/pre><p>10mm is about 60% of the way from 12\/32 inches to 13\/32 inches.<\/p><h4>One-tenth<a name=\"79ec4004-f8ff-4ce9-8925-2470a78ee898\"><\/a><\/h4><p>Now let's turn to floating point numbers. What happens when execute this MATLAB statement?<\/p><pre class=\"codeinput\">   x = 1\/10\r\n<\/pre><pre class=\"codeoutput\">x =\r\n    0.1000\r\n<\/pre><p>One is divided by ten and the closest floating point number is stored in <tt>x<\/tt>.  The same value is produced by the statement<\/p><pre class=\"codeinput\">   x = 0.1\r\n<\/pre><pre class=\"codeoutput\">x =\r\n    0.1000\r\n<\/pre><p>The resulting <tt>x<\/tt> lies in the interval between 1\/16 and 1\/8. The floating point numbers in this interval are uniformly spaced with a separation of<\/p><pre class=\"codeinput\">   e = eps(1\/16)\r\n<\/pre><pre class=\"codeoutput\">e =\r\n   1.3878e-17\r\n<\/pre><p>This is <tt>2^-56<\/tt>.  Let<\/p><pre class=\"codeinput\">   e = sym(e)\r\n<\/pre><pre class=\"codeoutput\">e =\r\n1\/72057594037927936\r\n<\/pre><p>This value <tt>e<\/tt> plays the role that 1\/64 plays for my wrenches.<\/p><p>The result of <tt>x = 1\/10<\/tt> lies between these two binary fractions.<\/p><pre class=\"codeinput\">   b1 = floor(1\/(10*e))*e\r\n   b2 = ceil(1\/(10*e))*e\r\n<\/pre><pre class=\"codeoutput\">b1 =\r\n7205759403792793\/72057594037927936\r\nb2 =\r\n3602879701896397\/36028797018963968\r\n<\/pre><p>The tiny interval of length <tt>e<\/tt> is<\/p><pre class=\"codeinput\">   c = [b1 1\/10 b2]'\r\n<\/pre><pre class=\"codeoutput\">c =\r\n 7205759403792793\/72057594037927936\r\n                               1\/10\r\n 3602879701896397\/36028797018963968\r\n<\/pre><p>In decimal<\/p><pre class=\"codeinput\">   vpa(c)\r\n<\/pre><pre class=\"codeoutput\">ans =\r\n 0.099999999999999991673327315311326\r\n                                 0.1\r\n  0.10000000000000000555111512312578\r\n<\/pre><p>Where in this interval does 1\/10 lie?<\/p><pre class=\"codeinput\">   f = double((1\/10 - b1)\/e)\r\n<\/pre><pre class=\"codeoutput\">f =\r\n    0.6000\r\n<\/pre><p>So 1\/10 is about 60% of the way from <tt>b1<\/tt> to <tt>b2<\/tt> and so is closer to <tt>b2<\/tt> than to <tt>b1<\/tt>.  The two statements<\/p><pre class=\"codeinput\">    x = 1\/10\r\n\r\n    x = double(b2)\r\n<\/pre><pre class=\"codeoutput\">x =\r\n    0.1000\r\nx =\r\n    0.1000\r\n<\/pre><p>store exactly the same value in <tt>x<\/tt>.<\/p><p>The 13\/32 wrench is the closest tool in the binary collection to the 10mm nut.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_e7a69dc0fbce44ddbf028f28e4a1a71b() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='e7a69dc0fbce44ddbf028f28e4a1a71b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' e7a69dc0fbce44ddbf028f28e4a1a71b';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2017 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_e7a69dc0fbce44ddbf028f28e4a1a71b()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2017a<br><\/p><\/div><!--\r\ne7a69dc0fbce44ddbf028f28e4a1a71b ##### SOURCE BEGIN #####\r\n%% Bank Format and Metric Socket Wrenches\r\n% A report about a possible bug in |format bank| and a visit to a local \r\n% hardware store made me realize that doing decimal arithmetic with\r\n% binary floating point numbers is like tightening a European bolt\r\n% with an American socket wrench.\r\n\r\n%% Tax Time\r\n% It's mid-April and so those of us who file United States\r\n% income taxes have that chore to do.  Years ago, I used MATLAB\r\n% to help with my taxes.  I had a program named |form1040.m| that had one\r\n% statement for each line on the tax form.  I just had to enter my income\r\n% and deductions.  Then MATLAB would do all the arithmetic.\r\n\r\n%%\r\n% If we're really meticulous about our financial records, we keep track\r\n% of things to the nearest penny.  So line 28 of |form1040|\r\n% might have been something like\r\n\r\n   interest = 48.35\r\n   \r\n%%\r\n% I didn't like those trailing zeros in the output.  So I introduced\r\n\r\n   format bank\r\n   \r\n%%\r\n% into MATLAB.  Now\r\n\r\n   interest \r\n   \r\n%%\r\n% is printed with just two digits after the decimal point.\r\n\r\n%%\r\n% |format bank| has turned out to be useful more broadly and is still\r\n% in today's MATLAB.\r\n\r\n%% Breaking Ties\r\n% We recently had a user ask about the rounding rule employed by\r\n% |format bank|.  What if a value fails halfway between two possible\r\n% outputs?  Which is chosen and why?\r\n\r\n%%\r\n% Here's the example that prompted the user's query.  Start with\r\n\r\n   format short\r\n   \r\n%%\r\n% so we can see four decimal places.\r\n\r\n   x = (5:10:45)'\/1000\r\n   \r\n   y = 1+x\r\n   \r\n   z = 2+x\r\n   \r\n%%\r\n% These values appear to fall halfway between pairs of two-digit decimal\r\n% fractions.  Let's see how the ties are broken.\r\n\r\n   format bank\r\n   \r\n   x\r\n   \r\n   y\r\n   \r\n   z\r\n   \r\n%%\r\n% Look at the last digits.\r\n% What mysterious hand is at work here?  Three of the |x|'s,\r\n% |x(1)|, |x(3)|, and |x(4)|, have been rounded up.  None of the |y|'s\r\n% have been rounded up.  Two of the |z|'s, |z(2)| and |z(4)|,\r\n% have been rounded up.\r\n  \r\n%%\r\n% Email circulated internally at MathWorks for a few days after this was\r\n% reported suggesting various explanations.\r\n% Is it a bug in |format bank|?  In the I\/O library?\r\n% Does it depend upon which compiler was used to build MATLAB?\r\n% Do we see the same behavior on the PC and the Mac?  Has it always\r\n% been this way?  These are the usual questions that we ask ourselves\r\n% when we see curious behavior.\r\n\r\n%%\r\n% Do you know what's happening?\r\n\r\n%% None of the above.\r\n% Well, none of the suspects I just mentioned is the culprit.\r\n% The fact is none of the numbers fall exactly on a midpoint.\r\n% Think binary, not decimal.  A value like 0.005 expressed as a \r\n% decimal fraction cannot be represented exactly as a binary floating\r\n% point number.  Decimal fractions fall in between the binary fractions,\r\n% and rarely fall precisely half way.\r\n\r\n%% Symbolic Toolbox\r\n% To understand what is going on, the Symbolic Toolbox function\r\n%\r\n%    sym(x,'e')\r\n% \r\n% is your friend.  The |'e'| flag is provided for this purpose.  The\r\n% |help| entry says\r\n%\r\n%    'e' stands for 'estimate error'.  The 'r' form is supplemented by a\r\n%    term involving the variable 'eps' which estimates the difference\r\n%    between the theoretical rational expression and its actual floating\r\n%    point value.  For example, sym(3*pi\/4,'e') is 3*pi\/4-103*eps\/249.\r\n\r\n%%\r\n% To see how this works for the situation encountered here.\r\n\r\n   symx = sym(x,'e') \r\n   \r\n   symy = sym(y,'e')\r\n   \r\n   symz = sym(z,'e')\r\n \r\n%%\r\n% The output is not as clear as I would like to see it, but I can pick \r\n% off the sign of the error terms and find\r\n% \r\n%    x  + - + + -\r\n%    y  - - - - -\r\n%    z  - + - + -\r\n\r\n%%\r\n% Or, I can compute the signs with\r\n\r\n   format short\r\n\r\n   sigx =  sign(double(symx - x))\r\n  \r\n   sigy =  sign(double(symy - y))\r\n  \r\n   sigz =  sign(double(symz - z))\r\n   \r\n%%\r\n% The sign of the error term tells us whether the floating point numbers \r\n% stored in |x|, |y| and |z|\r\n% are larger or smaller than the anticipated decimal fractions.\r\n% After this initial input, there is essentially no more roundoff error.\r\n% |format bank| will round up or down from the decimal value accordingly.\r\n% Again, it is just doing its job on the input it is given.\r\n\r\n%% Socket Wrenches\r\n% <<Craftsman-Max-Axess-Universal-Socket-Set.jpg>>\r\n%\r\n% Photo credit: http:\/\/toolguyd.com\/\r\n\r\n%%\r\n% A high-end socket wrench set includes both metric (left) and fractional\r\n% inch (right) sizes.  Again, think decimal and binary.  Metric sizes of\r\n% nuts and bolts and wrenches are specified in decimal fractions, while\r\n% the denominators in fractional inch sizes are powers of two.\r\n\r\n%%\r\n% Conversion charts between the metric and fractional inch standards\r\n% abound on the internet.  Here is a link to one of them:\r\n% <http:\/\/www.engineeringtoolbox.com\/wrenches-inches-metric-us-conversion-comparison-d_1607.html\r\n% Wrench Conversion Chart>.\r\n\r\n%%\r\n% But we can easily compute our own conversion chart.  And in the process\r\n% compute |delta|, the relative error made when the closest binary\r\n% wrench is used on a decimal bolt.\r\n\r\n   make_chart\r\n   \r\n%%\r\n% Let's plot those relative errors.  Except for the small sizes, where\r\n% this set doesn't have enough wrenches, the relative error is only a few\r\n% percent.  But that's still enough to produce a damaging fit on a tight\r\n% nut.\r\n\r\n   bar(k,d)\r\n   axis([0 25 -.05 .05])\r\n   xlabel('millimeters')\r\n   ylabel('delta')\r\n   \r\n%%\r\n% You might notice that my conversion chart, like all such charts,\r\n% and like the wrenches themselves,\r\n% has a little bit of floating point character.  The spacing of the\r\n% entries is not uniform.  The spacing between the binary values\r\n% is 1\/64, then 1\/32, then 1\/16.  The spacing of the metric values\r\n% is 1mm at the top of the chart and 2mm later on.\r\n\r\n%% 10 millimeters\r\n% Suppose we want to tighten a 10mm nut and all we have are binary\r\n% wrenches. The diameter of the nut in inches is\r\n\r\n   meter = 39.370079;   \r\n   d = 10*meter\/1000\r\n   \r\n%%\r\n% Consulting our chart, we see that a 13\/32 wrench is the best fit, but\r\n% it's a little too large.  10mm lies between these two binary values.\r\n   \r\n   [floor(32*d) ceil(32*d)]    \r\n   b1 = 12\/32;\r\n   b2 = 13\/32;\r\n   [b1 d b2]'\r\n   \r\n%%\r\n% The fraction of the interval is\r\n\r\n   f = (d - b1)\/(b2 - b1)\r\n   \r\n%%\r\n% 10mm is about 60% of the way from 12\/32 inches to 13\/32 inches.\r\n\r\n\r\n%% One-tenth\r\n% Now let's turn to floating point numbers.\r\n% What happens when execute this MATLAB statement?\r\n\r\n   x = 1\/10\r\n   \r\n%%\r\n% One is divided by ten and the closest floating point number is\r\n% stored in |x|.  The same value is produced by the statement\r\n\r\n   x = 0.1\r\n   \r\n%%\r\n% The resulting |x| lies in the interval between 1\/16 and 1\/8.\r\n% The floating point numbers in this interval are uniformly spaced\r\n% with a separation of \r\n\r\n   e = eps(1\/16)\r\n   \r\n%%\r\n% This is |2^-56|.  Let\r\n\r\n   e = sym(e)\r\n   \r\n%%\r\n% This value |e| plays the role that 1\/64 plays for my wrenches.\r\n\r\n%%\r\n% The result of |x = 1\/10| lies between these two binary fractions.\r\n\r\n   b1 = floor(1\/(10*e))*e\r\n   b2 = ceil(1\/(10*e))*e\r\n   \r\n%%\r\n% The tiny interval of length |e| is\r\n\r\n   c = [b1 1\/10 b2]'\r\n   \r\n%%\r\n% In decimal\r\n\r\n   vpa(c)\r\n   \r\n%% \r\n% Where in this interval does 1\/10 lie?\r\n\r\n   f = double((1\/10 - b1)\/e)\r\n   \r\n%%\r\n% So 1\/10 is about 60% of the way from |b1| to |b2| and so is closer\r\n% to |b2| than to |b1|.  The two statements\r\n\r\n    x = 1\/10\r\n    \r\n    x = double(b2)\r\n    \r\n%%\r\n% store exactly the same value in |x|.\r\n\r\n%%\r\n% The 13\/32 wrench is the closest tool in the binary collection to\r\n% the 10mm nut.\r\n\r\n\r\n   \r\n##### SOURCE END ##### e7a69dc0fbce44ddbf028f28e4a1a71b\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/Craftsman-Max-Axess-Universal-Socket-Set.jpg\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction--><p>A report about a possible bug in <tt>format bank<\/tt> and a visit to a local hardware store made me realize that doing decimal arithmetic with binary floating point numbers is like tightening a European bolt with an American socket wrench.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2017\/04\/10\/bank-format-and-metric-socket-wrenches\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":2427,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,16,7],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2425"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/comments?post=2425"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2425\/revisions"}],"predecessor-version":[{"id":2431,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2425\/revisions\/2431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media\/2427"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=2425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=2425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=2425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}