How to convert incredibly long decimals to fractions and back with high precision

Question:

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….

Asked By: Einsneins

||

Answers:

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)
Answered By: relent95