QUESTION:
I would like to convert floats into a ratio of integers in simplest form. (Not a duplicate of this question, see "EDIT" below). For example, 0.1
= 1, 10
, 0.66666...
= 2, 3
, etc. In the code snippet below, I try doing this for x = 0.1, 0.2, ..., 1.0
using this default function; the method only works successfully for x = 0.5
and x = 1.0
. Why does this algorithm fail for other values of x
and what is a better method to do this? In case it is relevant, my use-case will be for dx ~ 0.0005 = x[1] - x[0]
for 0.0005 < x 10.0
.
CODE:
import numpy as np
f = np.vectorize(lambda x : x.as_integer_ratio())
x = np.arange(0.1, 1.1, 0.1)
nums, dens = f(x)
for xi, numerator, denominator in zip(x, nums, dens):
print("\n .. {} = {} / {}\n".format(xi, numerator, denominator))
OUTPUT:
.. 0.1 = 3602879701896397 / 36028797018963968
.. 0.2 = 3602879701896397 / 18014398509481984
.. 0.30000000000000004 = 1351079888211149 / 4503599627370496
.. 0.4 = 3602879701896397 / 9007199254740992
.. 0.5 = 1 / 2
.. 0.6 = 5404319552844595 / 9007199254740992
.. 0.7000000000000001 = 6305039478318695 / 9007199254740992
.. 0.8 = 3602879701896397 / 4503599627370496
.. 0.9 = 8106479329266893 / 9007199254740992
.. 1.0 = 1 / 1
EDIT:
This is not really a duplicate. Both methods of the accepted answer in the original question fail a basic use-case from my MWE. To show that the Fraction
module gives the same error:
import numpy as np
from fractions import Fraction
f = np.vectorize(lambda x : Fraction(x))
x = np.arange(0.1, 1.1, 0.1)
y = f(x)
print(y)
## OUTPUT
[Fraction(3602879701896397, 36028797018963968)
Fraction(3602879701896397, 18014398509481984)
Fraction(1351079888211149, 4503599627370496)
Fraction(3602879701896397, 9007199254740992) Fraction(1, 2)
Fraction(5404319552844595, 9007199254740992)
Fraction(6305039478318695, 9007199254740992)
Fraction(3602879701896397, 4503599627370496)
Fraction(8106479329266893, 9007199254740992) Fraction(1, 1)]