**3.1.5 Arbitrary-Precision Numbers**

When you do calculations with arbitrary-precision numbers, Mathematica keeps track of precision at all points. In general, Mathematica tries to give you results which have the highest possible precision, given the precision of the input you provided.

Mathematica treats arbitrary-precision numbers as representing the values of quantities where a certain number of digits are known, and the rest are unknown. In general, an arbitrary-precision number x is taken to have Precision[x] digits which are known exactly, followed by an infinite number of digits which are completely unknown.

When you do a computation, Mathematica keeps track of which digits in your result could be affected by unknown digits in your input. It sets the precision of your result so that no affected digits are ever included. This procedure ensures that all digits returned by Mathematica are correct, whatever the values of the unknown digits may be.

This evaluates

trying to get 30-digit precision.
In[1]:= **N[Gamma[1/7], 30]**

Out[1]=

In this case, the result has a precision of exactly 30 digits.
In[2]:= **Precision[%]**

Out[2]=

If you give input only to a few digits of precision, Mathematica cannot give you such high-precision output.
In[3]:= **N[Gamma[0.142], 30]**

Out[3]=

If you want Mathematica to assume that 0.142 is exactly142/1000, then you have to show this explicitly.
In[4]:= **N[Gamma[142/1000], 30]**

Out[4]=

In many computations, the precision of the results you get progressively degrades as a result of "roundoff error". A typical case of this occurs if you subtract two numbers that are close together. The result you get depends on high-order digits in each number, and typically has far fewer digits of precision than either of the original numbers.

Both input numbers have a precision of 20 digits, but the result has a precision of only 3 digits.
In[5]:= **1.11111111111111111111 -**

1.11111111111111111000

Out[5]=

Adding extra digits in one number but not the other is not sufficient to allow extra digits to be found in the result.
In[6]:= **1.11111111111111111111345 -**

1.11111111111111111000

Out[6]=

The precision of the output from a function can depend in a complicated way on the precision of the input. Functions that vary rapidly typically give less precise output, since the variation of the output associated with uncertainties in the input is larger. Functions that are close to constants can actually give output that is more precise than their input.

Functions like Sin that vary rapidly typically give output that is less precise than their input.
In[7]:= **Sin[111111111.0000000000000000]**

Out[7]=

Here is

evaluated to 20-digit precision.
In[8]:= **N[Exp[-40], 20]**

Out[8]=

The result you get by adding the exact integer 1 has a higher precision.
In[9]:= **1 + %**

Out[9]=

It is worth realizing that different ways of doing the same calculation can end up giving you results with very different precisions. Typically, if you once lose precision in a calculation, it is essentially impossible to regain it; in losing precision, you are effectively losing information about your result.

Here is a 40-digit number that is close to 1.
In[10]:= **x = N[1 - 10^-30, 40]**

Out[10]=

Adding 1 to it gives another 40-digit number.
In[11]:= **1 + x**

Out[11]=

The original precision has been maintained.
In[12]:= **Precision[%]**

Out[12]=

This way of computing 1+x loses precision.
In[13]:= **(x^2 - 1) / (x - 1)**

Out[13]=

The result obtained in this way has quite low precision.
In[14]:= **Precision[%]**

Out[14]=

The fact that different ways of doing the same calculation can give you different numerical answers means, among other things, that comparisons between approximate real numbers must be treated with care. In testing whether two real numbers are "equal", Mathematica effectively finds their difference, and tests whether the result is "consistent with zero" to the precision given.

These numbers are equal to the precision given.
In[15]:= **3 == 3.000000000000000000**

Out[15]=

The internal algorithms that Mathematica uses to evaluate mathematical functions are set up to maintain as much precision as possible. In most cases, built-in Mathematica functions will give you results that have as much precision as can be justified on the basis of your input. In some cases, however, it is simply impractical to do this, and Mathematica will give you results that have lower precision. If you give higher-precision input, Mathematica will use higher precision in its internal calculations, and you will usually be able to get a higher-precision result.

Numerical evaluation.

If you start with an expression that contains only integers and other exact numeric quantities, then N[expr,n] will in almost all cases succeed in giving you a result to n digits of precision. You should realize, however, that to do this Mathematica sometimes has to perform internal intermediate calculations to much higher precision.

The global variable $MaxExtraPrecision specifies how many additional digits should be allowed in such intermediate calculations.

Mathematica automatically increases the precision that it uses internally in order to get the correct answer here.
In[16]:= **N[Sin[10^40], 30]**

Out[16]=

Using the default setting $MaxExtraPrecision=50Mathematica cannot get the correct answer here.
In[17]:= **N[Sin[10^100], 30]**

$MaxExtraPrecision::meprec: $MaxExtraPrecision = 50. reached while evaluating Sin[10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]. Increasing the value of $MaxExtraPrecision may help resolve the uncertainty.

Out[17]=

The precision is zero, indicating that no digits can be expected to be correct.
In[18]:= **Precision[%]**

Out[18]=

This tells Mathematica that it can use more digits in its internal calculations.
In[19]:= **$MaxExtraPrecision = 100**

Out[19]=

Now it gets the correct answer.
In[20]:= **N[Sin[10^100], 30]**

Out[20]=

This resets $MaxExtraPrecision to its default value.
In[21]:= **$MaxExtraPrecision = 50**

Out[21]=

Mathematica saves its previous result, so still gives the correct answer here.
In[22]:= **N[Sin[10^100], 30]**

Out[22]=

Even when you are doing computations that give exact results, Mathematica still occasionally uses approximate numbers for some of its internal calculations, so that the value of $MaxExtraPrecision can thus have an effect.

Mathematica works this out using bounds from approximate numbers.
In[23]:= **Sin[Exp[100]] > 0**

Out[23]=

With the default value of $MaxExtraPrecision, Mathematica cannot work this out.
In[24]:= **Sin[Exp[200]] > 0**

200

$MaxExtraPrecision::meprec: $MaxExtraPrecision = 50. reached while evaluating Sin[E ]. Increasing the value of $MaxExtraPrecision may help resolve the uncertainty.

Out[24]=

Temporarily resetting $MaxExtraPrecision allows Mathematica to get the result.
In[25]:= **Block[{$MaxExtraPrecision = 100},**

Sin[Exp[200]] > 0 ]

Out[25]=

Global precision parameters.

When Mathematica works out the potential effect of unknown digits in arbitrary-precision numbers, it assumes by default that these digits are completely independent in different numbers. While this assumption will never yield too high a precision in a result, it may lead to unnecessary loss of precision.

In particular, if two numbers are generated in the same way in a computation, some of their unknown digits may be equal. Then, when these numbers are, for example, subtracted, the unknown digits may cancel. By assuming that the unknown digits are always independent, however, Mathematica will miss such cancellations.

Here is a number computed to 20-digit precision.
In[26]:= **delta = N[3^-30, 20]**

Out[26]=

The quantity 1+delta has 34-digit precision.
In[27]:= **Precision[1 + delta]**

Out[27]=

This quantity also has only 34-digit precision, since Mathematica assumes that the unknown digits in each number delta are independent.
In[28]:= **Precision[(1 + delta) - delta]**

Out[28]=

Numerical algorithms sometimes rely on cancellations between unknown digits in different numbers yielding results of higher precision. If you can be sure that certain unknown digits will eventually cancel, then you can explicitly introduce arbitrary digits in place of the unknown ones. You can carry these arbitrary digits through your computation, then let them cancel, and get a result of higher precision.

Functions for modifying precision and accuracy.

This adds 10 arbitrary digits to delta.
In[29]:= **delta = SetPrecision[delta, 30]**

Out[29]=

The digits that were added cancel out here.
In[30]:= **(1 + delta) - delta**

Out[30]=

The precision of the result is now 44, rather than 34, digits.
In[31]:= **Precision[%]**

Out[31]=

SetPrecision works by adding digits which are zero in base 2. Sometimes, Mathematica stores slightly more digits in an arbitrary-precision number than it displays, and in such cases, SetPrecision will use these extra digits before introducing zeros.

This creates a number with a precision of 40 decimal digits. The extra digits come from conversion to base 10.
In[32]:= **SetPrecision[0.300000000000000, 40]**

Out[32]=

By making the global assignment $MinPrecision=n, you can effectively apply SetPrecision[expr,n] at every step in a computation. This means that even when the number of correct digits in an arbitrary-precision number drops below n, the number will always be padded to have n digits.

If you set $MaxPrecision=n as well as $MinPrecision=n, then you can force all arbitrary-precision numbers to have a fixed precision of n digits. In effect, what this does is to make Mathematica treat arbitrary-precision numbers in much the same way as it treats machine numbersbut with more digits of precision.

Fixed-precision computation can make some calculations more efficient, but without careful analysis you can never be sure how many digits are correct in the results you get.

Here is a small number with 20-digit precision.
In[33]:= **k = N[Exp[-60], 20]**

Out[33]=

With Mathematica's usual arithmetic, this works fine.
In[34]:= **Evaluate[1 + k] - 1**

Out[34]=

This tells Mathematica to use fixed-precision arithmetic.
In[35]:= **$MinPrecision = $MaxPrecision = 20**

Out[35]=

The first few digits are correct, but the rest are wrong.
In[36]:= **Evaluate[1 + k] - 1**

Out[36]=