Re: [Tutor] Float precision untrustworthy~~~
I understand what you are talking about, but I tend toward just making it one of the things to remember when working with floats. (I've been bitten a lot when I forget to use '==' instead of '=', too!) Yeah, but it threw me for a loop, because I could find *no*e way to compare a float and an integer and get it to come out right before I remembered round. As you say, the problems arise when you try to make comparisons. To get around the difficulties with comparisons, I wrote a helper function: ### Python 2.3 (#2, Jul 30 2003, 11:45:28) [GCC 3.1 20020420 (prerelease)] Type copyright, credits or license for more information. MacPython IDE 1.0.1 from math import floor, log10 def Round(x, n=0, sigfigs=False): '''An enhanced rounder which rounds to the nth significant digit (the nth digit from the first non-zero digit, not the nth decimal place) if the parameter sigfigs is not zero. This uses round-up decisions when the digit following the one of interest is a 5, i.e. 1.35 and 1.45 Round to 1.4 and 1.5 when sigfigs = 2. ''' if x==0: return 0 if not sigfigs: return round(x,n) else: return round(x,n-1-int(floor(log10(abs(x) ### And here's a helper that uses it to check for equality of two numbers (floats, or otherwise) to whatever number of digits you desire --starting from the first non-zero digit, The default is for high precision. ### def same(x,y,prec=9): Return True if x and y are the same after being rounded to the same degree of precision. return Round(x,prec,1)==Round(y,prec,1) .. print same(1.3,1.31,3) #at the 3rd digit these are different False print same(1.3,1.31,2) #at the second digit they are (rounded to) the same digit number True same(64.0**(1/3.0) ,4) #here's your example True ### You can be bitten by any comparison, not only tests for equality, too. ### while 1: .. i+=.1 .. if i2.1:break .. print i 2.1 ### It doesn't look like the last value of i was really greater than 2.1--it's actually 2.1005 so the result is correct (though not what we expected). We don't have the problem with a step size of 0.7 in this case, though, because the value before 2.8 was 2.0996--just a little smaller than 2.1. Here, we specify the precision and get the desired result. ### i=0 while 1: .. i+=.1 .. if round(i,9)round(2.1,9):break .. print i 2.2 ### Wish granted in version 2.4 ;-) I don't have it on the mac, but there is a write-up at I meant in the scripts -- even better, as a builtin. Your above helper function is fine... but I believe that it should be part of the __cmp__ method of the float types. Perhaps with optional parameter? Such as oldway=True Jacob Schmidt ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Float precision untrustworthy~~~
On Mon, 28 Mar 2005 22:13:10 -0500, Jacob S. [EMAIL PROTECTED] wrote: I've already deleted the recent thread-- But sometimes I agree with he who said that you can't trust floats at all. The scientific theory suggests that if an output is not what it should be, then the hypothesis is untrue. In this case, the hypothesis is the fact that float division should always produce the same output as our decimal division used in common schools today. Since that is not always true, then floats are not trustworthy~~~ frankly, the mere fact that floats are difficult to check with equality has bitten me more than anything I've met yet in python. The scientific method is also quite well aware of the limits of precision. *EVERY* tool that you use to make measurements has precision limits. In most of those cases, the imprecision due to measuring tools will overwhelmingly swamp the tiny bit of imprecision involved with floating-point arithmetic. It's also worth pointing out that most of the float imprecision isn't anything inherent in the floats themselves -- it's due to converting between binary and decimal representation. Just as a phrase that's translated from English into Russian and then back to English again can have its meaning shifted, translating between different numerical bases can create error -- but it's usually *much* less error than the natural language translations cause. Really, all this talk about floating-point imprecision is *way* overblown. It's important to be aware of it, yes, because in some cases it can be relevant... but it's a *long* way from making floats unusable or unreliable. 64**(1/3) == 4 False 64**-3 == 4 False a = 1/3 a 0.1 Note that you'll have the same problems if you use a Decimal number type, because there's also an imprecision with Decimals. The problem is that you're expecting a digital variable with a limited discrete set of possible values to be equivalent to a rational number -- but no binary or decimal floating-point number can exactly represent 1/3. A Decimal approximation would have a 3 as the final digit rather than a 1, but there *would* be a final digit, and *that* is why this can't work. Why not just implement decimal or some equivalent and get rid of hidden, hard to debug headaches? Well, a Decimal type *has* been implemented... but it's just trading one set of headaches for another. What your code is apparently expecting is a Rational type, which has been discussed ad infinitum (and probably implemented several times, though not (yet) accepted into the standard library); Rationals have the problem, though, that any given operation may take an unpredictable amount of time to execute. Would you consider it an improvement if, instead of wondering why you're not getting an equality, you were wondering whether your machine had frozen? There's always a trade-off. It's important to be aware of the weaknesses of the tools that you use, but *every* tool has weaknesses, and it doesn't make sense to discard a tool just because you've learned what those weaknesses are. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Float precision untrustworthy~~~
Jacob S. wrote: I've already deleted the recent thread-- But sometimes I agree with he who said that you can't trust floats at all. The scientific theory suggests that if an output is not what it should be, then the hypothesis is untrue. In this case, the hypothesis is the fact that float division should always produce the same output as our decimal division used in common schools today. Since that is not always true, then floats are not trustworthy~~~ No, you should conclude that the hypothesis is untrue - that in fact float division does not produce the same output as decimal division - and look for a new hypothesis. Like, maybe that float division is a close approximation of exact decimal division that has some well-known limitations. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor