2012-02-10 506 views
20

我如何能圆了一个数字,小数点后第三位在Python例如:四舍五入到小数点后第三位在Python

0.022499999999999999

应该四舍五入到0.03

0.1111111111111000

应舍入为0.12

如果在小数点后第三位有任何值,我希望它总是向上舍入,让我留下2个值小数点

+4

在继续之前,我建议阅读Python教程中的[Floating Point Arithmetic:Issues and Limitations](http://docs.python.org/tutorial/floatingpoint.html)。 – 2012-02-10 17:44:25

+0

另外,考虑你是否真的想舍入值,或者你只是想*显示* 3位小数...... – geoffspear 2012-02-10 19:27:16

回答

17
from math import ceil 

num = 0.1111111111000 
num = ceil(num * 100)/100.0 

参见:
math.ceil documentation
round documentation - 你可能会想反正检查了这一点以备将来参考

+0

这里你不需要'round()' - 它不会改变结果以任何方式。 – 2012-02-10 17:49:45

+2

给出下列情况下错误的结果: 'math.ceil((1.11 * 100.0))/ 100.0' 出来是'1.12' 因为: '1.11 * 100.0'具有价值'111.00000000000001' – nimeshkiranverma 2017-02-23 15:59:58

+1

@nimeshkiranverma请参阅[浮点数学是否被破坏?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken)使用['decimal'模块](https://docs.python.org /3/library/decimal.html)如果你需要精确的小数结果。 – 2017-11-16 14:16:33

34

的Python包括round()功能,lets you specify你想要位数。从文档:

round(x[, n])

返回浮点值X小数点后四舍五入到n个数字。如果省略n,则默认为零。结果是一个浮点数。数值四舍五入为10的最接近倍数,以功率减n;如果两个倍数同样接近,则四舍五入从0开始(例如,round(0.5)为1.0,round(-0.5)为-1.0)。

所以你想用round(x, 2)做正常的四舍五入。为确保数字总是舍入为以上您需要使用ceil(x)函数。同样,要将下调使用floor(x)

+4

很好的建议,但它并没有像OP那样需要**。 – NPE 2012-02-10 17:45:53

+1

“舍入”与正常舍入不同。看看问题中的例子。 – 2012-02-10 17:46:23

+0

你是对的 - 我现在正在编辑。 – simchona 2012-02-10 17:48:14

10
x = math.ceil(x * 100.0)/100.0 
+1

在我意识到这比我的解决方案更加pythonic之前,我不得不盯着这一段时间。 – Edwin 2012-02-10 17:49:53

9

从埃德温的回答推断:

from math import ceil, floor 
def float_round(num, places = 0, direction = floor): 
    return direction(num * (10**places))/float(10**places) 

要使用:

>>> float_round(0.21111, 3, ceil) #round up 
>>> 0.212 
>>> float_round(0.21111, 3)  #round down 
>>> 0.211 
>>> float_round(0.21111, 3, round) #round naturally 
>>> 0.211 
+1

在以下情况下给出错误结果: 'math.ceil((1。11 * 100.0))/ 100.0' 出来是'1.12' 因为: '1.11 * 100.0'的值是'111.00000000000001' – nimeshkiranverma 2017-02-23 15:59:28

3

注意,ceil(num * 100)/100招会崩溃一些退化的投入,像1e308。这可能不会经常出现,但我可以告诉你,这花了我几天的时间。为了避免这种情况,“如果ceil()floor()采用了小数位参数,就好像round()一样......”同时,任何人都知道一个干净的替代品,它不会像这样的输入崩溃?我曾经为decimal包一些希望,但它似乎死过:

当然
>>> from math import ceil 
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP 
>>> num = 0.1111111111000 
>>> ceil(num * 100)/100 
0.12 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
0.12 
>>> num = 1e308 
>>> ceil(num * 100)/100 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
OverflowError: cannot convert float infinity to integer 
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP)) 
Traceback (most recent call last): 
    File "<string>", line 301, in runcode 
    File "<interactive input>", line 1, in <module> 
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>] 

之一可能会说,崩溃是这样的投入,唯一理智的行为,但我认为这不是舍入而是乘法这就是导致问题的原因(这就是为什么,例如,1e306不会崩溃的原因),并且更清楚地实现第n个地方的fn将避免乘法破解。

+0

这个使用'Decimal'的问题就是结果量化表达式需要311位数字来表示,而且当前精度太小。如果你从''''''''进行了十进制输入getcontext; getcontext()。prec = 400',这将“工作”,对于某些“工作”值。或者你可以注意到,绝对值大于2 ** 52的浮点数必须是一个整数,所以舍入将不起作用。是的,我同意如果“ceil”和“floor”取小数点的话,这很好。 – 2015-08-30 16:56:33

7

这取决于您在考虑正数和负数时想要的行为,但是如果您希望始终舍入较大的值(例如2.0449 - > 2.05,-2。0449 - > -2.04),那么你可以这样做:

round(x + 0.005, 2) 

还是有点票友:

def round_up(x, place): 
    return round(x + 5 * 10**(-1 * (place + 1)), place) 

这也似乎工作如下:

round(144, -1) 
# 140 
round_up(144, -1) 
# 150 
round_up(1e308, -307) 
# 1.1e308 
0

中规定的轮funtion不不适用于像definate整数:

一个= 8
轮(A,3)
8.0
α= 8.00
轮(A,3)
8.0
一个= 8.000000000000000000000000
轮(A,3)
8.0

但,适用于:

R = 400/3.0
ř
133.33333333333334
圆(R,3)
133.333

Morever小数点如2.675四舍五入为2.67 n ot 2.68。
更好地使用上面提供的其他方法。