I'm trying to convert very large integers to decimals, then convert those decimals to Fractions, and then convert the Fraction back to a decimal. I'm using the fractions and decimal packages to try and avoid floating point imprecision, however the accuracy still tapers off rather quickly. Is there any way to fix this / other ways of doing this?
import fractions
import decimal
def convert(exampleInt):
power_of_10 = len(str(exampleInt))
decimal.getcontext().prec = 10000
exampleDecimal = decimal.Decimal(exampleInt) / (decimal.Decimal(10) ** power_of_10)
exampleFraction = fractions.Fraction(str(exampleDecimal)).limit_denominator()
backToDecimal = exampleFraction.numerator / decimal.Decimal(exampleFraction.denominator)
print(f"backToDecimal: {backToDecimal}")
convert(34163457536856478543908582348965743529867234957893246783427568734742390675934285342)
Which outputs: .341634575369123189552597490138153768602695082851231192155069838....
It's because of calling the limit_denominator()
. Also it's quite inefficient to convert using an intermediate string.
Convert a Decimal
object into a Fraction
object using the constructor like the following.(It's Mark Dickinson's solution.)
import fractions
import decimal
decimal.getcontext().prec = 100
d = decimal.Decimal(34163457536856478543908582348965743529867234957893246783427568734742390675934285342)
d = d / 10**(d.adjusted() + 1)
f = fractions.Fraction(d) # This is equivalent to Fraction(*d.as_integer_ratio())
d2 = decimal.Decimal(f.numerator) / f.denominator
assert(d2 == d)