Linux迷+Python粉 - 精度问题https://blog.pythonwood.com/2017-12-12T22:12:00+08:00Python量化之数据处理——小数浮点精度问题解决2017-04-18T14:03:00+08:002017-12-12T22:12:00+08:00pythonwoodtag:blog.pythonwood.com,2017-04-18:/2017/04/Python量化之数据处理——小数浮点精度问题解决/<h3 id="_1">量化金融刚结果:计算出差了一分钱的涨停价<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3> <p>量化金融用Python,最近在处理浮点问题的时候,发现一个问题,比较有意思,分享出来。</p> <p>python计算79.035的四舍五入结果是79.03,这是错误的。</p> <p>以下是IPython中输入程序语句,IPython能即时编译运算和输出结果。</p> <div class="highlight"><pre><span></span># 计算71.85的涨停价 In [1]: 71.85 * 1 …</pre></div><h3 id="_1">量化金融刚结果:计算出差了一分钱的涨停价<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h3> <p>量化金融用Python,最近在处理浮点问题的时候,发现一个问题,比较有意思,分享出来。</p> <p>python计算79.035的四舍五入结果是79.03,这是错误的。</p> <p>以下是IPython中输入程序语句,IPython能即时编译运算和输出结果。</p> <div class="highlight"><pre><span></span># 计算71.85的涨停价 In [1]: 71.85 * 1.10 Out[1]: 79.035 # 涨停价四舍五入应该是79.04,但由精度损失,只有79.03。 In [2]: round(71.85 * 1.10, 2) Out[2]: 79.03 </pre></div> <h3 id="_2">原因分析<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h3> <p>这个问题和Python语言本身无关,原因是浮点数即小数在<a href="http://www.cnblogs.com/jiayouwyhit/p/3148493.html" title="计算机的二进制化标准">计算机的二进制化标准</a>有关。</p> <p>所以很多计算机语言都存在浮点精度损失问题,但庆幸python已有解决方法。Python已经写出了一些库,能屏蔽下层计算机架构带来的浮点问题。</p> <h3 id="python">Python浮点运算的正确方法<a class="headerlink" href="#python" title="Permanent link">&para;</a></h3> <p>Python解决浮点精度问题的办法是使用<a href="http://python.usyiyi.cn/python_278/library/decimal.html" title="decimal官网">decimal</a>库。</p> <div class="highlight"><pre><span></span><span class="n">In</span> <span class="p">[</span><span class="mi">26</span><span class="p">]:</span> <span class="kn">from</span> <span class="nn">decimal</span> <span class="kn">import</span> <span class="o">*</span> <span class="n">In</span> <span class="p">[</span><span class="mi">31</span><span class="p">]:</span> <span class="k">print</span> <span class="n">Decimal</span><span class="p">(</span><span class="mf">79.035</span><span class="p">)</span><span class="o">.</span><span class="n">quantize</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="s1">&#39;.01&#39;</span><span class="p">),</span> <span class="n">rounding</span><span class="o">=</span><span class="n">ROUND_HALF_UP</span><span class="p">)</span> <span class="mf">79.04</span> </pre></div> <p>为此我特地写了邮件,写出期望优矿支持引入<a href="http://python.usyiyi.cn/python_278/library/decimal.html" title="decimal官网">decimal</a>库。得到回复说优矿下一个版本中引入。</p> <p>(更新:到了5月份确实可以引入decimal库了,至此问题解决)</p> <h3 id="_3">参考<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h3> <p>谈谈关于Python里面小数点精度控制的问题&nbsp;http://www.cnblogs.com/herbert/p/3402245.html</p> <p>Python 为什么不解决四舍五入(round)的“bug”?&nbsp;https://www.zhihu.com/question/20128906</p> <p>python:0.1 + 0.2 == 0.3:False&nbsp;https://stackoverflow.com/questions/588004/is-floating-point-math-broken</p> <p>round() in Python doesn&rsquo;t seem to be rounding properly&nbsp;https://stackoverflow.com/questions/56820/round-in-python-doesnt-seem-to-be-rounding-properly</p>