# SetPrecision — different values subtracted from unity gives same value

How are my results possible?

CODE:

SetPrecision[FibersFailedNew, 40]

3.612171938234261799295174910010284760488*10^-16

SetPrecision[FibersFailedNewT2, 40]

3.612171938234886971562562561866073555376*10^-16

SetPrecision[FibersRemainingNewT2 = 1 – FibersFailedNewT2, 55]

0.999999999999999666933092612453037872910499572753906250

SetPrecision[FibersRemainingNew = 1 – FibersFailedNew, 55]

0.999999999999999666933092612453037872910499572753906250

The values are calculated from previous equations in the specific notebook. If I would take only values and copy pasted them in a different notebook, of course, the results given are true. How is this possible? Does Mathematica calculate in a different precision as set? of it calculates what is shown on the screen

The values of FiberFailedNew and FiberFailedNewT2 are different, but when subtracted from unity they give the same result.

=================

– Yves Klett
Jul 6 ’14 at 13:51

@YvesKlett. I have added partially the code. The initial values of FibersFailedNew and FibersFailedT2 come from a large CODE with loops, etc. Therefore it is difficult to add the whole procedure of how these values are obtained. Nevertheless, It the main code I use SetPrecision and AccountingForm to show me the Decimals. Does this influence the calculation? Because as noted if I copy paste the numbers only the result subtracted from unity is correct
– Nikolas
Jul 6 ’14 at 14:22

=================

2

=================

Not knowing exactly what FibersFailedNew and FibersFailedNewT2 are, I’m going to hazard a guess that they are MachinePrecision numbers. I’m also going to guess that your use of SetPrecision does not achieve what you want it to do. The code

SetPrecision[FibersFailedNew, 40]

does not change the precision of FibersFailedNew; it displays the value of converting FibersFailedNew to 40-digit precision. And in the code,

SetPrecision[FibersRemainingNewT2 = 1 – FibersFailedNewT2, 55]

the calculation inside SetPrecision is done first at MachinePrecision and the result is converted to 55-digit precision. In all the OP’s code (currently posted), the underlying arithmetic would be done at machine precision. The explanation of what is going on lies in the granularity of machine precision numbers.

As you may know, \$MachineEpsilon is the smallest number that may be added to 1.` to yield a distinct number. Basically, on a binary machine, it changes the lowest-order bit. For numbers between 0.5 and 1. the smallest change would be \$MachineEpsilon/2. The difference 1 – FibersFailedNew will differ from 1. by a multiple of

\$MachineEpsilon/2
(* 1.11022*10^-16 *)

which will be determined by rounding. In the OP’s numbers, both FibersFailedNew and FibersFailedNewT2 round to the same multiple of \$MachineEpsilon/2, namely 3:

FibersFailedNew = N[3.612171938234261799295174910010284760488*10^-16];
FibersFailedNewT2 = N[3.612171938234886971562562561866073555376*10^-16];

1. – N[FibersFailedNew];
1. – %
(* 3.33067*10^-16 *)

1. – N[FibersFailedNewT2];
1. – %
(* 3.33067*10^-16 *)

You may want to think about how these numbers are calculated and whether it might be better to use arbitrary precision numbers from the start.

How to use SetPrecision

Assuming that it is desired to carry out the calculations with arbitrary precision numbers, then here is a way to proceed. Assign the result of SetPrecision to a new or the same variable and use it for your calculations. Below I used the precision \$MachinePrecision, because it seems advisable to me to keep track of how precise my numbers actually are. If they came from MachinePrecision numbers, then certainly no more than \$MachinePrecision digits are accurate. However, higher precision may be used.

FibersFailedNew = SetPrecision[FibersFailedNew, \$MachinePrecision];
FibersFailedNewT2 = SetPrecision[FibersFailedNewT2, \$MachinePrecision];
1 – FibersFailedNew
1 – FibersFailedNewT2
(*
0.9999999999999996387828061765738
0.9999999999999996387828061765113
– or in FullForm –
0.9999999999999996387828061765738200704825089989715239512322`31.39682135577845
0.9999999999999996387828061765113028437437438133926444624335`31.39682135577837
*)

Display of numbers

Concerning the implicit question about what is shown on the screen:

The number of digits displayed by the Front End for MachinePrecision numbers is controlled by the system option

SystemOptions[MachineRealPrintPrecision]
(* {“MachineRealPrintPrecision” -> 6} *)

The Front End displays an arbitrary precision number according to the number of digits of precision of the number.

+1 You took your time to answer the question (and I learnt a lot by reading your text). Wouldn’t it be fair to upvote Nikolas question?
– eldo
Jul 6 ’14 at 22:34

@eldo Sure, just as soon as the OP accepts/responds to one/more answers. Especially for users learning the site’s culture, I prefer positive reinforcement of positive behaviors. (And thanks.)
– Michael E2
Jul 6 ’14 at 23:13

o1 = 3.612171938234261799295174910010284760488*10^-16;
o2 = 3.612171938234886971562562561866073555376*10^-16;

Subtracting like you from 1 (Integer!)

o11 = 1 – o1;
o22 = 1 – o2;
o11 == o22

False

o22 – o11

shows a tiny difference:

-6.2517226738765185578879489*10^-29

Position of last equal digit:

prec = Length@First@Split@First@(RealDigits@o11 – RealDigits@o22)

28

sp1 = SetPrecision[o11, prec];
sp2 = SetPrecision[o22, prec]

0.999999999999999666933092612

sp1 == sp2

True

Now subtract from 1. (Real!)

o11 = 1. – o1;
o22 = 1. – o2

1.

o11 == o22

True