RE: Zero does not equal Zero

*To*: mathgroup at smc.vnet.net*Subject*: [mg31388] RE: [mg31360] Zero does not equal Zero*From*: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.de>*Date*: Wed, 31 Oct 2001 19:59:09 -0500 (EST)*Sender*: owner-wri-mathgroup at wolfram.com

> -----Original Message----- > From: Ersek, Ted R [mailto:ErsekTR at navair.navy.mil] To: mathgroup at smc.vnet.net > Sent: Tuesday, October 30, 2001 10:36 AM > To: mathgroup at smc.vnet.net > Subject: [mg31388] [mg31360] Zero does not equal Zero > > > Hello Group, > > It seems people didn't fully grasp the inconsistency that I > pointed to in my earlier message with the same subject. > I came across this problem when I tried to make my > RootSearch package (recent MathSource addition) capable of > finding roots to a an arbitrary precision. To allow that I > had to make a function similar to Ulp[x] in the > NumericalMath`Microscope` package. Among other things my > version of Ulp can work with arbitrary precision numbers. > Unfortunately I can't make RootSearch work as well as I would > like because of the problem I demonstrate below. > > First consider the next line which demonstrates that a > StandardForm output such as (0. x 10^-20) represents an > arbitrary precision number that is more or less zero. > > In[1]:= > x=Exp[ N[Pi/3, 20] ]; > x-x > > Out[1]= > 0. x 10^-20 > > > Now suppose we want to find the arbitrary precision number > that is slightly larger than x, but as close as possible > to x and still a different number. What do I mean when > I say "a different number"? Well if x and y are > different numbers their difference should not be zero. In > the first case below I view x and y as essentially the same number. > > In[2]:= > y=x+SetPrecision[5.96*^-20, 30]; > {y-x, y-x==0} > > Out[4]= > {0. x 10^-20, True} > > > What about the next case. Here the StandardForm of (x-y) > looks like zero, but (x-y==0) returns False. > Are x and y "different numbers"? Why does > (x-y) return False in the next line, but True in the slightly > different case above? I think when comparing numeric values > (x-y==0) should return True IF AND ONLY IF the StandardForm > of (x-y) is zero. When I say "is zero", that includes > (0. x 10^-20) and similar output. > > > In[5]:= > y=x+SetPrecision[5.97*^-20, 30]; > {y-x, y-x==0} > > Out[6] > {0. x 10^-20, False} > > > -------- > Regards, > Ted Ersek > > Hello Ted, I would not like to say what Mathematica should do or not, rather observe what she does. Before doing so let's have a look into The Book (§3.1.5 Arbitrary-Precision Numbers): 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. Ignoring that word "effectively", disliked by me, let's try to find out what "consistent with zero, to the precision given" might mean: As the precise behaviour might vary, my machine is In[1]:= {$Version, $MachineType, $ProcessorType, $OperatingSystem} Out[1]= {"4.0 for Microsoft Windows (April 21, 1999)", "PC", "x86", "WindowsNT"} Instead of judging from StandartForm let's look at our results in InputForm, and also for a certain reason let's decrease $MinPrecision below zero. In[2]:= $MinPrecision = -1; In[3]:= x = Exp[N[Pi/3, 20]]; x - x // InputForm Out[4]//InputForm= 0``19.2233 (Plain zero of course, no precision can be given, but a certain accuracy) Now we take three different nearby values: In[5]:= y1 = x + SetPrecision[0.597*^-19, 30]; {y - x, y - x == 0} // InputForm Out[6]//InputForm= {5.97`-0.0007*^-20, True} In[7]:= y = x + SetPrecision[0.598*^-19, 30]; {y - x, y - x == 0} // InputForm Out[8]//InputForm= {5.98`0*^-20, True} In[9]:= y2 = x + SetPrecision[0.599*^-19, 30]; {y2 - x, y2 - x == 0} // InputForm Out[10]//InputForm= {5.99`0.0007*^-20, False} y1 and y are considered to be equal to x, y2 not. We look at the accurate Precisions: In[11]:= {prec1, acc1} = Through@{Precision, Accuracy}[y1 - x, Round -> False] Out[11]= {-0.000723805, 19.2233} In[12]:= {prec, acc} = Through@{Precision, Accuracy}[y - x, Round -> False] Out[12]= {3.048266694770595`*^-6, 19.223301864278284`} In[13]:= {prec2, acc2} = Through@{Precision, Accuracy}[y2 - x, Round -> False] Out[13]= {0.000728687, 19.2233} We clearly recognize that "y-x" is a borderline case. For y1-x we see that the precision is smaller than zero, which means the error (due to that precision) is greater that the value, such is "consistent with zero", for y2-x the error is less, so the value can be decided to be positve, what Mathematica does in both cases. Using accuracy, subtracting from the value, we come to a similar conclusion: In[14]:= (y1 - x) - 10^-SetPrecision[acc1, 40] // InputForm Out[14]//InputForm= -9.9580271645`-2.7785*^-23 In[15]:= (y - x) - 10^-SetPrecision[acc, 40] // InputForm Out[15]//InputForm= 4.19728355`-5.1537*^-25 In[16]:= (y2 - x) - 10^-SetPrecision[acc2, 40] // InputForm Out[16]//InputForm= 1.00419728355`-2.7749*^-22 Again we would say that y-x is at "zero crossing". I would not call the case y-x==0 to be an error, rather it is astonishing that y1-x, and y2-x come out right, considering the precision given for x. -- Hartmut Wolf