복붙노트

[PYTHON] 파이썬에서 round ()가 제대로 반올림되지 않는 것 같습니다.

PYTHON

파이썬에서 round ()가 제대로 반올림되지 않는 것 같습니다.

round () 함수에 대한 설명서에서는 숫자와 소수점 이하의 위치를 ​​반올림하여 전달한다고 명시합니다. 따라서 다음을 수행해야합니다.

n = 5.59
round(n, 1) # 5.6

그러나 실제로, 좋은 오래된 부동 소수점 이상한 것들이 들끓고 있습니다.

5.5999999999999996

UI를 위해 5.6을 표시해야합니다. 나는 인터넷 주위를 샅샅이 뒤졌고, 이것이 나의 파이썬 구현에 의존한다는 몇몇 문서를 발견했다. 불행히도, 이것은 내 Windows dev 컴퓨터와 내가 시도한 각 Linux 서버에서 발생합니다. 여기도 참조하십시오.

나 자신의 원형 라이브러리를 만드는 것의 부족한 점이 있습니다.

해결법

  1. ==============================

    1.저장 방법을 도울 수는 없지만 적어도 형식은 올바르게 작동합니다.

    저장 방법을 도울 수는 없지만 적어도 형식은 올바르게 작동합니다.

    '%.1f' % round(n, 1) # gives you '5.6'
    
  2. ==============================

    2.서식을 지정하지 않아도 올바르게 작동합니다.

    서식을 지정하지 않아도 올바르게 작동합니다.

    "%.1f" % n
    
  3. ==============================

    3.Decimal 모듈을 사용하면 'round'함수를 사용하지 않고 근사값을 계산할 수 있습니다. 통화 애플리케이션을 작성할 때 특히 반올림을 위해 사용한 것은 다음과 같습니다.

    Decimal 모듈을 사용하면 'round'함수를 사용하지 않고 근사값을 계산할 수 있습니다. 통화 애플리케이션을 작성할 때 특히 반올림을 위해 사용한 것은 다음과 같습니다.

    Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP)
    

    16.20 인 10 진수를 반환합니다.

  4. ==============================

    4.라운드 (5.59, 1)가 잘 작동합니다. 문제는 5.6이 2 진 부동 소수점으로 정확하게 표현 될 수 없다는 것입니다.

    라운드 (5.59, 1)가 잘 작동합니다. 문제는 5.6이 2 진 부동 소수점으로 정확하게 표현 될 수 없다는 것입니다.

    >>> 5.6
    5.5999999999999996
    >>> 
    

    Vinko가 말했듯이 문자열 형식을 사용하여 표시를 반올림 할 수 있습니다.

    파이썬에는 필요한 경우 십진수 산술을위한 모듈이 있습니다.

  5. ==============================

    5.그냥 라운드 (n, 1) 대신에 str (round (n, 1))을하면 '5.6'이됩니다.

    그냥 라운드 (n, 1) 대신에 str (round (n, 1))을하면 '5.6'이됩니다.

  6. ==============================

    6.데이터 유형을 정수로 전환 할 수 있습니다.

    데이터 유형을 정수로 전환 할 수 있습니다.

    >>> n = 5.59
    >>> int(n * 10) / 10.0
    5.5
    >>> int(n * 10 + 0.5) 
    56
    

    로캘의 소수 구분 기호를 삽입하여 숫자를 표시합니다.

    그러나 지미의 대답이 더 좋습니다.

  7. ==============================

    7.부동 소수점 수학은 경미하지만 귀찮은 정밀도 부정확성에 취약합니다. 정수 또는 고정 소수점으로 작업 할 수 있다면 정밀도가 보장됩니다.

    부동 소수점 수학은 경미하지만 귀찮은 정밀도 부정확성에 취약합니다. 정수 또는 고정 소수점으로 작업 할 수 있다면 정밀도가 보장됩니다.

  8. ==============================

    8.Decimal 모듈 살펴보기

    Decimal 모듈 살펴보기

    십진법은 부동 소수점 연산이 필요한 응용 프로그램을 쉽게 작성하고 그러한 결과를 사람이 읽을 수있는 형식 (예 : 회계)으로 표시해야하는 작업을 제공합니다.

  9. ==============================

    9.sprintf와 비슷한 문자열 형식 연산자 %를 사용할 수 있습니다.

    sprintf와 비슷한 문자열 형식 연산자 %를 사용할 수 있습니다.

    mystring = "%.2f" % 5.5999
    
  10. ==============================

    10.빨판을 지어 라.

    빨판을 지어 라.

    print '%.1f' % 5.59  # returns 5.6
    
  11. ==============================

    11.참으로 큰 문제입니다. 다음 코드를 사용해보십시오.

    참으로 큰 문제입니다. 다음 코드를 사용해보십시오.

    print "%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),)
    

    4.85를 표시합니다. 그럼 당신은 :

    print "Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),)
    

    4.8을 보여줍니다. 정확한 답은 4.85이지만 손으로 ​​계산합니까? 시도 할 경우 :

    print "Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),)
    

    당신은 진상을 볼 수 있습니다 : 부동 소수점은 분모의 가장 가까운 유한 합으로 저장됩니다. 분모의 분모는 2의 제곱입니다.

  12. ==============================

    12.완벽하게 작동합니다.

    완벽하게 작동합니다.

    format(5.59, '.1f') # to display
    float(format(5.59, '.1f')) #to round
    
  13. ==============================

    13.내가 뭐하는 거지:

    내가 뭐하는 거지:

    int(round( x , 0))
    

    이 경우 먼저 단위 수준에서 올바르게 반올림 한 다음 부동 소수점을 인쇄하지 않도록 정수로 변환합니다.

    그래서

    >>> int(round(5.59,0))
    6
    

    이 답변은 문자열을 형식화하는 것보다 효과적이며 둥근 기능을 사용하는 것이 더 의미가 있다고 생각합니다.

  14. ==============================

    14.여기 내가 라운드가 실패하는 것을 볼 수 있습니다. 이 두 숫자를 하나의 소수점으로 반올림하고 싶다면 어떻게해야할까요? 23.45 23.55 제 교육은 이것들을 반올림하여 얻는 것이 었습니다 : 23.4 23.6 앞의 숫자가 홀수 인 경우에 반올림해야한다는 "규칙", 앞의 숫자가 짝수 인 경우 반올림하지 말아야한다는 것입니다. 파이썬의 round 함수는 단순히 5를 잘라 버립니다.

    여기 내가 라운드가 실패하는 것을 볼 수 있습니다. 이 두 숫자를 하나의 소수점으로 반올림하고 싶다면 어떻게해야할까요? 23.45 23.55 제 교육은 이것들을 반올림하여 얻는 것이 었습니다 : 23.4 23.6 앞의 숫자가 홀수 인 경우에 반올림해야한다는 "규칙", 앞의 숫자가 짝수 인 경우 반올림하지 말아야한다는 것입니다. 파이썬의 round 함수는 단순히 5를 잘라 버립니다.

  15. ==============================

    15.암호:

    암호:

    x1 = 5.63
    x2 = 5.65
    print(float('%.2f' % round(x1,1)))  # gives you '5.6'
    print(float('%.2f' % round(x2,1)))  # gives you '5.7'
    

    산출:

    5.6
    5.7
    
  16. ==============================

    16.문제는 마지막 숫자가 5 일 때만입니다. 0.045는 내부적으로 0.044999999999999 ...로 저장됩니다. 마지막 숫자를 6으로 증가시키고 반올림합니다. 이렇게하면 원하는 결과를 얻을 수 있습니다.

    문제는 마지막 숫자가 5 일 때만입니다. 0.045는 내부적으로 0.044999999999999 ...로 저장됩니다. 마지막 숫자를 6으로 증가시키고 반올림합니다. 이렇게하면 원하는 결과를 얻을 수 있습니다.

    import re
    
    
    def custom_round(num, precision=0):
        # Get the type of given number
        type_num = type(num)
        # If the given type is not a valid number type, raise TypeError
        if type_num not in [int, float, Decimal]:
            raise TypeError("type {} doesn't define __round__ method".format(type_num.__name__))
        # If passed number is int, there is no rounding off.
        if type_num == int:
            return num
        # Convert number to string.
        str_num = str(num).lower()
        # We will remove negative context from the number and add it back in the end
        negative_number = False
        if num < 0:
            negative_number = True
            str_num = str_num[1:]
        # If number is in format 1e-12 or 2e+13, we have to convert it to
        # to a string in standard decimal notation.
        if 'e-' in str_num:
            # For 1.23e-7, e_power = 7
            e_power = int(re.findall('e-[0-9]+', str_num)[0][2:])
            # For 1.23e-7, number = 123
            number = ''.join(str_num.split('e-')[0].split('.'))
            zeros = ''
            # Number of zeros = e_power - 1 = 6
            for i in range(e_power - 1):
                zeros = zeros + '0'
            # Scientific notation 1.23e-7 in regular decimal = 0.000000123
            str_num = '0.' + zeros + number
        if 'e+' in str_num:
            # For 1.23e+7, e_power = 7
            e_power = int(re.findall('e\+[0-9]+', str_num)[0][2:])
            # For 1.23e+7, number_characteristic = 1
            # characteristic is number left of decimal point.
            number_characteristic = str_num.split('e+')[0].split('.')[0]
            # For 1.23e+7, number_mantissa = 23
            # mantissa is number right of decimal point.
            number_mantissa = str_num.split('e+')[0].split('.')[1]
            # For 1.23e+7, number = 123
            number = number_characteristic + number_mantissa
            zeros = ''
            # Eg: for this condition = 1.23e+7
            if e_power >= len(number_mantissa):
                # Number of zeros = e_power - mantissa length = 5
                for i in range(e_power - len(number_mantissa)):
                    zeros = zeros + '0'
                # Scientific notation 1.23e+7 in regular decimal = 12300000.0
                str_num = number + zeros + '.0'
            # Eg: for this condition = 1.23e+1
            if e_power < len(number_mantissa):
                # In this case, we only need to shift the decimal e_power digits to the right
                # So we just copy the digits from mantissa to characteristic and then remove
                # them from mantissa.
                for i in range(e_power):
                    number_characteristic = number_characteristic + number_mantissa[i]
                number_mantissa = number_mantissa[i:]
                # Scientific notation 1.23e+1 in regular decimal = 12.3
                str_num = number_characteristic + '.' + number_mantissa
        # characteristic is number left of decimal point.
        characteristic_part = str_num.split('.')[0]
        # mantissa is number right of decimal point.
        mantissa_part = str_num.split('.')[1]
        # If number is supposed to be rounded to whole number,
        # check first decimal digit. If more than 5, return
        # characteristic + 1 else return characteristic
        if precision == 0:
            if mantissa_part and int(mantissa_part[0]) >= 5:
                return type_num(int(characteristic_part) + 1)
            return type_num(characteristic_part)
        # Get the precision of the given number.
        num_precision = len(mantissa_part)
        # Rounding off is done only if number precision is
        # greater than requested precision
        if num_precision <= precision:
            return num
        # Replace the last '5' with 6 so that rounding off returns desired results
        if str_num[-1] == '5':
            str_num = re.sub('5$', '6', str_num)
        result = round(type_num(str_num), precision)
        # If the number was negative, add negative context back
        if negative_number:
            result = result * -1
        return result
    
  17. ==============================

    17.는 어때:

    는 어때:

    round(n,1)+epsilon
    
  18. from https://stackoverflow.com/questions/56820/round-in-python-doesnt-seem-to-be-rounding-properly by cc-by-sa and MIT license