HELP: restore my faith in Python

Ken Seehof kens at sightreader.com
Wed Mar 8 08:46:45 EST 2000


(people who said stuff about using round() before int() in reply to my
epsilon suggesion don't get it.  Reread everything and try again.  Tim's
comments here are much more to the point).

Tim Peters wrote:

> [Ken Seehof]
> > Seems to me an improvement would be to have python artificially
> > add epsilon to floats before converting to int.  This would still
> > suck but IMHO it would suck less.
>
> In my arrogant option, it's a terrible idea.  You're welcome <wink>.
>
> > Yeah, I know it's artificial, but it's not rocket science.  Everyone
> > knows that int(0.99999999999999999999993427) == 1 is more
> > correct than int(0.99999999999999999999993427) == 0.
>
> Does everyone also know that
>
>     int(0.9999999999999999999993427) == 1
>
> is more useful?  How about
>
>     int(0.999999999999999999993427) == 1
>     int(0.99999999999999999993427) == 1
>     int(0.9999999999999999993427) == 1
>     int(0.999999999999999993427) == 1
>
> and so on?  So long as you draw the line *somewhere*, you haven't solved
> anything, you've merely moved the surprises from where they're predictable
> across *all* IEEE-754 platforms to something unique to Python.
>
> The problems with floating-point are deep and can't be patched over.  "Quick
> hacks" always backfire.

Well, that's true.  It is finite precision after all. What's the best epsilon
for getting
floating points to behave like real number as often as possible? Interesting
question.  Perhaps the best answer is not 0.0.  Larger epsilons detract from the

net precision (in a well defined way) of the floating point operation.  Smaller
epsilons fail to correct large rounding errors.

>  If somebody wants to indulge in a notion of "safe
> epsilon", there's nothing to stop them from writing that explicitly.

True, but non-geek programmers don't know that they need epsilon.  Some
non-geek-but-nevertheless-skilled programmers would rather not have
to think about epsilon.

If epsilon is a constant, geeks can subtract it back out :-)  Hey, better
yet, lets invent a new operator: geek_int that does old-style truncation.

> > I challenge anyone to come up with a real world situation where the
> > latter answer is more valuable.
>
> For starters, any situation whatsoever in which exact integers happen to be
> manipulated in floating-point format.  It would be surprising as hell for,
> e.g.,
>
>     top = 2.**52 - 1.0
>     bot = top + 1.0
>     int(top/bot)
>
> to come out as 1.  Not just surprising, but plain wrong.  Many programs do
> this, btw:  Python's floats have 53 bits of precision on most machines, but
> Python's ints only 31.

Good point.  That's the first intelligent argument I've heard against my humble
opinion.

But it's too late, the other silly comments (like thinking that I want rounding
when I really want "fuzzy" truncation) are making me more rigid in my
humble beliefs, so I will persist in my arguing :-)

The example you give is pushing the limits of the machines floating point
precision.  I could argue that the real reason your example fails is that the
programmer is relying on implementation details of the floating point processor
rather than simply thinking of floats as real numbers with some imprecision.

In my humble experience, I've found that it is best to stay a
little bit away from these limits.  My proposal is really to give up a little
precision in exchange for correct results within the "mundane domain".

I guess the real problem, as you point out, is that epsilon is hard to
choose. I'll have to think about that.

Still, doesn't this seem more traumatic than your example?
>>> (7/5.0 - 1) * 5
2.0
>>> int((7/5.0 - 1) * 5)
1

Now that's a problem that is totally independent of the precision of
the processor (but is dependent on the base).

Python is supposed to work for non-computer geeks.  Your example
is one that only computer geeks would have.  Your example is a problem
precisely because the programmer knows exactly what the precision of
the floating point implementation is.

My solution works for people who:
1. Don't know the exact precision and details of the floating point processor
2. Don't know and don't care what the base of the floating point processor is
3. Want correct results in all cases that aren't pushing the limits too hard
4. Expect floating point numbers to behave like real numbers in most cases.

The existing solution:
1. Gives incorrect results in trivial cases that don't push the limits (see
above)
2. Works better than my solution only in cases where people are expecting
particular
behavior based on processor implementation specifics.

Now we all know about relying on implementation specifics from OO class.

BTW, my definition of correct is simply that floating point mimics real numbers,

not that it fits some arbitrary standard.

> > I'll let the experts figure out what exactly epsilon should be.
>
> There is no suitable value, an no expert will touch this even on a
> double-dog dare <wink>.
>
> [on integer division]
> > I suggest the Alice approach: find out what "non-programmers"
> > expect the behaviour to be, commit to that, then do the best you
> > can to formalize the rules so "real programmers" can figure out
> > what to expect too.
>
> The ABC project did that and came up with rationals.  Ditto the TeachScheme!
> project.  In ABC rationals didn't work out that well in practice, but I
> suspect it's because the language's floating-point facilities were clunky.
> Haven't heard similar complaints about MzScheme.
>
> > Unfortunately, I have a feeling that most "real programmers",
> > including myself, will probably be somewhat annoyed at the results.
> > After all, we think integer division is sometimes useful.
>
> It would be reasonable to introduce, e.g., "//" as an integer division
> operator.

Excellent idea!  So 1/2 is 0.5 and 1//2 is 0.  How about 1/1?  Is that1 or 1.0?
Actually, I think I vote for 1/2 = 1/2 (rational), since we've
got all the other bases covered with your 1//2 = 0 suggestion.

> > ...
>
> leaving-case-sensitivity-to-the-sensitive<wink>-ly y'rs  - tim

shouldn't-have-to-know-IEEE-754-to-use-python-ly yr's
- Ken





More information about the Python-list mailing list