Получить Ceil() Десятичного в питоне?
Есть ли способ получить значение высокой точности десятичного числа в Python?
>>> import decimal;
>>> decimal.Decimal(800000000000000000001)/100000000000000000000
Decimal('8.00000000000000000001')
>>> math.ceil(decimal.Decimal(800000000000000000001)/100000000000000000000)
8.0
математика округляет значение и возвращает не точное значение
6 ответов
x = decimal.Decimal('8.00000000000000000000001')
with decimal.localcontext() as ctx:
ctx.prec=100000000000000000
ctx.rounding=decimal.ROUND_CEILING
y = x.to_integral_exact()
Самый прямой способ взять потолок десятичного экземпляра x
это использовать x.to_integral_exact(rounding=ROUND_CEILING)
, Там нет необходимости возиться с контекстом здесь. Обратите внимание, что это устанавливает Inexact
а также Rounded
флаги, где это уместно; если вы не хотите, чтобы флаги касались, используйте 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_exact
а также to_integral_value
Методы не зависят от точности текущего контекста, поэтому вам не нужно беспокоиться об изменении точности:
>>> from decimal import getcontext
>>> getcontext().prec = 2
>>> x.to_integral_exact(rounding=ROUND_CEILING)
Decimal('-123')
Кстати, в Python 3.x, math.ceil
работает именно так, как вы хотите, за исключением того, что он возвращает int
а не Decimal
пример. Это работает, потому что math.ceil
перегружается для пользовательских типов в Python 3. В Python 2 math.ceil
просто преобразует Decimal
экземпляр для float
Во-первых, это может привести к потере информации в процессе, что может привести к неверным результатам.
Вы можете сделать это, используя опцию точности и режима округления конструктора Context.
ctx = decimal.Context(prec=1, rounding=decimal.ROUND_CEILING)
ctx.divide(decimal.Decimal(800000000000000000001), decimal.Decimal(100000000000000000000))
РЕДАКТИРОВАТЬ: Вы должны рассмотреть вопрос об изменении принятого ответа.. Хотя prec
может быть увеличено по мере необходимости, to_integral_exact
это более простое решение.
def decimal_ceil(x):
int_x = int(x)
if x - int_x == 0:
return int_x
return int_x + 1
>>> decimal.Context(rounding=decimal.ROUND_CEILING).quantize(
... decimal.Decimal(800000000000000000001)/100000000000000000000, 0)
Decimal('9')
Просто используйте потенцию, чтобы сделать это. импорт математики
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