Вот несколько рецептов, которые служат служебными функциями и демонстрируют способы работы с классом decimal.Decimal()
:
from decimal import Decimal, getcontext def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg=''): """Преобразование десятичной дроби в строку формата денег. places: Требуемое количество знаков после запятой curr: Необязательный символ валюты перед знаком (может быть пустым) sep: Необязательный разделитель групп (запятая, точка, пробел или пусто) dp: Индикатор десятичной точки (запятая или точка) pos: Необязательный знак для положительных чисел: «+», пробел или пусто neg: дополнительный знак для отрицательных чисел: '-', '(', пробел или пусто trailneg:опциональный трейлинг-минус: '-', ')', пробел или пусто >>> d = Decimal('-1234567.8901') >>> moneyfmt(d, curr='$') '-$1,234,567.89' >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-') '1.234.568-' >>> moneyfmt(d, curr='$', neg='(', trailneg=')') '($1,234,567.89)' >>> moneyfmt(Decimal(123456789), sep=' ') '123 456 789.00' >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>') '<0.02>' """ q = Decimal(10) ** -places # 2 places --> '0.01' sign, digits, exp = value.quantize(q).as_tuple() result = [] digits = list(map(str, digits)) build, next = result.append, digits.pop if sign: build(trailneg) for i in range(places): build(next() if digits else '0') if places: build(dp) if not digits: build('0') i = 0 while digits: build(next()) i += 1 if i == 3 and digits: i = 0 build(sep) build(curr) build(neg if sign else pos) return ''.join(reversed(result))
from decimal import Decimal, getcontext def pi(): """Вычислить Pi с текущей точностью. >>> print(pi()) 3.141592653589793238462643383 """ getcontext().prec += 2 # extra digits for intermediate steps three = Decimal(3) # substitute "three=3.0" for regular floats lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24 while s != lasts: lasts = s n, na = n+na, na+8 d, da = d+da, da+32 t = (t * n) / d s += t getcontext().prec -= 2 return +s # unary plus applies the new precision
е
в степень х
. Тип результата соответствует типу ввода:from decimal import Decimal, getcontext def exp(x): """Получить е, возведенное в степень х. Тип результата соответствует типу ввода. >>> print(exp(Decimal(1))) 2.718281828459045235360287471 >>> print(exp(Decimal(2))) 7.389056098930650227230427461 >>> print(exp(2.0)) 7.38905609893 >>> print(exp(2+0j)) (7.38905609893+0j) """ getcontext().prec += 2 i, lasts, s, fact, num = 0, 0, 1, 1, 1 while s != lasts: lasts = s i += 1 fact *= i num *= x s += num / fact getcontext().prec -= 2 return +s
х
, измеренный в радианах:from decimal import Decimal, getcontext def cos(x): """Косинус `х`, измеренный в радианах Приближение ряда Тейлора работает лучше всего при небольшом значении x. Для больших значений сначала вычислите x = x % (2 * pi). >>> print(cos(Decimal('0.5'))) 0.8775825618903727161162815826 >>> print(cos(0.5)) 0.87758256189 >>> print(cos(0.5+0j)) (0.87758256189+0j) """ getcontext().prec += 2 i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1 while s != lasts: lasts = s i += 2 fact *= i * (i-1) num *= x * x sign *= -1 s += num / fact * sign getcontext().prec -= 2 return +s
х
, измеренный в радианах:from decimal import Decimal, getcontext def sin(x): """Синус х, измеренный в радианах. Приближение ряда Тейлора работает лучше всего при небольшом значении x. Для больших значений сначала вычислите x = x % (2 * pi). >>> print(sin(Decimal('0.5'))) 0.4794255386042030002732879352 >>> print(sin(0.5)) 0.479425538604 >>> print(sin(0.5+0j)) (0.479425538604+0j) """ getcontext().prec += 2 i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1 while s != lasts: lasts = s i += 2 fact *= i * (i-1) num *= x * x sign *= -1 s += num / fact * sign getcontext().prec -= 2 return +s