2010-05-08 3 views
6

파이썬에서 고정밀 소수점 이하 자릿수를 얻는 방법이 있습니까?파이썬에서 십진수의 Ceil()을 얻고 싶습니까?

>>> import decimal; 
>>> decimal.Decimal(800000000000000000001)/100000000000000000000 
Decimal('8.00000000000000000001') 
>>> math.ceil(decimal.Decimal(800000000000000000001)/100000000000000000000) 
8.0 

수학은 값을 반올림

+0

저는 사실 파이썬을 처음 접했고, 어제는 사실 어제부터 시작했습니다. 내 두 번째 연습 프로그램에서이 문제를 우연히 만났습니다 (첫 번째 것은 의무적 인 "인쇄, 안녕하세요, 세계!"). 그래서 나는 이것에 대한 최선의 대답을 판단하기가 어렵다. Matthew Flaschen의 10 진수 컨텍스트 솔루션이 필자의 특별한 경우에 사용되었습니다. 하지만 다른 사람들에게 최상의 솔루션을 upvote하고 싶습니다. (특정 접근 방식이 왜 더 효과적인지 설명 할 수 있다면 나 같은 초보자에게 도움이 될 것입니다.) 나는 돌아와서 받아 들일 것입니다. – Gunjan

답변

5
x = decimal.Decimal('8.00000000000000000000001') 
with decimal.localcontext() as ctx: 
    ctx.prec=100000000000000000 
    ctx.rounding=decimal.ROUND_CEILING 
    y = x.to_integral_exact() 
+4

괜찮 으면 여기에서 컨텍스트 정밀도를 변경할 필요가 없습니다. 'to_integral_exact'도'rounding' 인자를 취합니다, 그래서 여러분은 문맥 전체를 엉망으로 만드는 것을 피할 수 있습니다. –

3

당신은 정밀도를 사용하고 컨텍스트 생성자 모드 옵션을 반올림이 작업을 수행 할 수 있습니다 비 정확한 값을 반환합니다.

ctx = decimal.Context(prec=1, rounding=decimal.ROUND_CEILING) 
ctx.divide(decimal.Decimal(800000000000000000001), decimal.Decimal(100000000000000000000)) 

편집이 : 필요에 따라 prec이 증가 할 수 있지만 당신은 .. 허용 대답을 변경하는 것을 고려한다 to_integral_exact은 간단한 솔루션입니다.

+0

완벽한 :) --- 글자 제한 완료 --- – Gunjan

+2

@ 군인, 완벽하면 왜 받아 들일 수 없습니까?! –

+0

@Alex 죄송합니다. 6 분 전에 시간을 초과해야했습니다. 알림을 주셔서 감사합니다 – Gunjan

0
>>> decimal.Context(rounding=decimal.ROUND_CEILING).quantize(
... decimal.Decimal(800000000000000000001)/100000000000000000000, 0) 
Decimal('9') 
+0

이 솔루션은 값이 큰 Decimal 인스턴스에 문제가 있음을주의하십시오. 예를 들어,'c.quantize (decimal.Decimal ('1e100'), 1)'을 컨텍스트'c'로하면, 'InvalidOperation' 예외입니다. –

0
def decimal_ceil(x): 
    int_x = int(x) 
    if x - int_x == 0: 
     return int_x 
    return int_x + 1 
18

진수 예를 x의 천장을하는 가장 직접적인 방법은 x.to_integral_exact(rounding=ROUND_CEILING)을 사용하는 것입니다. 여기서 컨텍스트를 망칠 필요가 없습니다. 이 경우 적절한 경우 InexactRounded 플래그가 설정됩니다. 플래그를 지정하지 않으려면 대신 x.to_integral_value(rounding=ROUND_CEILING)을 사용하십시오. 예 :

소수점 대부분의 방법과는 달리
>>> from decimal import Decimal, ROUND_CEILING 
>>> x = Decimal('-123.456') 
>>> x.to_integral_exact(rounding=ROUND_CEILING) 
Decimal('-123') 

to_integral_exactto_integral_value 방법은 현재 컨텍스트의 정밀도에 영향을받지 않습니다, 그래서 당신은 변화의 정밀도에 대해 걱정할 필요가 없습니다 :

>>> from decimal import getcontext 
>>> getcontext().prec = 2 
>>> x.to_integral_exact(rounding=ROUND_CEILING) 
Decimal('-123') 

그런데 파이썬 3.x에서 math.ceil은 정확히 Decimal 인스턴스가 아닌 int을 반환한다는 점을 제외하고는 원하는대로 정확하게 작동합니다. 그건 math.ceil이 Python 3의 사용자 정의 유형에 대해 과부하가 걸리기 때문입니다. Python 2에서 math.ceilDecimal 인스턴스를 float으로 간단히 변환하여 프로세스에서 정보가 손실 될 수 있으므로 잘못된 결과가 발생할 수 있습니다.

+0

완전성을 위해 : python 2.x'math.ceil'은 예상대로 작동하지 않습니다. 먼저 십진수를 부동 소수점으로 변환합니다. 그 때문에'int (ceil (D ('1.0000000000000001')))')는 파이썬 2.x에서는 1, 파이썬 3.x에서는 2로 계산됩니다. –

+0

@AntonyHatchkins : 감사합니다. 나는 그 정보를 답안에 편집했다. –

0

그냥 힘을 실어 이것을 만듭니다. 수입 수학

def lo_ceil(num, potency=0): # Use 0 for multiples of 1, 1 for multiples of 10, 2 for 100 ... 
     n = num/(10.0 ** potency) 
     c = math.ceil(n) 
     return c * (10.0 ** potency) 

lo_ceil(8.0000001, 1) # return 10 
관련 문제