Re: [Tutor] Float precision untrustworthy~~~

2005-03-31 Thread Jacob S.

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~~~

2005-03-30 Thread Jeff Shannon
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~~~

2005-03-30 Thread Kent Johnson
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