Не полная/укороченная дробная часть

Запускаю следующий код

import math
from decimal import Decimal
from decimal import *

SinAlpha = ((0.5-0.8)/(-0.45))
print('SinAlpha =', '%.64f' % SinAlpha)
Alpha = Decimal(math.degrees(math.asin(SinAlpha)))
print('Alpha    =', Alpha)
Fraction = Decimal(Decimal(Alpha) - Decimal(int(Alpha)))
print('Fraction =', Fraction)

и получаю

SinAlpha = 0.6666666666666667406815349750104360282421112060546875000000000000
Alpha    = 41.8103148957786032724470715038478374481201171875
Fraction = 0.8103148957786032724470715038

Почему Fraction урезан? Как сделать чтоб количество знаков после запятой в Fraction было бы таким же как и у Alpha?

Спасибо


Ответы (1 шт):

Автор решения: CrazyElf
import math
from decimal import Decimal
from decimal import *

getcontext().prec = 64 # устанавливаем точность работы с Decimal

SinAlpha = ((0.5-0.8)/(-0.45))
print('SinAlpha =', SinAlpha)
Alpha = Decimal(math.degrees(math.asin(SinAlpha)))
print('Alpha    =', Alpha)
Fraction = Decimal(Decimal(Alpha) - Decimal(int(Alpha)))
print('Fraction =', Fraction)

Результат:

SinAlpha = 0.6666666666666667
Alpha    = 41.8103148957786032724470715038478374481201171875
Fraction = 0.8103148957786032724470715038478374481201171875

По умолчанию точность работы с Decimal - 28 знаков. Так что всё, что вы видели дальше 28 знака - это были артефакты представления float.

Почему же при точности 28 знаков Alpha и Fraction печатались с разным числом знаков после запятой? А вот почему:

print(Alpha.as_integer_ratio())
print(Fraction.as_integer_ratio())

(2942139352888619, 70368744177664)
(4051574478893016362235357519, 5000000000000000000000000000)

Fraction просто хорошо разложилась на дробь и при делении первого числа на второе не получалось лишнего "хвоста" в конце, всё заканчивалось 28 знаками после запятой. А вот про Alpha такое сказать нельзя, поэтому у Alpha можно было напечатать и больше знаков, думаю, вплоть до бесконечности, при желании.

→ Ссылка