# Decimal2rational

**URL:** <https://discourse.julialang.org/t/decimal2rational/117147>\
**Category:** General Usage\
**Tags:** numbers\
**Created:** [July 17, 2024, 2:58pm UTC](https://discourse.julialang.org/t/decimal2rational/117147 "2024-07-17T14:58:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mefi](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@mefi](https://discourse.julialang.org/u/mefi)\
**Post date:** [July 17, 2024, 2:58pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/1 "2024-07-17T14:58:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [July 17, 2024, 3:33pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/2 "2024-07-17T15:33:36Z")

</div>

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-repl
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-repl
julia> 1//3 == 1/3
false

```

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

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [July 17, 2024, 3:45pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/3 "2024-07-17T15:45:05Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [July 17, 2024, 3:54pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/4 "2024-07-17T15:54:12Z")

</div>

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

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 17, 2024, 3:56pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/5 "2024-07-17T15:56:52Z")

</div>

> [@kapple](#):
>
> You ask for an easy way, of which there’s none.

You can just specify a larger tolerance and Julia will give its “best guess” for a number with a smaller denominator:

```julia-auto
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](https://codegolf.stackexchange.com/questions/17907/convert-a-repeated-decimal-to-a-fraction)):

```julia-auto
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-auto
julia> decimal2rational("0", "8", "5") # 0.8555…
77//90

julia> decimal2rational("1", "", "3") # 1.333…
4//3

```

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [July 17, 2024, 4:07pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/6 "2024-07-17T16:07:45Z")

</div>

You can use the package RepeatingDecimalNotations.jl.

```julia
julia> using RepeatingDecimalNotations

julia> rd"0.85555..."
77//90

```

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [July 17, 2024, 4:09pm UTC](https://discourse.julialang.org/t/decimal2rational/117147/7 "2024-07-17T16:09:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mefi](https://avatars.discourse-cdn.com/v4/letter/m/54ee81/32.png) [@mefi](https://discourse.julialang.org/u/mefi)\
**Post date:** [July 18, 2024, 8:42am UTC](https://discourse.julialang.org/t/decimal2rational/117147/8 "2024-07-18T08:42:29Z")

</div>

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
