如何在Python中四舍五入一个数字?


486

这个问题使我丧命。如何在Python中向上舍入一个数字?

我尝试了舍入(数字),但它四舍五入数字。例:

round(2.3) = 2.0 and not 3, what I would like

我尝试了int(number + .5),但是它再次将数字取整!例:

int(2.3 + .5) = 2

然后我尝试了round(number + .5),但在边缘情况下不起作用。例:

WAIT! THIS WORKED!

请指教。


4
round(number + .5)如果数字是整数,则不起作用。round(3+.5) == 4当你真正想要的时候3
Nearoo

Answers:


844

小区(上限)功能:

import math
print(math.ceil(4.2))

21
详细说明:math.ceil返回大于或等于输入值的最小整数。此函数将输入视为浮点型(Python没有强类型变量),并且该函数返回浮点型。如果您想要一个整数,则可以根据返回值构造一个整数,即int(math.ceil(363))
RW Sinnet

9
@Sinnet:实际上可以说python是强类型的stackoverflow.com/a/11328980/5069869
Bernhard

1
@TheEspinosa:是的,python肯定是类型的,只是很多函数都会问一些参数类型的问题,并根据答案执行不同的代码。
quamrana

12
@RWSinnet在Python 3中,math.ceil返回一个实际的整数对象,而不仅仅是具有整数值的浮动对象。
亚瑟·塔卡

注意浮动精度,因为10000000 * 0.00136 = 13600.000000000002ceil可能会增加很多math.ceil(10000000 * 0.00136) = 13601.0
thestreet

170

我知道这个答案是一个很久以前的问题,但是如果您不想导入数学并且只想四舍五入,那么这对我有用。

>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5

如果有余数,则第一部分将变为4,第二部分将得出“ True”,另外,True = 1; False =0。因此,如果没有余数,则它将保持相同的整数,但是如果有余数,则将其加1。


38
真好 您也可以使用//整数除法,因此变为21 // 5 + (21 % 5 > 0)
naught101

6
如果仅涉及整数,则这是最佳解决方案。没有不必要float的。真好
NicoSchlömer17年

158

请记住有趣的Python 2.x问题:

>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0

问题是在python中将两个int相除会产生另一个int,并且在上限调用之前被截断了。您必须使一个值成为浮点数(或强制转换)才能获得正确的结果。

在javascript中,完全相同的代码会产生不同的结果:

console.log(Math.ceil(4500/1000));
5

44
Python 2.x中:int /
int-

7
您可以通过启用“真师”获得关于Python 2.x中的某些版本的行为Python的3.x作为显示在这里
罗布·丹尼斯

110

如果使用整数,则四舍五入的一种方法是利用四舍五入的事实//:只需对负数进行除法,然后取反即可。无需导入,浮点或有条件的。

rounded_up = -(-numerator // denominator)

例如:

>>> print(-(-101 // 5))
21

1
当您不需要执行任何数学运算时该怎么办?即您只有一个号码。
克利克(Klik)2013年

2
@Klik:然后您可以除以1 ==>-(--num // 1),您将得到答案:-)祝您有美好的一天!大卫·鲍(David Bau):非常好的提议!
Marco smdm

10
我在这里为所有答案定了时间,这比次佳(math.ceil)快五倍。@Andreas在同一时间
迷你帐篷'17

@minitotent这并不奇怪,因为它是简单的整数除法和几个单周期操作。这是让您获得工作的答案:不仅要理解语言,还要理解其下的所有抽象层。
Nearoo

真好!我一直使用(num + den - 1) // den,这对于int带有正分母的输入很好,但是即使涉及单个非整数float(分子或分母),也会失败。这看起来更神奇,但同时适用于intfloat。对于较小的分子,它也更快(在CPython 3.7.2上),但是奇怪的是,当仅分子大到足以需要基于数组的数学运算时,您的方法就更慢了。不清楚为什么会这样,因为除法运算应该相似,并且两个一元否定应该比加减法便宜。
ShadowRanger

56

您可能还喜欢numpy:

>>> import numpy as np
>>> np.ceil(2.3)
3.0

我并不是说它比数学更好,但是如果您已经将numpy用于其他目的,则可以使代码保持一致。

无论如何,我遇到的只是一个细节。我经常使用numpy,但感到惊讶的是它没有被提及,但是当然可以接受。


3
使用numpy也很好。最简单的是数学运算,因为它已经是内置库中的python的一部分。这更有意义。相反,如您提到的,如果您在其他问题上使用大量的numpy,则使用numpy.ceil是合理且一致的:-)很好的提示!
Marco smdm

30

使用math.ceil围捕:

>>> import math
>>> math.ceil(5.4)
6.0

注意:输入应为浮点型。

如果需要整数,请调用int将其转换:

>>> int(math.ceil(5.4))
6

BTW,使用math.floor到轮,并round以轮最接近的整数。

>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)

1
如果使用python 3,则输入不一定是浮点数:ceil() 将在内部对其进行处理
guival


11

我很惊讶没有人建议

(numerator + denominator - 1) // denominator

用于四舍五入的整数除法。曾经是C / C ++ / CUDA的常用方法(参见divup


2
仅与静态类型的语言有关。如果分母是浮点数,那么您就死定了。
巴雷尔

如果分母为正,这也将始终如一地起作用。如果分母为负,则需要加1而不是减,或者在执行数学运算之前翻转分子和分母的正负号。
ShadowRanger

7

请确保四舍五入的值应为浮点型

a = 8 
b = 21
print math.ceil(a / b)
>>> 0

print math.ceil(float(a) / b)
>>> 1.0

6

尝试这个:

a = 211.0
print(int(a) + ((int(a) - a) != 0))

1
聪明。每当需要四舍五入时,((int(a) - a) != 0)表达式1都会返回a。您可能需要扩大答案并解释其工作原理。
汤姆·阿兰达

@TomAranda谁能解释一个布尔表达式如何求值?
Bowen Liu

6
>>> def roundup(number):
...     return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20

此功能不需要任何模块。


如果您的电话号码是什么3,那么它将舍入4为某人想要或可能不是的东西
buydadip

15
这仅适用于所有情况的99%。您没有正确地考虑到这一点。应不惜一切代价避免这种解决方案。
Nearoo

所以代替+.5对我来说已经足够+ .49999999了。
FlyingZebra 1

5

上面的答案是正确的,但是,math对于这个功能而言,导入模块通常对我来说有点过头了。幸运的是,还有另一种方法可以做到:

g = 7/5
g = int(g) + (not g.is_integer())

True并且在python中涉及数字的语句中False被解释为10g.is_interger()基本上翻译为g.has_no_decimal()g == int(g)。因此,最后的英文陈述为round g down and add one if g has decimal


1
如果您愿意,可以int(g) + (g % 1 > 0)改用;-)
Nearoo

from math import ceil似乎修复了导入整个数学模块的问题:)
SH7890

@ SH7890恐怕这行import math与幕后发生的事情并没有太大不同。它只会删除除以外的所有符号ceil
Nearoo

5

无需导入数学//使用基本环境:

a)方法/类方法

def ceil(fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

def ceil(self, fl): 
  return int(fl) + (1 if fl-int(fl) else 0)

b)lambda:

ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)

5

对于那些想要四舍五入a / b并获得整数的人:

使用整数除法的另一个变体是

def int_ceil(a, b):
    return (a - 1) // b + 1

>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5

3

如果有人希望将其舍入到小数点后一位:

import math
def round_up(n, decimals=0):
    multiplier = 10 ** decimals
    return math.ceil(n * multiplier) / multiplier

1

令我惊讶的是我还没有看到这个答案round(x + 0.4999),所以我要把它放下来。请注意,这适用于任何Python版本。对Python舍入方案的更改使事情变得困难。看到这篇文章

不导入,我使用:

def roundUp(num):
    return round(num + 0.49)

testCases = list(x*0.1 for x in range(0, 50))

print(testCases)
for test in testCases:
    print("{:5.2f}  -> {:5.2f}".format(test, roundUp(test)))

为什么这样

来自文档

对于支持round()的内置类型,将值四舍五入为乘幂n的最接近10的倍数;如果两个倍数相等接近,则四舍五入取整为偶数选择

因此,将2.5舍入为2,将3.5舍入为4。如果不是这种情况,则可以通过加0.5来舍入,但是我们要避免到达中间点。因此,如果添加0.4999,您将接近,但有足够的余量可以四舍五入到通常的期望值。当然,如果x + 0.4999等于,这将失败[n].5000,但这不太可能。


2
使用0.4999,它将不能为???。0000和???。0001(打开间隔)之间的任何输入给出正确的结果,而不仅仅是???。0001。例如,如果您将其与3.00005一起尝试,则结果将为3,而不是预期的4。指出如果手边有更健壮和直观的解决方案,例如使用math.ceil()
blubberdiblub

@blubberdiblub在回答中我声明Without importing I use:。我还提到过,如果x + 0.4999等于,它将失败[n].5000
Klik

4
是的,您在回答中指出您的解决方案未导入,但是我看不到它的价值。该math模块math.ceil()位于标准库中,因此可在所有实际应用中随处使用,而无需安装其他东西。关于您提到何时失败,这在您的答案中是不完整的,因为它会在整个时间间隔内失败,而不仅仅是在单个点上失败。从技术上讲,您可以说您是正确的,就像您说的是if而不是iff一样,但这会让随便的读者觉得它的可能性比实际的可能性小。
blubberdiblub

0

要做到这一点而无需任何导入:

>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3

0

我知道这已经有一段时间了,但是我找到了一个非常有趣的答案,所以可以这样:

-round(-x-0.5)

这可以修复边缘情况,并且适用于正数和负数,并且不需要任何函数导入

干杯


2
这仍然会四舍五入-round(-x-0.3) = x
Diblo Dk

0

当您在python中操作4500/1000时,结果将为4,因为默认情况下python假定结果为整数,逻辑上:4500/1000 = 4.5-> int(4.5)= 4且ceil显然为4

使用4500 / 40.0的结果将是4.5且ceil为4.5-> 5

使用javascript,您将收到4.5的4500/1000结果,因为javascript仅将结果视为“数值类型”,并将结果直接返回为float

祝好运!!


仅在Python 2.x中如此。在Python 3中,用单个除法/总是产生浮点数,所以4500/1000总是4.5。
Nearoo

0

如果您不想导入任何内容,则可以始终将自己的简单函数编写为:

def RoundUP(num): if num== int(num): return num return int(num + 1)


2
如果num为2.05,则此方法不起作用。您必须至少有9个数字作为输入,剩下的数字为0.999 ...是1。但是随后您的角案例2又被四舍五入了。-嗯,我想那是为什么math.ceil存在的原因。
约翰内斯·玛丽亚·弗兰克


-1

我认为您会混淆int()和之间的工作机制round()

int()如果给出浮点数,则总是截断十进制数;相反round(),如果2.5where 23are都在等距离内2.5,则Python返回距离0点更远的那个。

round(2.5) = 3
int(2.5) = 2

“向上舍入”表示例如2.3变成3,这在您的两个示例中都不会发生。
Nearoo

-2

我的份额

我已经测试 print(-(-101 // 5)) = 21了上面给出的示例。

现在进行四舍五入:

101 * 19% = 19.19

我不能使用,**所以我将乘法扩展到除法:

(-(-101 //(1/0.19))) = 20

-3

我基本上是Python的初学者,但是如果您只是想舍入而不是舍弃,那为什么不做:

round(integer) + 1

2
这不会对任何整数工作i其中2.5 <整数<3向上取整后的所期望的值是3,但是您的表达式将变成4
Pranav舒克拉

1
我认为您的意思round(integer + 0.5)是我经常这样做
Klik
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.