6
$\begingroup$

Consider the following calculation:

1234*5678*90.12

The result is:

6.31439*10^8

However, I want to get a precise result. Of course, I can always write for example:

NumberForm[1234*5678*90.12, 20]

But that gives me

6.314394782399999*10^8

which is clearly not correct. Another possible solution is to force 90.12 to have a certain precision, e.g.:

1234*5678*90.12`20

which gives

6.3143947824000000000*10^8

but that's not really what I want either, since there's always the possibility (with more complicated calculations) that maybe there's a secret non-zero digit hiding somewhere more than 20 digits after the decimal and thus will be missed with only 20 digits of precision.

The only way I found to make Mathematica actually do an infinite precision calculation is to write

1234*5678*9012/100

but that gives me

15785986956/25

which isn't what I want either, since I want to get a decimal representation. Again, I could write something like

N[1234*5678*9012/100, 20]

which gives

6.3143947824000000000*10^8

but that still only has 20 digits of precision, not infinite precision.

So my question is: how can I force Mathematica to do an infinite-precision calculation - I stress again, not to any specific finite precision (e.g. 20), but infinite precision - and give me the precise result up to the last non-zero digit after the decimal point?

$\endgroup$
13
  • 5
    $\begingroup$ What problem are you actually trying to solve? Even if you confine yourself to rationals, only a rare subset (those whose minimal denominator contains no prime factors other than 2 and 5) can be expressed as an exact decimal. $\endgroup$
    – John Doty
    Dec 27, 2021 at 18:32
  • 2
    $\begingroup$ Given that approximate numbers are represented in binary, this might be a challenge. For example the decimal .12 does not have a finite binary representation. So at some point in such computations, rounding will have to be done. $\endgroup$ Dec 27, 2021 at 18:35
  • 3
    $\begingroup$ Infinite precision requires conversion to exact numbers rather using inexact numbers. Either 1234*5678*SetPrecision[90.12, Infinity] or 1234*5678*Rationalize[90.12, 0]. After calculating with exact numbers, use N[#, prec]& to display with prec digits of precision. Of course, exact calculations are slower than inexact calculations. $\endgroup$
    – Bob Hanlon
    Dec 27, 2021 at 18:42
  • 1
    $\begingroup$ You can change the output formatting of an expression, but you cannot really change the internal representation. (Not without writing a library package to support your new creation, especially about something so fundamental to the system as numbers.) 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$
    – Michael E2
    Dec 27, 2021 at 18:48
  • 2
    $\begingroup$ Okay. If you start with an exact rational value, and use RealDigits, then I think you will get what you want. $\endgroup$ Dec 27, 2021 at 19:23

2 Answers 2

12
$\begingroup$

Mathematica will perform exact arithmetic only so long as all quantities are expressed as exact numbers. 90.12 is an inexact number with machine precision (i.e. floating point). Corresponding exact representations include 9012/1000 or 9012*^-2.

For numbers with a finite decimal representation, we can use RealDigits to see all the digits along with a count of how many appear before the decimal point:

RealDigits[1234*5678*9012/100]

decimal representation

RealDigits will also give us a finite representation for repeating decimals with the repeated sequence appearing in a sublist:

RealDigits[Prime[10000]/7]

decimal representation

For transcendental numbers we are out of luck for an exact decimal representation. We must specify how many digits we wish to see:

RealDigits[Pi]

error

RealDigits[Pi, 10, 10^6]

decimal representation

$\endgroup$
2
  • $\begingroup$ This indeed works! But it's cumbersome to use. I wish there was a built-in Mathematica function that actually writes down the full number in decimal representation and marks repeated decimals if applicable, such as the ones suggested in this answer. For my needs I will probably write my own function that does something similar, but it would have been nice if it was built in. Wolfram, if you're reading this, please consider adding such a function! $\endgroup$
    – Wolf
    Dec 28, 2021 at 0:16
  • $\begingroup$ @Wolf On basis of recent Wolfram livestreams I'm under an impression of such forms being planned for Wolfram Language, but they're definitely not there yet. $\endgroup$
    – kirma
    Dec 31, 2021 at 9:04
0
$\begingroup$

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

$\endgroup$
4
  • 3
    $\begingroup$ I don't understand how you're using the Repeated function. For example, 0. Repeated[3] has value shown as 0., as does 0. Repeated[3]/(NumberForm[#, 20] &). $\endgroup$
    – murray
    Dec 27, 2021 at 19:49
  • $\begingroup$ I am just trying to imagine an output format. $\endgroup$ Dec 27, 2021 at 21:56
  • 1
    $\begingroup$ @Pierre the fact is, Repeated is a built in with a totally different meaning, hence the confusion, so it would be best to use something else in your mocked-up representation. $\endgroup$
    – MarcoB
    Dec 27, 2021 at 22:51
  • $\begingroup$ Yes and the remark leads to the algebra of this periodic representation, I added to the answer for this. $\endgroup$ Dec 31, 2021 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.