Python将整数舍入到下一百

时间:2012-01-14 22:52:42

标签: python math rounding

似乎应该已经被问过几百次(双关语很有趣)但是我只能找到圆形浮子的功能。如何对整数进行舍入,例如:130 -> 200

9 个答案:

答案 0 :(得分:110)

舍入通常在浮点数上完成,这里有三个你应该知道的基本函数:round(舍入到最接近的整数),math.floor(总是向下舍入)和{{ 3}}(总是向上舍入)。

你询问有关整数和四舍五入的整数,但只要你的数字小于2 53 ,我们仍然可以使用math.ceil。要使用math.ceil,我们先将100除以100,然后乘以100:

>>> import math
>>> def roundup(x):
...     return int(math.ceil(x / 100.0)) * 100
... 
>>> roundup(100)
100
>>> roundup(101)
200

首先除以100,然后乘以100将“左移两位小数”向左右移动,以便math.ceil对数百个进行处理。如果要舍入到数十(10**n),数千(n = 1)等,可以使用n = 3而不是100。

另一种方法是避免浮点数(它们的精度有限),而只使用整数。整数在Python中具有任意精度,因此这允许您对任何大小的数字进行舍入。舍入规则很简单:找到除法后的余数为100,如果非零,则加上100减去这个余数:

>>> def roundup(x):
...     return x if x % 100 == 0 else x + 100 - x % 100

这适用于任何大小的数字:

>>> roundup(100)
100
>>> roundup(130)
200
>>> roundup(1234567891234567891)
1234567891234567900L

我做了两个解决方案的迷你基准测试:

$ python -m timeit -s 'import math' -s 'x = 130' 'int(math.ceil(x/100.0)) * 100'
1000000 loops, best of 3: 0.364 usec per loop
$ python -m timeit -s 'x = 130' 'x if x % 100 == 0 else x + 100 - x % 100'
10000000 loops, best of 3: 0.162 usec per loop

math.ceil解决方案相比,纯整数解决方案的速度提高了两倍。

托马斯提出了一个基于整数的解决方案,它与我上面的解决方案相同,只是它通过乘以布尔值来使用技巧。有趣的是,以这种方式编写代码没有速度优势:

$ python -m timeit -s 'x = 130' 'x + 100*(x%100>0) - x%100'
10000000 loops, best of 3: 0.167 usec per loop

作为最后一句话,我还要注意,如果你想要将101-149轮到100轮并将轮150-199轮到200轮,例如,轮到最近的百,那么内置round函数可以为您做到这一点:

>>> int(round(130, -2))
100
>>> int(round(170, -2))
200

答案 1 :(得分:19)

试试这个:

int(round(130 + 49, -2))

答案 2 :(得分:17)

这是一种舍入到任何正整数的最接近倍数的一般方法:

def roundUpToMultiple(number, multiple):
    num = number + (multiple - 1)
    return num - (num % multiple)

样本用法:

>>> roundUpToMultiple(101, 100)
200
>>> roundUpToMultiple(654, 321)
963

答案 3 :(得分:17)

这是一个迟到的答案,但有一个简单的解决方案结合了现有答案的最佳方面:100的下一个倍数xx - x % -100(或者如果你更喜欢,x + (-x) % 100)。

>>> x = 130
>>> x -= x % -100  # Round x up to next multiple of 100.
>>> x
200

这是快速而简单的,为任何整数x(如John Machin的答案)提供正确的结果,并且如果x也给出了合理的结果(以浮点表示的常见警告为模)是一个浮动(就像Martin Geisler的回答)。

>>> x = 0.1
>>> x -= x % -100
>>> x
100.0

答案 4 :(得分:9)

对于a非负,b正数,两个整数:

>>> rup = lambda a, b: (a + b - 1) // b * b
>>> [(x, rup(x, 100)) for x in (199, 200, 201)]
[(199, 200), (200, 200), (201, 300)]

更新 当前接受的答案与整数分开,因此无法将float(x)/ float(y)准确地表示为{{1} }。看到这段代码:

float

输出:

import math

def geisler(x, y): return int(math.ceil(x / float(y))) * y

def orozco(x, y): return x + y * (x % y > 0) - x % y

def machin(x, y): return (x + y - 1) // y * y

for m, n in (
    (123456789123456789, 100),
    (1234567891234567891, 100),
    (12345678912345678912, 100),
    ):
    print; print m, "m"; print n, "n"
    for func in (geissler, orozco, machin):
        print func(m, n), func.__name__

以下是一些时间:

123456789123456789 m
100 n
123456789123456800 geisler
123456789123456800 orozco
123456789123456800 machin

1234567891234567891 m
100 n
1234567891234568000 geisler <<<=== wrong
1234567891234567900 orozco
1234567891234567900 machin

12345678912345678912 m
100 n
12345678912345680000 geisler <<<=== wrong
12345678912345679000 orozco
12345678912345679000 machin

答案 5 :(得分:3)

如果你的int是x:x + 100 - x % 100

但是,正如评论中所指出的,如果x==100,则会返回200。

如果这不是预期的行为,您可以使用x + 100*(x%100>0) - x%100

答案 6 :(得分:3)

警告:提前过早优化......

由于这里有很多答案,所以我想增加另一种选择。

采取@Martin Geisler的

def roundup(x):
    return x if x % 100 == 0 else x + 100 - x % 100

(我最喜欢有几个原因)

但要考虑%行动

def roundup2(x):
    x100= x % 100
    return x if x100 == 0 else x + 100 - x100

比原来的速度提高了约20%的速度

def roundup3(x):
    x100 = x % 100
    return x if not x100 else x + 100 - x100

甚至更好,比原来的快36%〜

最后我想我可以放弃not运营商并改变分支机构的顺序,希望这也会提高速度但是却感到困惑,发现实际上它的回落速度只有23%比原来快。

def roundup4(x):
    x100 = x % 100
    return x + 100 - x100  if x100 else x


>python -m timeit -s "x = 130" "x if x % 100 == 0 else x + 100 - x % 100"
1000000 loops, best of 3: 0.359 usec per loop

>python -m timeit -s "x = 130" "x100 = x % 100"  "x if x100 == 0 else x + 100 - x100"
1000000 loops, best of 3: 0.287 usec per loop

>python -m timeit -s "x = 130" "x100 = x % 100"  "x if not x100 else x + 100 - x100"
1000000 loops, best of 3: 0.23 usec per loop

>python -m timeit -s "x = 130" "x100 = x % 100"  "x + 100 - x100 if x100 else x"
1000000 loops, best of 3: 0.277 usec per loop

关于为什么3比4更快的解释将是最受欢迎的。

答案 7 :(得分:0)

这是一个非常简单的解决方案:

next_hundred = x//100*100+100

它如何工作?

  1. 将整数除以100(它基本上会切除正常除法的小数部分)。这样,您可以获得数的十。例如:243 // 100 = 2。
  2. 乘以100,得到的原始数字不包含十进制和一个。例如:2 * 100 = 200。
  3. 加100以得到所需的结果。例如:200 + 100 = 300

一些示例

  • 0 ... 99舍入为100
  • 100 ... 199舍入为200

稍作修改的方法将1 ... 100舍入为100,101 ... 200舍入为200,依此类推:

next_hundred = (x-1)//100*100+100

答案 8 :(得分:0)

简单地说:

round(599, -2)

会给:

<块引用>

600