Re: Using Equal with Real Numbers
- To: mathgroup at smc.vnet.net
- Subject: [mg123184] Re: Using Equal with Real Numbers
- From: Bill Rowe <readnews at sbcglobal.net>
- Date: Fri, 25 Nov 2011 04:58:29 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
On 11/24/11 at 6:53 AM, gtlandi at gmail.com (Gabriel Landi) wrote: >Consider: >In[187]:= list1 = Range[0, 1, 0.1] Out[187]= {0., 0.1, 0.2, 0.3, >0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.} >Using InputForm we see that: >In[188]:= list1 // InputForm >Out[188]//InputForm={0., 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, >0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1.} >That is, 0.3, 0.6 and 0.7 have some round-off error. Actually, only three of these values can be expressed in a finite number of digits. That is: In[51]:= FromDigits[First@#, 2] 2^(-Length@First@# + Last@#) & /@ RealDigits[Range[0, 1, .1], 2] - Range[0, 10]/10 Out[51]= {0,1/180143985094819840,1/90071992547409920,1/22517998136852480,1/45035996273704960,0,1/11258999068426240,3/45035996273704960,1/22517998136852480,1/45035996273704960,0} >Now: >In[200]:= {MemberQ[list1, 0.6], MemberQ[list1, 0.7]} Out[200] >{True, False} >(This actually depends on the OS and perhaps other things). The >point is that he recognizes 0.6 as a member of list1 but not 0.7, >even though both have the same InputForms. This issue, as you may >imagine, prohibits one from using functions that implicitly make use >of =, when dealing with real numbers. >Here is my solution: >range[xi_, xf_, df_] := N@Rationalize@Range[xi, xf, df] It was somewhat surprising to me this actually worked. It seems to me a simpler solution would be to use: MemberQ[Rationalize[list1],6/10] or MemberQ[Rationalize[list1], Rationalize[.6]] I believe the internal algorithm Mathematica uses for Range[xi, xf, df] is add df to xi and repreat adding df to the sum until xf is reached. If so, choosing a value for df that cannot be represented in a finite number of binary digits means there will be an accumulated error. I recall reading somewhere Mathematica uses a few extra binary digits beyond the standard number used for a machine precision value. If so, the accumulated error will not be a simple monotonic sequence since at each step the sum is converted to a machine precision value prior to the next sum being computed. At least the following suggests my hypothesis is close to correct. In[59]:= x = FromDigits[First@#, 2] 2^(-Length@First@# + Last@#) & /@ RealDigits[Range[0, 1, .1], 2] - Range[0, 10]/10; In[60]:= x/x[[2]] Out[60]= {0,1,2,8,4,0,16,12,8,4,0} In any case, the underlying issue is one that is inherent to using machine precision numbers rather than exact arithmetic.