简体   繁体   English

Python 将整数四舍五入到下一个百

[英]Python round up integer to next hundred

Seems that should have already been asked hundreds (pun are fun =) of times but i can only find function for rounding floats.似乎应该已经问了数百次(双关语很有趣=),但我只能找到舍入浮点数的函数。 How do I round up an integer, for example: 130 -> 200 ?如何舍入整数,例如: 130 -> 200

Rounding is typically done on floating point numbers, and here there are three basic functions you should know: round (rounds to the nearest integer), math.floor (always rounds down), and math.ceil (always rounds up).四舍五入通常是在浮点数上完成的,这里有三个你应该知道的基本函数: round (四舍五入到最接近的整数)、 math.floor (总是向下math.ceil )和math.ceil (总是向上math.ceil )。

You ask about integers and rounding up to hundreds, but we can still use math.ceil as long as your numbers smaller than 2 53 .您询问整数并四舍五入到数百,但只要您的数字小于 2 53 ,我们仍然可以使用math.ceil To use math.ceil , we just divide by 100 first, round up, and multiply with 100 afterwards:要使用math.ceil ,我们只需先除以 100,四舍五入,然后再乘以 100:

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

Dividing by 100 first and multiply with 100 afterwards "shifts" two decimal places to the right and left so that math.ceil works on the hundreds.先除以 100,然后乘以 100,然后“移动”两个小数位左右,以便math.ceil处理数百个。 You could use 10**n instead of 100 if you want to round to tens ( n = 1 ), thousands ( n = 3 ), etc.如果您想四舍五入为十 ( n = 1 )、千 ( n = 3 ) 等,则可以使用10**n而不是 100。

An alternative way to do this is to avoid floating point numbers (they have limited precision) and instead use integers only.另一种方法是避免浮点数(它们的精度有限)而只使用整数。 Integers have arbitrary precision in Python, so this lets you round numbers of any size.整数在 Python 中具有任意精度,因此这可以让您舍入任何大小的数字。 The rule for rounding is simple: find the remainder after division with 100, and add 100 minus this remainder if it's non-zero:四舍五入的规则很简单:找到除以 100 后的余数,如果余数不为零,则加上 100 减去这个余数:

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

This works for numbers of any size:这适用于任何大小的数字:

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

I did a mini-benchmark of the two solutions:我做了两个解决方案的迷你基准测试:

$ 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

The pure integer solution is faster by a factor of two compared to the math.ceil solution.math.ceil解决方案相比,纯整数解决方案的速度快了math.ceil

Thomas proposed an integer based solution that is identical to the one I have above, except that it uses a trick by multiplying Boolean values. Thomas 提出了一种基于整数的解决方案,与我上面的解决方案相同,只是它使用了乘以布尔值的技巧。 It is interesting to see that there is no speed advantage of writing the code this way:有趣的是,以这种方式编写代码没有速度优势:

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

As a final remark, let me also note, that if you had wanted to round 101–149 to 100 and round 150–199 to 200, eg, round to the nearest hundred, then the built-in round function can do that for you:最后,我还要注意,如果您想将 101-149 舍入到 100,并将 150-199 舍入到 200,例如,舍入到最接近的百位,那么内置的round函数可以为您完成:

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

This is a late answer, but there's a simple solution that combines the best aspects of the existing answers: the next multiple of 100 up from x is x - x % -100 (or if you prefer, x + (-x) % 100 ).这是一个迟到的答案,但有一个简单的解决方案,它结合了现有答案的最佳方面: x的下一个100倍数是x - x % -100 (或者,如果您愿意, x + (-x) % 100 )。

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

This is fast and simple, gives correct results for any integer x (like John Machin's answer) and also gives reasonable-ish results (modulo the usual caveats about floating-point representation) if x is a float (like Martin Geisler's answer).这既快速又简单,为任何整数x提供正确的结果(如 John Machin 的答案),并且如果x是浮点数(如 Martin Geisler 的答案),也给出合理的结果(以关于浮点表示的通常警告为模)。

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

试试这个:

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

Here's a general way of rounding up to the nearest multiple of any positive integer:这是四舍五入到任何正整数的最接近倍数的一般方法:

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

Sample usage:示例用法:

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

For a non-negative, b positive, both integers:对于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)]

Update The currently-accepted answer falls apart with integers such that float(x) / float(y) can't be accurately represented as a float .更新当前接受的答案因整数而分崩离析,因此 float(x) / float(y) 无法准确表示为float See this code:看到这个代码:

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__

Output:输出:

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

And here are some timings:以下是一些时间安排:

>\python27\python -m timeit -s "import math;x =130" "int(math.ceil(x/100.0))*100"
1000000 loops, best of 3: 0.342 usec per loop

>\python27\python -m timeit -s "x = 130" "x + 100 * (x % 100 > 0) - x % 100"
10000000 loops, best of 3: 0.151 usec per loop

>\python27\python -m timeit -s "x = 100" "(x + 99) // 100 * 100"
10000000 loops, best of 3: 0.0903 usec per loop

Try this:试试这个:

import math
def ceilm(number,multiple):
    '''Returns a float rounded up by a factor of the multiple specified'''
    return math.ceil(float(number)/multiple)*multiple

Sample usage:示例用法:

>>> ceilm(257,5)
260
>>> ceilm(260,5)
260

Warning: Premature optimizations ahead...警告:前面的过早优化...

Since so many of the answers here do the timing of this I wanted to add another alternative.由于这里的许多答案都与此有关,因此我想添加另一种选择。

Taking @Martin Geisler 's以@Martin Geisler 的

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

(which i like best for several reasons) (我最喜欢有几个原因)

but factoring out the % action但考虑到 % 动作

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

Yields a ~20% speed improvement over the original比原始速度提高约 20%

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

Is even better and is ~36% faster then the original甚至更好,比原来的快约 36%

finally I was thinking that I could drop the not operator and change the order of the branches hoping that this would also increase speed but was baffled to find out that it is actually slower dropping back to be only 23% faster then the original.最后,我想我可以删除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

explanations as to why 3 is faster then 4 would be most welcome.关于为什么 3 比 4 快的解释是最受欢迎的。

If your int is x: x + 100 - x % 100如果您的 int 是 x: x + 100 - x % 100

However, as pointed in comments, this will return 200 if x==100 .但是,正如评论中所指出的,如果x==100 ,这将返回 200 。

If this is not the expected behavior, you can use x + 100*(x%100>0) - x%100如果这不是预期的行为,您可以使用x + 100*(x%100>0) - x%100

Here is a very simple solution:这是一个非常简单的解决方案:

next_hundred = x//100*100+100

How does it work?它是如何工作的?

  1. Perform the integer division by 100 (it basically cuts off the fractional part of the normal division).执行整数除以 100(它基本上切断了正常除法的小数部分)。 In this way you obtain the tens of a number.这样你就得到了一个数的十位。 For example: 243//100=2.例如:243//100=2。
  2. Multiply by 100, getting the original number without its tens and ones.乘以 100,得到不带十位和个位的原始数。 For example: 2*100=200.例如:2*100=200。
  3. Add 100 to get the desired result.添加 100 以获得所需的结果。 For example: 200+100=300例如:200+100=300

Some examples一些例子

  • 0...99 rounded to 100 0...99 四舍五入为 100
  • 100...199 rounded to 200 100...199 四舍五入为 200
  • etc.等等。

A slightly modified approach rounds 1...100 to 100, 101...200 to 200, etc.:稍微修改的方法将 1...100 舍入到 100、101...200 到 200 等:

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

Simply:简单地:

round(599, -2)

will give:会给:

600 600

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM