Округление Decimal
Есть число и 40 знаков после запятой. Последнюю цифру дробной части нужно округлить;один раз вверх и один раз вниз. Запускаю
Num = Decimal(123.1234567890123456789012345678901234567890)
Delta = Decimal(1/10000000000000000000000000000000000000000)
NumUp = Num + Delta
NumDown = Num - Delta
print('Delta = ' '%.40f' % Delta)
print('NumUp = ' '%.40f' % NumUp)
print('Num = ' '%.40f' % Num)
print('NumDown = ' '%.40f' % NumDown)
Ожидую получить:
Delta = 0.0000000000000000000000000000000000000001
NumUp = 123.1234567890123456789012345678901234567891
Num = 123.1234567890123456789012345678901234567890
NumDown = 123.1234567890123456789012345678901234567889
А получаю:
Delta = 0.0000000000000000000000000000000000000001
NumUp = 123.1234567890123514644074020907282829284668
Num = 123.1234567890123514644074020907282829284668
NumDown = 123.1234567890123514644074020907282829284668
Как добиться необходимого округления?
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
У вас точность теряется три раза:
- при создании
Decimalизfloat - при операциях с
Decimal - при преобразовании
Decimalвfloatдля печати
Можно всё исправить таким образом:
from decimal import *
# по умолчанию точность работы с Decimal всего 28 знаков, нам нужно задать "с запасом"
getcontext().prec = 43
# создаём Decimal из литерала, а не из float, чтобы не потерять точность!
Num = Decimal('123.1234567890123456789012345678901234567890')
# можно создавать Decimal и таким образом, главное, что не из float
Delta = 1 / Decimal(10000000000000000000000000000000000000000)
NumUp = Num + Delta
NumDown = Num - Delta
# вывод на печать делаем без float-формата, средствами форматирования самого Decimal
print('Delta =', Delta)
print('NumUp =', NumUp)
print('Num =', Num)
print('NumDown =', NumDown)
Delta = 1E-40
NumUp = 123.1234567890123456789012345678901234567891
Num = 123.1234567890123456789012345678901234567890
NumDown = 123.1234567890123456789012345678901234567889