Design

Types that represents repeating decimals

There are three types that represents a repeating decimal number; String, Rational, and RepeatingDecimal.

  • Rational{T}
    • Stores a numerator and a denominator as T<:Real.
    • The representation is unique.
    • e.g. 4111111//33300
  • String
    • Stores characters that can represent repeating decimals directly.
    • The representation is not unique.
    • e.g. "123.45(678)", "123.456(786)", "123.456_786_786(786_786)"
  • RepeatingDecimal
    • Stores sign::Bool, finite_part::BigInt, repeat_part::BigInt, point_position::Int, and period::Int to represent a repeating decimal.
    • The representation is not unique.
    • e.g. RepeatingDecimal(true, 12345, 678, 2, 3), RepeatingDecimal(true, 123456, 786, 3, 3), RepeatingDecimal(true, 123456_786_786, 786_786, 9, 6)
julia> RepeatingDecimal(true, 12345, 678, 2, 3)       2|--|---|3
    +123.45(678)
----------- --------------
Finite part Repeating part
julia> RepeatingDecimal(true, 123456, 786, 3, 3) 3|---|---|3 +123.456(786) ----------- -------------- Finite part Repeating part
julia> RepeatingDecimal(true, 123456_786_786, 786_786, 9, 6) 9|---------|------|6 +123.456786786(786786) -------------- -------------- Finite part Repeating part

Converting functions: stringify, rationalify

graph LR A -- "RepeatingDecimal" --> C A[String] -- "rationalify" --> B[Rational] B -- "RepeatingDecimal" --> C[RepeatingDecimal] C -- "rationalify" --> B B -- "stringify" --> A C -- "stringify" --> A
  • We avoided adding methods to Base.string and Base.rationalize not to induce type piracy.
  • These functions are not exported because the names of these functions does not imply relation to repeating decimals. Please use them like the following in your code.
    • RepeatingDecimalNotations.stringify(...)
    • import RepeatingDecimalNotations: stringify
    • using RepeatingDecimalNotations: stringify
julia> using RepeatingDecimalNotations
julia> using RepeatingDecimalNotations: stringify, rationalify
julia> str = "123.45(678)""123.45(678)"
julia> rd = RepeatingDecimal(true,12345,678,2,3) 2|--|---|3 +123.45(678) ----------- -------------- Finite part Repeating part
julia> r = 4111111//333004111111//33300
julia> str == stringify(rd) == stringify(r)true
julia> rd == RepeatingDecimal(str) == RepeatingDecimal(r)true
julia> r == rationalify(str) == rationalify(rd)true

Subtypes of RepeatingDecimalNotation

There are several supported notations[Notations] for repeating decimals.

julia> subtypes(RepeatingDecimalNotation)4-element Vector{Any}:
 DotsNotation
 EllipsisNotation
 ParenthesesNotation
 ScientificNotation

ParenthesesNotation (Default)

  • 😊 Common notations in some regions.
  • 😆 Easy to input.
  • 😇 May conflict with Julia syntax[Conflict].

\[123.45(678)\]

julia> rd"123.45(678)"4111111//33300
julia> no = ParenthesesNotation()ParenthesesNotation()
julia> stringify(no, 1//11)"0.(09)"
julia> rationalify(no, "123.45(678)")4111111//33300

DotsNotation

  • 😊 Common notations in some regions.
  • 😁 Does not break digit positions.
  • 😂 Requires more typings \dot[TAB] and correct font environment.

\[123.45\dot{6}7\dot{8}\]

julia> rd"123.456̇78̇"4111111//33300
julia> no = DotsNotation()DotsNotation()
julia> stringify(no, 1//11)"0.0̇9̇"
julia> rationalify(no, "123.456̇78̇")4111111//33300

Note that the above code block may not show \dot (\u0307) correctly. If you are using JuliaMono v0.053 or later, the characters will be rendered correctly like this[JuliaMono196]:

ScientificNotation

  • 😉 Easy to combine with exponential notation.
  • 🥲 Not much common notation[r_notation].

\[1.2345\text{r}678\text{e}2\]

julia> rd"123.45r678"4111111//33300
julia> no = ScientificNotation()ScientificNotation()
julia> stringify(no, 1//11)"0.r09"
julia> rationalify(no, "123.45r678")4111111//33300
julia> rd"1.2345r678e2" # Exponent term is supported.4111111//33300

EllipsisNotation

  • 🤩 You don't have to specify the repeating decimal part.
  • 😝 Sometimes repeating part will be long and hard to read.

\[123.45678678...\]

julia> rd"123.45678678..."4111111//33300
julia> no = EllipsisNotation()EllipsisNotation()
julia> stringify(no, 1//11)"0.0909..."
julia> rationalify(no, "123.45678678...")4111111//33300
julia> rd"0.4545..." # Same as 0.(45), repeating [45] two times5//11
julia> rd"0.333..." # Same as 0.(3), repeating one digit [3] three times1//3
julia> rd"0.13331333..." # Same as 0.(1333), repeating [1333] has priority over repeating [3]1333//9999
julia> rd"0.133313333..." # Same as 0.13331(3), adding additional [3] resolves the ambiguity.19997//150000

Non-supported notation

Vinculum notation $123.45\overline{678}$ is not supported because it is hard to input with Unicode.

$0.\dot{6}\dot{6} = 12/18$ is the birthday of the package.