[Python-Dev] Minutes from the Numeric Coercion dev-day session

Guido van Rossum guido@digicool.com
Tue, 13 Mar 2001 05:18:35 -0500


> [Guido, to David Ascher]
> > ...
> > One thing we *could* agree to there, after I pressed some people: 1/2
> > should return 0.5.
> 
> FWIW, in a show of hands at the devday session after you left, an obvious
> majority said they did object to that 1/2 is 0 today.  This was bold in the
> face of Paul Dubois's decibel-rich opposition <wink>.  There was no consensus
> on what it *should* do instead, though.
> 
> > Possibly 1/2 should not be a binary floating point number -- but then
> > 0.5 shouldn't either, and whatever happens, these (1/2 and 0.5) should
> > have the same type, be it rational, binary float, or decimal float.
> 
> I don't know that imposing this formal simplicity is going to be a genuine
> help, because the area it's addressing is inherently complex.  In such cases,
> simplicity is bought at the cost of trying to wish away messy realities.
> You're aiming for Python arithmetic that's about 5x simpler than Python
> strings <0.7 wink>.
> 
> It rules out rationals because you already know how insisting on this rule
> worked out in ABC (it didn't).
> 
> It rules out decimal floats because scientific users can't tolerate the
> inefficiency of simulating arithmetic in software (software fp is at best
> ~10x slower than native fp, assuming expertly hand-optimized assembler
> exploiting platform HW tricks), and aren't going to agree to stick physical
> constants in strings to pass to some "BinaryFloat()" constructor.
> 
> That only leaves native HW floating-point, but you already know *that*
> doesn't work for newbies either.

I'd like to argue about that.  I think the extent to which HWFP
doesn't work for newbies is mostly related to the change we made in
2.0 where repr() (and hence the interactive prompt) show full
precision, leading to annoyances like repr(1.1) == '1.1000000000000001'.

I've noticed that the number of complaints I see about this went way
up after 2.0 was released.

I expect that most newbies don't use floating point in a fancy way,
and would never notice it if it was slightly off as long as the output
was rounded like it was before 2.0.

> Presumably ABC used rationals because usability studies showed they worked
> best (or didn't they test this?).

No, I think at best the usability studies showed that floating point
had problems that the ABC authors weren't able to clearly explain to
newbies.  There was never an experiment comparing FP to rationals.

> Presumably the TeachScheme! dialect of
> Scheme uses rationals for the same reason.

Probably for the same reasons.

> Curiously, the latter behaves
> differently depending on "language level":
> 
> > (define x (/ 2 3))
> > x
> 2/3
> > (+ x 0.5)
> 1.1666666666666665
> >
> 
> That's what you get under the "Full Scheme" setting.  Under all other
> settings (Beginning, Intermediate, and Advanced Student), you get this
> instead:
> 
> > (define x (/ 2 3))
> > x
> 2/3
> > (+ x 0.5)
> 7/6
> >
> 
> In those you have to tag 0.5 as being inexact in order to avoid having it
> treated as ABC did (i.e., as an exact decimal rational):
> 
> > (+ x #i0.5)
> #i1.1666666666666665
> >
> 
> > (- (* .58 100) 58)   ; showing that .58 is treated as exact
> 0
> > (- (* #i.58 100) 58) ; same IEEE result as Python when .58 tagged w/ #i
> #i-7.105427357601002e-015
> >
> 
> So that's their conclusion:  exact rationals are best for students at all
> levels (apparently the same conclusion reached by ABC), but when you get to
> the real world rationals are no longer a suitable meaning for fp literals
> (apparently the same conclusion *I* reached from using ABC; 1/10 and 0.1 are
> indeed very different beasts to me).

Another hard question: does that mean that 1 and 1.0 are also very
different beasts to you?  They weren't to the Alice users who started
this by expecting 1/4 to represent a quarter turn.

> A hard question:  what if they're right?  That is, that you have to favor one
> of newbies or experienced users at the cost of genuine harm to the other?

You know where I'm leaning...  I don't know that newbies are genuinely
hurt by FP.  If we do it right, the naive ones will try 11.0/10.0, see
that it prints 1.1, and be happy; the persistent ones will try
1.1**2-1.21, ask for an explanation, and get a introduction to
floating point.  This *doesnt'* have to explain all the details, just
the two facts that you can lose precision and that 1.1 isn't
representable exactly in binary.  Only the latter should be new to
them.

--Guido van Rossum (home page: http://www.python.org/~guido/)