1
wh1100717 2014-10-23 11:14:40 +08:00
{:.2f}只是精度操作,表示的是保留小数点后两位,但不是四舍五入操作。
|
2
hahastudio 2014-10-23 11:24:50 +08:00 2
这是因为 decimal 的默认 context 是“四舍六入五留双”,rounding=ROUND_HALF_EVEN
>>> from decimal import * >>> getcontext() Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, InvalidOperation, Overflow]) 你可以试试 a = '238.355',你最后会获得 238.36 -你学过大学物理肯定清楚这个修约方式- |
3
davidli 2014-10-23 11:26:25 +08:00
@wh1100717
其实是因为python里无法精确表示一个float number. https://docs.python.org/2/tutorial/floatingpoint.html Decimal(234.345) 是234.3449999999 |
4
sriuu 2014-10-23 11:34:15 +08:00
|
5
hahastudio 2014-10-23 11:35:37 +08:00
@davidli 已然用了 decimal,就不是这个问题了
你可以试试 getcontext().rounding = ROUND_HALF_UP 之后,a = '238.345' 就会得到 238.35 |
7
hahastudio 2014-10-23 11:38:51 +08:00 1
关于修约的扩展阅读
GB/T8170-2008 数值修约规则与极限数值的表示和判定 http://www.cws.net.cn/xiazai/yuanxf20112149435658.pdf Numerical Rounding https://en.wikipedia.org/wiki/Rounding |
8
pc10201 OP @hahastudio 好像现在可以了
from decimal import * getcontext().rounding = ROUND_HALF_UP a='238.345' length=len(a[a.find('.'):]) if length>=3: x='{:.2f}'.format(Decimal(a)) print x |
10
Delbert 2014-10-23 11:45:02 +08:00
Python不是round到最近的偶数吗?
|
11
stillzhl 2014-10-23 11:49:37 +08:00
In [2]: from decimal import Decimal
In [3]: def round(x): ...: return '{:.2f}'.format(Decimal(x)) ...: In [4]: a = '238.345' In [5]: round(a) Out[5]: '238.34' In [6]: b = '238.346' In [7]: round(b) Out[7]: '238.35' In [8]: c = '238.355' In [9]: round(c) Out[9]: '238.36' In [10]: d = '238.356' In [11]: round(d) Out[11]: '238.36' 这个问题并不像@wh1100717说的那样,{:.2f}确实对浮点数进行了四舍五入(round)。 具体请查看IEEE的float point rounding rules: http://en.wikipedia.org/wiki/IEEE_floating_point#Rounding_rules 至于为什么会这样我也还没有太弄明白,但是会进一步研究,等有了结果会再来回复。 |
12
hahastudio 2014-10-23 11:52:46 +08:00
@pc10201 对啊,因为你替换了修约规则,变成了“四舍五入”了
-但四舍六入五留双才是国家标准啊- |
13
wodemyworld 2014-10-23 11:52:51 +08:00
有单独的处理舍入的库,你可以找找
|
14
stillzhl 2014-10-23 11:55:28 +08:00
|
15
wh1100717 2014-10-23 11:58:32 +08:00
@davidli
@hahastudio @pc10201 刚才看了一下decimal的定义,实际情况如下: from decimal import * b = Decimal('238.345') getcontext() 返回的值为Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation]) 其中rounding为ROUND_HALF_EVEN. 而ROUND_HALF_EVEN的描述为:Behave as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behave as for ROUND_HALF_DOWN if it's even. (Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case, rounds towards the even neighbor.) 简单说就是如果为238.345 则会使用ROUND_HALF_DOWN,如果是238.355 则会使用ROUND_HALF_UP。 测试代码如下: '{:.2f}'.format(Decimal('238.345')) //返回的是 238.34 '{:.2f}'.format(Decimal('238.355')) //返回的是 238.36 如有错误,请勘正~~ |
18
hahastudio 2014-10-23 12:06:07 +08:00
|
19
andychen20121130 2014-10-23 13:49:31 +08:00
a=a+0.5 保留一个小数。a=a+0.05保留两位小数,你试试
|
20
sivacohan 2014-10-23 14:00:51 +08:00
@stillzhl
最开始接触到四舍五入5留双是在物理学里面。 四舍五入的规约法则如下 0 不需要舍入 [1 ~ 4] = 0 [5 ~ 9] = 10 在上述情况下, 0 到 9 的舍入情况就对应于 [0, -1, -2 , -3, -4, +5, +4, +3, +2, +1] 造成的结果就是每10个数字做舍入操作,总和就增加了5 为了解决这个问题,我们把上面的列表变成 [0, -1, -2 , -3, -4, +/-5, +4, +3, +2, +1] 这样的算总和的结果更接近真实值。 而+/-5 前面的符号,就有前面的数字是奇数还是偶数确定。 |
21
est 2014-10-23 14:11:56 +08:00
@davidli 准确的说不是python无法处理浮点,而是大多数程序的浮点计算,底层都是调用CPU芯片的IEEE 754指令。你要自己撸一个超高精度的软浮点库也行,用纯python的都可以,只是享受不到硬件加速了。
|
22
stillzhl 2014-10-24 11:14:14 +08:00
|