[python] 가장 가까운 정수로 반올림

나는 다음과 같이 긴 부동 소수점 숫자를 반올림하려고했습니다.

32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...

지금까지 성공하지 못했습니다. 나는 (내가 찾는 것이 아닌 반올림 또는 내림에도 불구하고) 시도했다 math.ceil(x).math.floor(x)round(x) 하는 (여전히 숫자를 떠) 중 하나가 작동하지 않았다.

어떻게해야합니까?

편집 : 코드 :

for i in widthRange:
    for j in heightRange:
        r, g, b = rgb_im.getpixel((i, j))
        h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)
        h = h * 360
        int(round(h))
        print(h)



답변

int(round(x))

반올림하고 정수로 바꿉니다.

편집하다:

변수에 int (round (h))를 할당하지 않았습니다. int (round (h))를 호출하면 정수를 반환하지만 다른 작업은 수행하지 않습니다. 그 줄을 다음과 같이 변경해야합니다.

h = int(round(h))

h에 새 값을 할당하려면

편집 2 :

의견에서 @plowman이 말했듯이 Python round()은 정상적으로 예상대로 작동하지 않으며 숫자가 변수로 저장되는 방식은 일반적으로 화면에 표시되는 방식이 아니기 때문입니다. 이 동작을 설명하는 많은 답변이 있습니다.

round ()가 올바르게 반올림되지 않는 것 같습니다

이 문제를 피하는 한 가지 방법은이 답변에 명시된 십진수를 사용하는 것입니다. https://stackoverflow.com/a/15398691/4345659

추가 라이브러리를 사용하지 않고이 답변이 제대로 작동하려면 사용자 정의 반올림 기능을 사용하는 것이 편리합니다. 많은 수정을 한 후 테스트 한 모든 저장 문제를 피할 수있는 다음 해결책을 생각해 냈습니다. repr()(NOT str()!)로 얻은 문자열 표현을 기반으로합니다 . 해키처럼 보이지만 모든 경우를 해결하는 유일한 방법이었습니다. Python2와 Python3 모두에서 작동합니다.

def proper_round(num, dec=0):
    num = str(num)[:str(num).index('.')+dec+2]
    if num[-1]>='5':
        return float(num[:-2-(not dec)]+str(int(num[-2-(not dec)])+1))
    return float(num[:-1])

테스트 :

>>> print(proper_round(1.0005,3))
1.001
>>> print(proper_round(2.0005,3))
2.001
>>> print(proper_round(3.0005,3))
3.001
>>> print(proper_round(4.0005,3))
4.001
>>> print(proper_round(5.0005,3))
5.001
>>> print(proper_round(1.005,2))
1.01
>>> print(proper_round(2.005,2))
2.01
>>> print(proper_round(3.005,2))
3.01
>>> print(proper_round(4.005,2))
4.01
>>> print(proper_round(5.005,2))
5.01
>>> print(proper_round(1.05,1))
1.1
>>> print(proper_round(2.05,1))
2.1
>>> print(proper_round(3.05,1))
3.1
>>> print(proper_round(4.05,1))
4.1
>>> print(proper_round(5.05,1))
5.1
>>> print(proper_round(1.5))
2.0
>>> print(proper_round(2.5))
3.0
>>> print(proper_round(3.5))
4.0
>>> print(proper_round(4.5))
5.0
>>> print(proper_round(5.5))
6.0
>>>
>>> print(proper_round(1.000499999999,3))
1.0
>>> print(proper_round(2.000499999999,3))
2.0
>>> print(proper_round(3.000499999999,3))
3.0
>>> print(proper_round(4.000499999999,3))
4.0
>>> print(proper_round(5.000499999999,3))
5.0
>>> print(proper_round(1.00499999999,2))
1.0
>>> print(proper_round(2.00499999999,2))
2.0
>>> print(proper_round(3.00499999999,2))
3.0
>>> print(proper_round(4.00499999999,2))
4.0
>>> print(proper_round(5.00499999999,2))
5.0
>>> print(proper_round(1.0499999999,1))
1.0
>>> print(proper_round(2.0499999999,1))
2.0
>>> print(proper_round(3.0499999999,1))
3.0
>>> print(proper_round(4.0499999999,1))
4.0
>>> print(proper_round(5.0499999999,1))
5.0
>>> print(proper_round(1.499999999))
1.0
>>> print(proper_round(2.499999999))
2.0
>>> print(proper_round(3.499999999))
3.0
>>> print(proper_round(4.499999999))
4.0
>>> print(proper_round(5.499999999))
5.0

마지막으로, 정답은 다음과 같습니다.

# Having proper_round defined as previously stated
h = int(proper_round(h))

편집 3 :

테스트 :

>>> proper_round(6.39764125, 2)
6.31 # should be 6.4
>>> proper_round(6.9764125, 1)
6.1  # should be 7

여기서 dec10 점은 9가 될 수 있고- dec+1> 5보다 큰 숫자 인 경우 9는 0이되고 1은- dec-1번째 숫자 로 이동해야합니다 .

이를 고려하면 다음과 같은 이점이 있습니다.

def proper_round(num, dec=0):
    num = str(num)[:str(num).index('.')+dec+2]
    if num[-1]>='5':
      a = num[:-2-(not dec)]       # integer part
      b = int(num[-2-(not dec)])+1 # decimal part
      return float(a)+b**(-dec+1) if a and b == 10 else float(a+str(b))
    return float(num[:-1])

전술 한 상황에서 b = 10이전 버전 하듯 CONCATENATE ab의 연결에 초래되는 10후단 0 사라지는 곳에. 이 버전은 b을 기반으로 dec올바른 캐리로 올바른 소수점 이하 자릿수로 변환 됩니다 .


답변

사용하십시오 round(x, y). 원하는 소수점 이하 자릿수로 올림합니다.

예를 들면 다음과 같습니다.

>>> round(32.268907563, 3)
32.269


답변

round(value,significantDigit)는 일반적인 솔루션이지만 반올림 값이로 끝나는 경우 수학 관점에서 예상 한대로 작동하지 않습니다 5. 5가 반올림 한 바로 다음의 자리에있는 경우 ,이 값은 때때로 예상대로 8.005반올림됩니다 (즉, 두 개의 10 진수로 반올림하면8.01 ). 부동 소수점 수학의 단점으로 인해 특정 값의 경우 대신 반올림됩니다!

>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01

기묘한.

과학의 통계에 대한 전통적인 반올림을 수행하려는 의도가 있다고 가정하면, 이는 과 같은 추가 항목이 필요할 round때 예상대로 함수를 작동 시키는 편리한 래퍼 입니다.importDecimal

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*5),2)

0.08

아하! 이를 바탕으로 함수를 만들 수 있습니다 …

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

기본적으로 이것은 사용하려는 문자열의 최소 숫자보다 작게 보장 된 값을 추가합니다 round. 소량을 추가하면 round대부분의 경우 동작을 유지 하면서 반올림되는 숫자보다 열등한 숫자가 반올림 5되는지 확인합니다.4 .

사용하는 접근 방식은 10**(-len(val)-1)시프트를 강제하기 위해 추가 할 수있는 가장 작은 숫자이므로 의도적으로 추가 .되었습니다. 또한 소수점 이하 자릿수 가 없어도 추가 한 값이 반올림을 변경하지 않도록합니다 . 더 많이 빼기 10**(-len(val))위해 조건부와 함께 사용할 수는 있지만 이 해결 방법으로 올바르게 처리 할 수있는 적용 가능한 10 진수 범위를 많이 변경하지 않으므로 항상 빼기하는 것이 더 간단합니다 . 이 방법은 값이 유형의 한계에 도달하면 실패하지만 실패하지만 거의 모든 유효 10 진수 값 범위에서 작동합니다.if (val>1)11

십진 라이브러리를 사용 하여이 작업을 수행 할 수도 있지만 제안하는 래퍼가 더 간단하고 경우에 따라 선호 될 수 있습니다.


편집 : 프린지 케이스가 특정 값에 대해서만 발생 한다고 지적한 Blckknght 에게 감사드립니다 5. 또한이 답변의 이전 버전은 반올림 하는 자리보다 숫자가 바로 열등한 경우에만5 홀수 반올림 동작이 발생 하기에 충분하지 않습니다 .


답변

긍정을 위해, 시도하십시오

int(x + 0.5)

부정적인면에서도 효과를 얻으려면 시도하십시오.

int(x + (0.5 if x > 0 else -0.5))

int()바닥 기능처럼 작동하므로이 속성을 악용 할 수 있습니다. 이것이 가장 빠른 방법입니다.


답변

IEEE 754에 규정 된대로 파이썬 만 반으로 반올림 하지 않습니까?

다시 정의하거나 “비표준”라운딩을 사용하십시오…

( https://stackoverflow.com/a/33019948/109839참조하십시오 )


답변

python3.x를 사용하는 경우 numpy를 사용할 수도 있습니다. 여기에 예제가 있습니다.

import numpy as np
x = 2.3
print(np.rint(x))
>>> 2.0


답변

솔루션이 두 번째 인수 (소수 자릿수)를 지정하지 않고 라운드를 호출합니다.

>>> round(0.44)
0
>>> round(0.64)
1

이보다 훨씬 더 나은 결과입니다

>>> int(round(0.44, 2))
0
>>> int(round(0.64, 2))
0

https://docs.python.org/3/library/functions.html#round 의 Python 설명서에서

라운드 (숫자 [, n 자리])

소수점 뒤에 n 자리 정밀도로 반올림 된 숫자를 반환합니다. ndigits가 생략되거나 None이면 입력에 가장 가까운 정수를 반환합니다.

노트

float에 대한 round ()의 동작은 놀랍습니다. 예를 들어 round (2.675, 2)는 예상 2.68 대신 2.67을 제공합니다. 이것은 버그가 아닙니다. 대부분의 소수는 정확히 부동 소수점으로 표현할 수 없다는 사실의 결과입니다. 자세한 내용은 부동 소수점 산술 : 문제 및 제한 사항을 참조하십시오.