Python 将整数四舍五入到下一个百位数
- 2025-02-13 08:35:00
- admin 原创
- 40
问题描述:
似乎这个问题应该已经被问了数百次(双关语很有趣 =)但我只能找到对浮点数进行舍入的函数。如何对整数进行舍入,例如:130 -> 200
?
解决方案 1:
四舍五入通常在浮点数上进行,这里有三个您应该知道的基本函数:(round
四舍五入到最接近的整数)、math.floor
(始终向下舍入)和math.ceil
(始终向上舍入)。
您询问的是整数和四舍五入到百位数,但math.ceil
只要您的数字小于 2 53 ,我们仍然可以使用。要使用math.ceil
,我们只需先除以 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
100 代替。n = 1
`n = 3`
另一种方法是避免使用浮点数(它们的精度有限),而只使用整数。整数在 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
。
Thomas 提出了一个基于整数的解决方案,它与我上面的解决方案相同,只是它使用了乘以布尔值的技巧。有趣的是,以这种方式编写代码没有任何速度优势:
$ 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
解决方案 2:
这是一个迟来的答案,但有一个简单的解决方案,它结合了现有答案的最佳方面:从100
向上的下一个倍数x
是x - x % -100
(或者如果你愿意,x + (-x) % 100
是)。
>>> x = 130
>>> x -= x % -100 # Round x up to next multiple of 100.
>>> x
200
这很快速且简单,可以为任何整数提供正确的结果x
(如 John Machin 的答案),并且如果是浮点数(如 Martin Geisler 的答案),也能提供合理的结果(模数关于浮点表示的通常警告)x
。
>>> x = 0.1
>>> x -= x % -100
>>> x
100.0
解决方案 3:
尝试一下:
int(round(130 + 49, -2))
解决方案 4:
以下是将任何正整数向上舍入到最接近的倍数的一般方法:
def roundUpToMultiple(number, multiple):
num = number + (multiple - 1)
return num - (num % multiple)
使用示例:
>>> 四舍五入为多值(101,100)
200
>>> 四舍五入为多值(654,321)
963
解决方案 5:
对于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) 无法准确表示为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
以下是一些时间安排:
>python27python -m timeit -s "import math;x =130" "int(math.ceil(x/100.0))*100"
1000000 loops, best of 3: 0.342 usec per loop
>python27python -m timeit -s "x = 130" "x + 100 * (x % 100 > 0) - x % 100"
10000000 loops, best of 3: 0.151 usec per loop
>python27python -m timeit -s "x = 100" "(x + 99) // 100 * 100"
10000000 loops, best of 3: 0.0903 usec per loop
解决方案 6:
尝试一下:
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
使用示例:
>>> ceilm(257, 5)
260
>>> ceilm(260, 5)
260
解决方案 7:
如果你的 int 是 x:x + 100 - x % 100
但是,正如评论所指出的,如果,这将返回 200 x==100
。
如果这不是预期的行为,您可以使用x + 100*(x%100>0) - x%100
解决方案 8:
警告:前方过早优化……
由于这里很多答案都与时间有关,所以我想添加另一种选择。
以@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 更快的解释。
解决方案 9:
这是一个非常简单的解决方案:
next_hundred = x//100*100+100
它是如何工作的?
将整数除以 100(基本上就是将普通除法的小数部分截掉)。这样就可以得到一个数的十位数。例如:243//100=2。
乘以 100,得到原始数字,不包含十位和个位。例如:2*100=200。
加 100 即可得到所需结果。例如:200+100=300
一些例子
0...99 四舍五入为 100
100...199 四舍五入为 200
ETC。
稍微修改一下的方法就是将 1...100 四舍五入为 100,将 101...200 四舍五入为 200,等等:
next_hundred = (x-1)//100*100+100
解决方案 10:
简单地:
round(599, -2)
将给出:
600
解决方案 11:
n // -100 * -100
(这就像// 100 * 100
,地板,但暂时否定会让世界颠倒,所以它反而会变成天花板。)