9
$\begingroup$

I'm trying to evaluate the machine epsilon of my computer (see below). I wrote this:

eps = 1.0;
p = 0;
While[(1.0 + eps) > 1.0, eps = eps/2.0; p += 1];
eps
p
eps*2

and got:

1.42109*10^-14
46
2.84217*10^-14

which is not what I expected (IEEE754). So I did this

EngineeringForm[1.0 + 2 * eps, 20]
EngineeringForm[1.0 + eps, 20]
EngineeringForm[1.0 + (eps/2.0), 20]
EngineeringForm[1.0 + (eps/4.0), 20]
EngineeringForm[1.0 + (eps/16.0), 20]
EngineeringForm[1.0 + (eps/32.0), 20]

and got that:

1.000000000000028
1.000000000000014
1.000000000000007
1.000000000000004
1.000000000000001
1.

which seems to contradict the termination condition of the 'while' loop. So I would like to understand what's going on under Mathematica's hood. I tried to look for some information on Mathematica's internal float representation without success. Any help to explain these results is welcome. I'm sorry if my question is a bit vague.

Eric

Context:

SystemInformationData[{"Kernel" ->
    {"Version" -> "9.0 for Mac OS X x86 (64-bit) (January 24, 2013)", 
    "ReleaseID" -> "9.0.1.0 (4055646, 4055073)", ...}]

EDIT

It was suggested the following program that works directly for some reason:

eps = 1.0;
n = 0;
While[(1.0 + eps) - 1.0 > 0.0,
  eps = eps/2;
  n++;
];
eps*2
n
Log[2, eps*2]
$\endgroup$
6
  • $\begingroup$ How about $MachineEpsilon? $\endgroup$ May 30, 2014 at 16:37
  • $\begingroup$ Hmm, yes. That gives 2.22045*10^-16 which is yet another value. Besides, I was asked to 'calculate' the machine's epsilon not just provide the value. Thx for the feedback. $\endgroup$
    – Eric
    May 30, 2014 at 16:47
  • $\begingroup$ Try 1. + $MachineEpsilon > 1.... $\endgroup$
    – Michael E2
    May 30, 2014 at 17:13
  • $\begingroup$ As per reference doc, this is indeed corresponds to 2^(-n+1) with n=53, which is the mantissa of a double precision IEEE754 float. That's what I expected. I still don't understand why the while loop calculation did not give this result. $\endgroup$
    – Eric
    May 30, 2014 at 17:14
  • $\begingroup$ @MichaelE2, tried that and got: In[439]:= 1.0 + $MachineEpsilon > 1.0 Out[439]= False. If I'm not wrong, this should have been True, no? $\endgroup$
    – Eric
    May 30, 2014 at 17:16

1 Answer 1

10
$\begingroup$

There is a tolerance Internal`$EqualTolerance that is applied when testing Real numbers. If the numbers agree up to the last Internal`$EqualTolerance digits, then they are treated as equal. Try this:

eps = 1.0;
p = 0;
Block[{Internal`$EqualTolerance = 0.},
 While[(1.0 + eps) > 1.0, eps = eps/2.0; p += 1];
 ]
eps
p
eps*2
(*
  1.11022*10^-16
  53
  2.22045*10^-16
*)

See How to make the computer consider two numbers equal up to a certain precision and also this answer by Alexey Popkov.

$\endgroup$
2
  • $\begingroup$ Ah, beautiful! Thx Michael! This post was also useful. Sorry I can't vote yet ;-). Eric $\endgroup$
    – Eric
    May 30, 2014 at 17:28
  • $\begingroup$ @Eric You're welcome. :) $\endgroup$
    – Michael E2
    May 30, 2014 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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