Python의 소수점 정밀도 및 반올림

11824 단어 python
프로젝트에서 정밀도가 필요한 경우 decimaldecimal module 을 사용해야 합니다. float 데이터 유형에는 floating issues 에서 볼 수 있듯이 몇 가지 문제와 제한이 있기 때문입니다.

여기에 설명된 대로 decimal를 사용하려면decimal tutorial:

from decimal import Decimal


number = Decimal("0.976815352")


알겠습니다. 특정 정밀도를 원하면 어떻게 해야 합니까? float를 사용하면 다음과 같습니다.

number = 0.976815352
rounded_number = (number, '.2f')
# or
print(f"rounded_number = {x:.2f}")

decimal 포함:

from decimal import getcontext, Decimal


getcontext().prec = 3
result = Decimal("0.976815352") / Decimal("2.42532")

print(result)
# 0.403


0.403을 줄 것입니다. 괜찮아 보인다. 그러나 시도하면

result = Decimal('3.1415926535') + Decimal('2.7182818285')

print(result)
# 5.86


5.86을 줄 것이고 아마도 wth라고 말할 것입니다. decimal 에서 정밀도는 소수점/점 앞의 숫자를 포함하는 정밀도를 의미하기 때문입니다.

그렇다면 어떻게 천 단위의 소수 자릿수를 알 수 있습니까? ∞에서 0.00000001 사이의 가격은?

많은 연구(일명 stackoverflowing) 후에 다음을 발견했습니다. gist .

정밀도 및 반올림



옵션 1 - round()를 사용하여 소수를 반올림




from decimal import Decimal


result = Decimal('3.1415926535') + Decimal('2.7182818285')
result = round(x, 2)

print(result)
# Output: 5.86


옵션 2 - 10진수 모듈의 반올림 사용




from decimal import Decimal, ROUND_HALF_UP
# All options for rounding:
# ROUND_05UP       ROUND_DOWN       ROUND_HALF_DOWN  ROUND_HALF_UP
# ROUND_CEILING    ROUND_FLOOR      ROUND_HALF_EVEN  ROUND_UP


result = Decimal('3.1415926535') + Decimal('2.7182818285')
result = Decimal(our_value.quantize(Decimal('.01'), rounding=ROUND_HALF_UP))

print(result)
# Output: 5.86


"0.01"을 소수점 이하 2자리로 반올림하여 사용합니다.

옵션 3 - Getcontext 정밀도 설정



우리는 처음에 이것을 보았고 우리에게 다음을 주었습니다.

from decimal import getcontext, Decimal


getcontext().prec = 2
result = Decimal('3.1415926535') + Decimal('2.7182818285')

print(result)


혼란 때문에 선택하지 않는 것이 좋습니다.

옵션 4(기본 옵션)



gist에 대한 몇 가지 의견을 읽은 후 궁극적인 해결책을 찾았습니다. 그것
py-moneyd 라이브러리에서 제공:

def round(self: M, ndigits: Optional[int] = 0) -> M:
    """
    Rounds the amount using the current ``Decimal`` rounding algorithm.
    """
    if ndigits is None:
        ndigits = 0
    return self.__class__(
        amount=self.amount.quantize(Decimal("1e" + str(-ndigits))),
        currency=self.currency,
    )


일반화를 위해 약간의 조정을 수행하고 다음 도우미 메서드를 작성했습니다.

from decimal import Decimal


class Acccounting:
    def round(self, amount: str, ndigits: int) -> Decimal:
        """ Rounds the amount using the current `Decimal` rounding algorithm. """
        if ndigits is None:
            ndigits = 0
        return Decimal(
            Decimal(amount).quantize(Decimal("1e" + str(-ndigits))),
        )


이 도우미로 2라운드를 진행하려면:

from decimal import Decimal
from .helpers import Acccounting


result = Decimal('3.1415926535') + Decimal('2.7182818285')
result = Acccounting().round(amount=result, ndigits=2)

print(result)
# Output: 5.86


@jackiekazil 감사합니다!

모두 완료되었습니다!

좋은 웹페이지 즐겨찾기