Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!mit-eddie!uw-beaver!tektronix!teklds!daniels From: daniels@teklds.TEK.COM (Scott Daniels) Newsgroups: comp.lang.c Subject: Re: How not to write a loop, revisited Summary: Correction, my arithmetic skills are poor Keywords: precision floating numbers Message-ID: <3653@teklds.TEK.COM> Date: 28 Jun 88 16:40:51 GMT References: <16276@brl-adm.ARPA> <329@accelerator.eng.ohio-state.edu> <3637@teklds.TEK.COM> Reply-To: daniels@teklds.UUCP (Scott Daniels) Followup-To: comp.lang.c Organization: Tektronix, Inc., Beaverton, OR. Lines: 52 Oh do I have egg all over my face. Ah well, I will go home and calculate fractions for a week. In article <3637@teklds.TEK.COM> daniels@teklds.UUCP (Scott Daniels) writes: --That's me-- > ... [ notation: E/F is F (a binary fraction) * pow(2.0,E) ] ... >Now notice that in this representation, a number E/F actually represents >the range: E / (F - 1/32) through E / (F + 1/32). The size of the interval >depends only on the exponent. > 1/.1110 = 1.750 represents 1.6875 through 1.8125 > 1/.1111 = 1.875 represents 1.8125 through 1.9375 > 2/.1000 = 2.000 represents 1.8750 through 2.1250 > 2/.1001 = 2.250 represents 2.1250 through 2.3750 Assume we treat the last bit as possibly in error. The numbers are in the range: E / (F - 1/16) through E / (F + 1/16). Again, the size of the interval depends only on the exponent. 1/.1110 = 1.750 represents 1.625 through 1.875 1/.1111 = 1.875 represents 1.750 through 2.000 2/.1000 = 2.000 represents 1.750 through 2.250 2/.1001 = 2.250 represents 2.000 through 2.500 >Ok, here we go: > To represent 2.0 exactly, we could use 2/.1000, but that represents the >interval 1.8750:2.1250. Now, there is a tighter specification which is >entirely within that interval: 1/.1111 (which represents 1.8125:1.9375), so >we should use that tighter interval since no poin inside it is any further >from the desired value 2.0 than the range that 2/.1000 gives. Hence the >besty representation (the tightest) for 2.0 is an interval which does not >even include 2.0! > 1/.1110 = 1.750 represents 1.625 through 1.875 1/.1111 = 1.875 represents 1.750 through 2.000 2/.1000 = 2.000 represents 1.750 through 2.250 2/.1001 = 2.250 represents 2.000 through 2.500 To represent 2.0 exactly, we could use 2/.1000, but that represents the interval 1.750:2.250. Now, there is a tighter specification which is entirely within that interval: 1/.1111 (which represents 1.750:2.000), so we should use that tighter interval since no poin inside it is any further from the desired value 2.0 than the range that 2/.1000 gives. Hence the best representation (the tightest) for 2.0 is an interval which does not even include 2.0! >-Scott Daniels daniels@teklds.TEK.COM (or daniels@teklds.UUCP) Basically, I remebered the argument as open intervals +/- lsbit, but I reproduced the argument using +/- 1/2 lsbit (seemed clearer and more appropriate), but didn't really check that that also exhibitted the behavior. I will now sneak off into a corner and cry myself to death. still: -Scott Daniels daniels@teklds.TEK.COM (or daniels@teklds.UUCP)