파이썬은 정수를 다음 100으로 반올림합니다.


78

이미 수백 번 (말장난은 재미 있습니다 =) 요청을 받았어야했지만 수레를 반올림하는 기능 만 찾을 수 있습니다. 예를 들어, 정수를 어떻게 반올림 130 -> 200합니까?


3
100도 200으로 반올림 하시겠습니까?
DSM

아니, 토마스의 대답은 내가 필요 단지 않습니다
userBG

1
Thomas의 대답 100에서 200까지 반올림합니다. 그래서 제가 물었습니다.
DSM

편집을 확인하십시오. 나는 첫 번째 답변에서 그것에주의를 기울이지 않았습니다.
Thomas Orozco

1
@ofko : 큰 정수로 실패한 답변을 수락했습니다. 자세한 내용은 업데이트 된 답변을 참조하십시오.
John Machin 2012-01-15

답변:


151

반올림은 일반적으로 부동 소수점 숫자에서 수행되며 여기에는 round(가장 가까운 정수로 반올림), math.floor(항상 반올림) 및 math.ceil(항상 반올림 )의 세 가지 기본 함수가 있습니다 .

정수에 대해 묻고 수백으로 반올림하지만 math.ceil2 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수십 ( n = 1), 수천 ( n = 3) 등 으로 반올림하려면 100 대신 사용할 수 있습니다 .

이를 수행하는 다른 방법은 부동 소수점 수 (정밀도가 제한됨)를 피하고 대신 정수만 사용하는 것입니다. 정수는 Python에서 임의의 정밀도를 가지므로 모든 크기의 숫자를 반올림 할 수 있습니다. 반올림 규칙은 간단합니다. 100으로 나눈 후 나머지를 찾고 0이 아닌 경우 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

순수한 정수 솔루션은 솔루션에 비해 2 배 더 빠릅니다 math.ceil.

Thomas는 Boolean 값을 곱하여 트릭을 사용한다는 점을 제외하면 위에서 설명한 것과 동일한 정수 기반 솔루션을 제안했습니다. 이런 식으로 코드를 작성하는 것이 속도 이점이 없다는 것은 흥미 롭습니다.

$ 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으로 반올림하려는 경우 (예 : 가장 가까운 100으로 반올림) 내장 round함수가이를 수행 할 수 있습니다.

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

내가 있다면 내가 여기에 정상적인 반올림 안하고, 그래, 나는 라운드 ()를 사용할 것
userBG

3
@ofko : 맞습니다. 반올림하고 싶습니다. 은 math.ceil나누어 100을 곱하면 만들 수있는 표준 방법입니다 - 그렇게 할 수있는 표준 방법 round, ceil그리고 floor수백에 일을.
Martin Geisler 2012 년

1
최근 편집 후 이제이 답변을 수락하는 것이 합리적입니다.
userBG

2
-1이 접근 방식은 실수 로 "정규적"일 수 있지만 큰 정수 에서는 실패 합니다. 자세한 내용은 내 대답을 참조하십시오. OP는 특별히 정수를 요청했고 숫자 크기에 대한 상한선을 표시하지 않았습니다.
존 머신

1
@JohnMachin : 반대표는 "유용하지 않은"질문에 대한 것이며이 간단하고 직접적인 대답이 왜 유용하지 않은지 알 수 없습니다. 가리키고, 영업 이익은 그것을 받아 같은, 그래서이 표시 되어 유용합니다. 또한 누군가가 130에서 200으로 반올림하는 데 도움이 필요하면 1234567891234567891을 올바르게 반올림하지 않는 것에 대해 불평하기 위해 약간 늘어난 것 같습니다. (물론!) 에 float비해 정밀도가 제한적이라는 것이 long맞지만 대부분의 실제 상황에서 a float는 상당히 큽니다.
Martin Geisler 2012 년

26

이것은 늦은 답변이지만 기존 답변의 가장 좋은 측면을 결합한 간단한 솔루션이 있습니다. 100up from 의 다음 배수는 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의 답변과 같은) 모든 정수에 대해 올바른 결과를 제공하고 x(Martin Geisler의 답변과 같은) float 인 경우 합리적인 결과를 제공합니다 (부동 소수점 표현에 대한 일반적인 경고 모듈로 ).

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

1
솔루션은 Martin만큼 빠르지 만 표기법은 더 짧습니다. 감사. % timeit 'x = 110' 'x-= x % -100'# 100000000 루프, 최고 3 : 루프 당 9.37ns VS % timeit 'x = 110' 'x + 100 * (x % 100> 0)-x % 100 '# 100000000 루프, 최고 3 : 루프 당
9.38ns

21

이 시도:

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

왜 int ()? 형 (원형 (999, -2)) INT (파이썬 3.8)이다
팀 리차드슨

이것은 항상 반올림되지는 않으며 질문이 묻는 것입니다.
Tim

18

다음은 양의 정수의 가장 가까운 배수로 반올림하는 일반적인 방법입니다.

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

샘플 사용법 :

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

동등하고 더 짧은 방법 :lambda number, multiple: multiple * (1 + (number - 1) // multiple)
mic_e 2014-08-27

8

내용은 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

다음은 몇 가지 타이밍입니다.

>\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

I know the OP was about rounding an integer-그러나 나는 당신이 (0.5,10)에 대해 3 개의 옵션을 사용하려고 시도 할 것이라고 지적하고 싶었습니다. 이것은 제가 10을 반환 할 것으로 예상 한 다음 처음 두 메서드 (geisler & orozco)는 예상대로 10을 반환하고 machin은 0을 반환합니다
epeleg

3

int가 x 인 경우 : x + 100 - x % 100

그러나 주석에서 지적했듯이 x==100.

이것이 예상 된 동작이 아닌 경우 다음을 사용할 수 있습니다. x + 100*(x%100>0) - x%100


그래도 매직 넘버가 마음에 들지 않으면 다른 솔루션을 사용할 수 있습니다. 성능에 관심이 있다면 이것은 더 빨리 실행됩니다.
Thomas Orozco

예, (100)는 반올림되지 유지되어야하지만 수식이 너무 복잡 할 것인지, 그 사용하여 코드를 방지 할 수 있습니다, 더 bigy 없습니다
userBG

다른 버전은 100을 더하기 전에 확인을 포함하므로이 문제를 해결합니다! 이것이 귀하의 필요를 충족한다면 수락하는 것을 잊지 마십시오! :)
Thomas Orozco

1
미안하지만이 코드는 비단뱀 적입니다. 예, a bool에는 숫자 값이 있으므로 예, 부울 식으로 곱할 수 있습니다. 그러나 다른 솔루션은 더 명확합니다.
Martin Geisler 2012 년

음, 성능이 핵심 매개 변수가 아닌 경우 다른 코드가 선호 될 수 있다는 점을 실제로 지적했습니다.
Thomas Orozco

3

이 시도:

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

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보다 빠른 이유에 대한 설명이 가장 환영받을 것입니다.


0

다음은 매우 간단한 해결책입니다.

next_hundred = x//100*100+100

어떻게 작동합니까?

  1. 100으로 정수 나누기를 수행합니다 (기본적으로 일반 나누기의 소수 부분을 잘라냅니다). 이런 식으로 수십의 숫자를 얻습니다. 예 : 243 // 100 = 2.
  2. 100을 곱하여 십과 1이없는 원래 숫자를 얻습니다. 예 : 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.