Is there an easy way to convert a periodic decimal number into a fraction?

As a mathematician I like not rationalize(0.85555555555)!!

That really leaves a homemade algorithm that handles the periodic part separately? thanks for inspirations.

Albert

This question seems ill-posed to me. See that a floating point number has finite precision and so if you tried converting from a float to a fraction you could not distinguish a periodic decimal part from a finite one.

To do this conversion you can simply do:

```
julia> convert(Rational, 2.5)
5//2
julia> convert(Rational, 1/3)
6004799503160661//18014398509481984
```

But as you see converting 1/3=0.3333333333333333 to rational does not give 1//3 and in fact

```
julia> 1//3 == 1/3
false
```

Or did you have some other datatype/data structure to convert from in mind?

I agree with @abraemer .

The problem is, thereâ€™s no actual way to store an infinitely repeating decimal as a floating point number in any language. You can get somewhat close but itâ€™s just not the same. And it sounds like you rely on that.

For Julia, the number has to be a `Rational`

from the start. Which youâ€™d construct as shown above.

You ask for an easy way, of which thereâ€™s none. But a somewhat more complicated way might be to instead store the repeating digits, which is nicely finite information store as integers. Look at the operations youâ€™re thinking to apply them to and manipulate such operations to account for separate storage of the integers that repeat and the nature of their repetition. Juliaâ€™s Irrationals do something similar under the hood, storing the numerator and denominator.

If you want rational results, itâ€™s best to perform the entire calculation with rationals. The `Rational`

type in Julia propagates through all basic arithmetic. Although functions that (generally) yield irrational results (e.g., `sqrt`

, `sin`

, `exp`

) will convert their result to floats and break such a chain.

```
julia> x = 2//3
2//3
julia> y = (x * (1 + x) + 2) / 4
7//9
julia> z = sqrt(y*y) # float result, even though there *happens to be* an exact rational result
0.7777777777777778
```

You can just specify a larger tolerance and Julia will give its â€śbest guessâ€ť for a number with a smaller denominator:

```
julia> rationalize(0.85555555555, tol=1e-8)
77//90
julia> rationalize(0.33333333333, tol=1e-8)
1//3
```

(\frac{77}{90} is exactly 0.8\bar{5}).

And here is an *exact* algorithm to convert a.b\bar{c}, specified as *strings*, to a fraction (ported from the Python solution in this stackexchange discussion):

```
function decimal2rational(::Type{T}, a::AbstractString, b::AbstractString, c::AbstractString) where {T<:Integer}
czero = isempty(c) || parse(T, c) == 0
numerator = parse(T, a*b*c) - !czero * parse(T, a*b)
denominator = (T(10)^length(c) - !czero) * T(10)^length(b)
return Rational{T}(numerator, denominator)
end
decimal2rational(a::AbstractString, b::AbstractString, c::AbstractString) =
decimal2rational(Int, a, b, c)
```

For example:

```
julia> decimal2rational("0", "8", "5") # 0.8555â€¦
77//90
julia> decimal2rational("1", "", "3") # 1.333â€¦
4//3
```

You can use the package RepeatingDecimalNotations.jl.

```
julia> using RepeatingDecimalNotations
julia> rd"0.85555..."
77//90
```

The Julia language and community continues to amaze and suprise me. And Iâ€™m so happy to be proven wrong.

Thank you for your contribution. I have learnt two ideas that answer my question:

a) Indicating tolerance with tol, thanks stevengj.

b) Use of the package RepeatingDecimalNotations, thanks greatpet.

I am happy with this!

Albert