<p><code>round(value,significantDigit)</code>是普通的解决方案,但是当以<code>5</code>结尾的舍入值结束时,从数学的角度来看,这并不像预期的那样操作。如果<code>5</code>在您四舍五入后的数字中,则这些值有时只按预期进行四舍五入(即<code>8.005</code>四舍五入到两个十进制数字表示<code>8.01</code>)。对于某些由于浮点数学的怪癖而产生的值,它们将被舍入!</p>
<p>即</p>
<pre><code>>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01
</code></pre>
<p>很奇怪。</p>
<p>假设您的目的是对科学中的统计数据进行传统的舍入,那么这是一个方便的包装器,可以让<code>round</code>函数按预期工作,需要<code>import</code>额外的东西,比如<code>Decimal</code>。</p>
<pre><code>>>> round(0.075,2)
0.07
>>> round(0.075+10**(-2*5),2)
0.08
</code></pre>
<p>啊哈!所以基于这个我们可以做一个函数。。。</p>
<pre><code>def roundTraditional(val,digits):
return round(val+10**(-len(str(val))-1), digits)
</code></pre>
<p>基本上,这会添加一个值,该值保证小于尝试对其使用<code>round</code>的字符串的最小给定数字。在大多数情况下,通过添加这个小数量,它会保留<code>round</code>的行为,同时现在确保低于被舍入到的数字的位数是<code>5</code>它会向上舍入,如果是<code>4</code>它会向下舍入。</p>
<p>使用<code>10**(-len(val)-1)</code>的方法是经过深思熟虑的,因为它是您可以添加以强制移位的最大小数值,同时还确保添加的值永远不会更改舍入,即使缺少小数<code>.</code>。我可以用<code>10**(-len(val))</code>和条件<code>if (val>1)</code>来减去<code>1</code>更多。。。但是总是减去<code>1</code>比较简单,因为这不会改变这个解决方案能够正确处理的十进制数的适用范围。如果您的值达到类型的限制,这种方法将失败,但对于几乎所有有效的十进制值范围,它都应该起作用。</p>
<p>您也可以使用<a href="https://docs.python.org/3/library/decimal.html" rel="noreferrer">decimal</a>库来实现这一点,但我建议的包装器更简单,在某些情况下可能更受欢迎。</p>
<hr/>
<p><strong>编辑:</strong>感谢<a href="https://stackoverflow.com/users/1405065/blckknght">Blckknght</a>指出<code>5</code>边缘情况只发生在某些值上。此外,这个答案的早期版本不够明确,只有当紧靠要舍入到的数字下面的数字有<code>5</code></em>时,才会出现奇数舍入行为<em>。</p>