"I want to get a decimal representation" is not compatible with infinite precision because some rational numbers like 1/3 have infinite decimal representation that does not fit into a computer.
You pointed out a solution: use fractions.
Equivalently you could represent exactly a rational number using its period, like
1/3 == 0.Repeated[3]
1344/19 == 70.Repeated[736842105263157894]
The successive digits can be obtained by Euclidean division, for example:
In[1066]:= Last /@
Rest@NestList[{Mod[#[[1]], #[[2]]] 10, #[[2]],
Quotient[#[[1]], #[[2]]]} &, {1344, 19}, 30]
Out[1066]= {70, 7, 3, 6, 8, 4, 2, 1, 0, 5, 2, 6, 3, 1, 5, 7, 8, 9, 4, \
7, 3, 6, 8, 4, 2, 1, 0, 5, 2, 6}
The digits before the decimal point are just the first Quotient[1344, 19]
.
FindRepeat
finds the period.
In[1071]:=
Rest[Last /@
Rest@NestList[{Mod[#[[1]], #[[2]]] 10, #[[2]],
Quotient[#[[1]], #[[2]]]} &, {1344, 19}, 30]] // FindRepeat
Out[1071]= {7, 3, 6, 8, 4, 2, 1, 0, 5, 2, 6, 3, 1, 5, 7, 8, 9, 4}
The cycle completes when mod and quotient come back to same previous values, which necessarily occurs before 19*10 steps. 30 was enough in the example.
The number of digits needed for this periodic representation should be about the same order of magnitude for large numbers as the number or digits in the reduced fraction.
The periodic representation is definitely better if you need to compare the numbers quickly.
Finally this seems to work:
In[1095]:= Clear@periodic;
periodic[x_Rational] := {IntegerPart@x,
Rest[Last /@
Rest@NestList[{Mod[#[[1]], #[[2]]] 10, #[[2]],
Quotient[#[[1]], #[[2]]]} &, NumeratorDenominator@x,
10 Denominator@x + 1]] // FindRepeat}
In[1096]:= periodic[1344/19]
Out[1096]= {70, {7, 3, 6, 8, 4, 2, 1, 0, 5, 2, 6, 3, 1, 5, 7, 8, 9, 4}}
In[1098]:= N[1344/19, 30]
Out[1098]= 70.7368421052631578947368421053
In[1097]:= periodic[1/7]
Out[1097]= {0, {1, 4, 2, 8, 5, 7}}
Then you could workout a pretty format with ToString
, StringJoin
...
I just realize that RealDigits
does it, never mind, do it yourself is instructive.
Further developments
I had the idea to express the output of RealDigits[1/7]
like {0,Repeated[142857]}
. Of course this does not evaluate to anything but the pattern gives a sense that it could be used for algebra.
To avoid confusion, I can use easily repeated
instead of Repeated
.
Periodic algebra examples: {1,repeated[12]}+{2,repeated[23]}
would evaluate to {3,repeated[34]}
, {1,repeated[12]}*1000
would evaluate to {1000,repeated[12]}
but it is more difficult to evaluate directly {1,repeated[12]}+{2,repeated[234]}
or {1,repeated[12]}*{2,repeated[23]}
.
Again, to avoid confusion, I should not use directly +
and *
but some periodicPlus
and periodicTimes
but surely you understand better what I mean with +
and *
.
Also I have used 1000
instead of {1000,Repeated[0]}
, that is type conversion.
The periodic algebra is isomorphic to the rational algebra and the RealDigits
has a simple inverse function so it is quite easy to solve periodic algebra by isomorphism.
Is the periodic representation more or less informative than the rational representation? It is definitely more informative with respect to order. How does the period length evolve when numbers are combined?
1234*5678*SetPrecision[90.12, Infinity]
or1234*5678*Rationalize[90.12, 0]
. After calculating with exact numbers, useN[#, prec]&
to display withprec
digits of precision. Of course, exact calculations are slower than inexact calculations. $\endgroup$15785986956/25
is the only infinite precision representation, AFAIK, but you can display it in all sorts of ways. See for instance, mathematica.stackexchange.com/questions/15818/… $\endgroup$RealDigits
, then I think you will get what you want. $\endgroup$