Why does the floating-point value of 4*0.1 look nice in Python 3 but 3*0.1 doesn't?
<p>I know that most decimals don't have an exact floating point representation (<a href="http://stackoverflow.com/questions/588004">Is floating point math broken?</a>).</p>

<p>But I don't see why <code>4*0.1</code> is printed nicely as <code>0.4</code>, but <code>3*0.1</code> isn't, when
both values actually have ugly decimal representations:</p>

<pre><code>&gt;&gt;&gt; 3*0.1
0.30000000000000004
&gt;&gt;&gt; 4*0.1
0.4
&gt;&gt;&gt; from decimal import Decimal
&gt;&gt;&gt; Decimal(3*0.1)
Decimal('0.3000000000000000444089209850062616169452667236328125')
&gt;&gt;&gt; Decimal(4*0.1)
Decimal('0.40000000000000002220446049250313080847263336181640625')
</code></pre>

<p><code>repr</code> (and <code>str</code> in Python 3) will put out as many digits as required to make the value unambiguous. In this case the result of the multiplication <code>3*0.1</code> isn't the closest value to 0.3 (0x1.3333333333333p-2 in hex), it's actually one LSB higher (0x1.3333333333334p-2) so it needs more digits to distinguish it from 0.3.</p>

<p>On the other hand, the multiplication <code>4*0.1</code> <em>does</em> get the closest value to 0.4 (0x1.999999999999ap-2 in hex), so it doesn't need any additional digits.</p>

<p>You can verify this quite easily:</p>

<pre><code>&gt;&gt;&gt; 3*0.1 == 0.3
False
&gt;&gt;&gt; 4*0.1 == 0.4
True
</code></pre>

<p>I used hex notation above because it's nice and compact and shows the bit difference between the two values. You can do this yourself using e.g. <code>(3*0.1).hex()</code>. If you'd rather see them in all their decimal glory, here you go:</p>

<pre><code>&gt;&gt;&gt; Decimal(3*0.1)
Decimal('0.3000000000000000444089209850062616169452667236328125')
&gt;&gt;&gt; Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
&gt;&gt;&gt; Decimal(4*0.1)
Decimal('0.40000000000000002220446049250313080847263336181640625')
&gt;&gt;&gt; Decimal(0.4)
Decimal('0.40000000000000002220446049250313080847263336181640625')
</code></pre>

python floating-point rounding floating-accuracy ieee-754