-1

Importing Fraction from fractions to give a fractional representation of a real number, but giving responses quite complicated which seems very simple by the paper-pen method.
Fractions(.2) giving answer 3602879701896397/18014398509481984,
which is 0.20000000000000001110223024625157, almost .2, but I want it to be simply 1/5.
I know there's limit() for this use, but what I simply required is smallest numerator and denominator which gives the exact real number bcoz I am dealing with a lot of numbers in a big range so i cant use same limit() argument for all.

Devendra Sharma
  • 47
  • 1
  • 1
  • 9
  • 2
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Jongware Feb 05 '18 at 12:57
  • This is not the duplicate of the question you specified above, I want to know the reason behind not giving 1/5 but instead 3602879701896397/18014398509481984. Completely different. – Devendra Sharma Feb 05 '18 at 13:38
  • It is not different. That post explains why there is no way to store `0.2` in a floating point number. *That* is the reason. – Jongware Feb 05 '18 at 13:47
  • You will need to provide the input as a string (i.e. `Fraction('.2')`), as float values themselves suffer from the "brokenness" as pointed out by others, while `str` does not - [the documentation](https://docs.python.org/3/library/fractions.html) pointed this out and has various examples demonstrating this issue. – metatoaster Jun 20 '22 at 04:41

2 Answers2

1

You can use the Fraction class to represent 0.2, and you can access the numerator and denominator as follows:

>>> from fractions import Fraction
>>> f = Fraction(1, 5)
>>> f.numerator
1
>>> f.denominator
5

Hope it helps.

Szabolcs
  • 3,990
  • 18
  • 38
0

Your strange output results from float point problems. You can in certain cases overcome this by limiting the denominator with Fraction.limit_denominator(). This procedure can of course also cause rounding errors, if the real value of the denominator is larger than the threshold you use. The default value for this threshold is 1,000,000, but you can also use smaller values.

>>> import fractions
>>> print(fractions.Fraction(0.1))
3602879701896397/36028797018963968
>>> # lower the threshold to 1000
>>> print(fractions.Fraction(0.1).limit_denominator(1000))
1/10
>>> # alternatively, use a str representation as per documentation/examples
>>> print(fractions.Fraction('0.1'))
1/10
>>> # won't work for smaller fractions, use default of 1,000,000 instead
>>> print(fractions.Fraction(0.00001).limit_denominator(1000))
0
>>> print(fractions.Fraction(0.00001).limit_denominator())
1/100000

Of course, as explained in the first sentence, there are precision limitations due to the way float numbers are stored. If you have numbers in the magnitude of 10^9, you won't get an accurate representation of 10 digits in the fractional part as

a = 1234567890.0987654321
print(a)

demonstrates. But you might ask yourself, if you really need an accuracy of 10^-15, if your input doesn't reflect this accuracy. If you want to have a higher precision, you have to use the decimal module right from the start with increased precision level throughout all mathematical operations. Even better is to take care of numerators and denominators as integer values from the beginning - in Python integer values are theoretically not restricted in size

metatoaster
  • 17,419
  • 5
  • 55
  • 66
Mr. T
  • 11,960
  • 10
  • 32
  • 54
  • It is very likely that this answer will satisfy to OP (+1). Nevertheless, "dealing with a lot of numbers in a big range so i cant use same limit() argument for all.", so perhaps that the 1000. in the limit_denominator will not work for all values. – Florian Feb 05 '18 at 12:39
  • Yeah, I dealt with ques. the same way you have shown, but since I am having numbers in the range of 10^9. This might not perform good enough. – Devendra Sharma Feb 05 '18 at 13:42
  • 1
    @Florian The 1000 are an example to show, that you don't have to rely on the default value of 1,000,000, if you can expect smaller values. I will update the answer and add that this is an example. – Mr. T Feb 05 '18 at 15:31