Round-off / round-up criteria in Python
<p>I'm porting a MATLAB code to Python 3.5.1 and I found a float round-off issue.</p>

<p>In MATLAB, the following number is rounded <strong>up</strong> to the 6th decimal place:</p>

<pre><code>fprintf(1,'%f', -67.6640625);
-67.664063
</code></pre>

<p>In Python, on the other hand, the following number is rounded <strong>off</strong> to the 6th decimal place:</p>

<pre><code>print('%f' % -67.6640625)
-67.664062
</code></pre>

<p>Interestingly enough, if the number is '-67.6000625', then it is rounded <strong>up</strong> even in Python:</p>

<pre><code>print('%f' % -67.6000625)
-67.600063
</code></pre>

<p>... Why does this happen?
What are the criteria to round-off/up in Python?
(I believe this has something to do with handling hexadecimal values.)</p>

<p>More importantly, how can I prevent this difference?
I'm supposed to create a python code which can reproduce exactly the same output as MATLAB produces.</p>

<p>The reason for the python behavior has to do with how floating point numbers are stored in a computer and the standardized rounding rules defined by IEEE, which defined the standard number formats and mathematical operations used on pretty much all modern computers.</p>

<p>The need to store numbers efficiently in binary on a computer has lead computers to use floating-point numbers.  These numbers are easy for processors to work with, but have the disadvantage that many decimal numbers <a href="https://docs.python.org/3/tutorial/floatingpoint.html#representation-error" rel="nofollow">cannot be exactly represented</a>.  This results in numbers sometimes being a little off from what we think they should be.</p>

<p>The situation becomes a bit clearer if we expand the values in Python, rather than truncating them:</p>

<pre><code>&gt;&gt;&gt; print('%.20f' % -67.6640625)
-67.66406250000000000000
&gt;&gt;&gt;  print('%.20f' % -67.6000625)
-67.60006250000000704858
</code></pre>

<p>So as you can see, <code>-67.6640625</code> is a number that can be exactly represented, but <code>-67.6000625</code> isn't, it is actually a little bigger.  The default rounding mode <a href="https://en.wikipedia.org/wiki/IEEE_floating_point#Rounding_rules" rel="nofollow">defined by the IEEE stanard</a> for floating-point numbers says that anything above <code>5</code> should be rounded up, anything below should be rounded down.  So for the case of <code>-67.6000625</code>, it is actualy <code>5</code> plus a small amount, so it is rounded up.  However, in the case of <code>-67.6640625</code>, it is exactly equal to five, so a tiebreak rule comes into play.  The default tiebreaker rule is round to the nearest even number.  Since <code>2</code> is the nearest event number, it rounds down to two.</p>

<p>So Python is following the approach recommended by the floating-point standard.  The question, then, is why your version of MATLAB <em>doesn't</em> do this.  I tried it on my computer with 64bit MATLAB R2016a, and I got the same result as in Python:</p>

<pre><code>&gt;&gt; fprintf(1,'%f', -67.6640625)
-67.664062&gt;&gt;
</code></pre>

<p>So it seems like MATLAB was, at some point, using a different rounding approach (perhaps a non-standard approach, perhaps one of the alternatives specified in the standard), and has since switched to follow the same rules as everyone else.</p>

python matlab rounding