Floating point bug?

R

robinsiebler

I've never had any call to use floating point numbers and now that I
want to, I can't!

*** Python 2.5.1 (r251:54863, May 1 2007, 17:47:05) [MSC v.1310 32
bit (Intel)] on win32. ***
 
P

Preston Landers

(e-mail address removed)([email protected])@2008.02.13 15:13:20 -0800:
Not a bug. All languages implementing floating point numbers have the
same issue. Some just decide to hide it from you. Please read
http://docs.python.org/tut/node16.html and particularly
http://docs.python.org/tut/node16.html#SECTION0016100000000000000000


This is true. Fortunately Python does provide a module which allows
you to work with exact floating point quantities.

http://docs.python.org/lib/module-decimal.html

Of course the downside is that these are not quite as fast as the
built in float type, but probably good enough for most purposes.

Preston
 
B

Bjoern Schliessmann

I've never had any call to use floating point numbers and now that
I want to, I can't!

Ever considered phrasing your actual problem so one can help, let
alone looking at the archive for many, many postings about this
topic?

Regards,


Björn
 
J

Jeff Schwab

I've never had any call to use floating point numbers and now that I
want to, I can't!

*** Python 2.5.1 (r251:54863, May 1 2007, 17:47:05) [MSC v.1310 32
bit (Intel)] on win32. ***0.29999999999999999

A classic (if lengthy) read:
http://docs.sun.com/source/806-3568/ncg_goldberg.html

If you just want to see a pretty representation:
0.3

If you need a pretty string for use in code:
... return ('%.8f' % fpnum).rstrip('0')
... '0.3'
 
D

Diez B. Roggisch

Preston said:
(e-mail address removed)([email protected])@2008.02.13 15:13:20 -0800:


This is true. Fortunately Python does provide a module which allows
you to work with exact floating point quantities.

That's a misconception. The decimal-module has a different base (10
instead of 2), and higher precision. But that doesn't change the fact
that it will expose the same rounding-errors as floats do - just for
different numbers.

The advantage is that the rounding errors are the ones expected in
monetary caluclations, which means that you can write correct programs
for such purposes.

Diez
 
J

Jeff Schwab

Dennis said:
What's wrong with just

str(0.3)
Nothing!

that's what "print" invokes, whereas the interpreter prompt is using

repr(0.3)

Thanks for pointing that out.
 
C

Christian Heimes

Dennis said:
What's wrong with just

str(0.3)

that's what "print" invokes, whereas the interpreter prompt is using

repr(0.3)

No, print invokes the tp_print slot of the float type. Some core types
have a special handler for print. The tp_print slot is not available
from Python code and most people don't know about it. :]

Christian
 
B

Bruno Desthuilliers

Christian Heimes a écrit :
Dennis said:
What's wrong with just

str(0.3)

that's what "print" invokes, whereas the interpreter prompt is using

repr(0.3)

No, print invokes the tp_print slot of the float type. Some core types
have a special handler for print. The tp_print slot is not available
from Python code and most people don't know about it. :]

???

bruno@bruno:~$ python
Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information..... def tp_print(self):
.... return "AHAHAHA"
....Traceback (most recent call last):
Traceback (most recent call last):
Traceback (most recent call last):

I Must have miss something...
 
B

Bruno Desthuilliers

Christian Heimes a écrit :
Yeah, You have missed the beginning of the third sentence: "The tp_print
slot is not available from Python code".

oops, my bad ! I missed the "not" !-)
 
D

Duncan Booth

Christian Heimes said:
Yeah, You have missed the beginning of the third sentence: "The tp_print
slot is not available from Python code". The tp_print slot is only
available in C code and is part of the C definition of a type. Hence tp_
as type.

It isn't easy to come up with an example which actually demonstrates
that print doesn't just call str, but after a little playing around I
managed it:
def __str__(self):
return mystr('oops')


Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
print s
RuntimeError: maximum recursion depth exceeded
Alternatively:
def __str__(self):
if self=='oops':
return 'you printed me!'
return mystr('oops')



and on that last line idle locks until you restart the shell. I can't
immediately see why; the command line interpreter is fine so it seems
just to be an idle problem:
.... def __str__(self):
.... if self=='oops':
.... return 'you printed me!'
.... return mystr('oops')
....
 
J

Jeff Schwab

Christian said:
Dennis said:
What's wrong with just

str(0.3)

that's what "print" invokes, whereas the interpreter prompt is using

repr(0.3)

No, print invokes the tp_print slot of the float type. Some core types
have a special handler for print. The tp_print slot is not available
from Python code and most people don't know about it. :]

Why does print use the tp_print slot, rather than str()? Are the two
effectively redundant? If (non-repr) string representations are
frequently needed for a given type, could str() be implemented as a
reference to tp_slot, via a C-language extension?
 
G

Gabriel Genellina

Christian Heimes wrote:
No, print invokes the tp_print slot of the float type. Some core types
have a special handler for print. The tp_print slot is not available
from Python code and most people don't know about it. :]

Why does print use the tp_print slot, rather than str()? Are the two
effectively redundant? If (non-repr) string representations are
frequently needed for a given type, could str() be implemented as a
reference to tp_slot, via a C-language extension?

As a side note, the print statement has FIVE related opcodes. Looks like
printing has been considered a very important operation...
 
R

robinsiebler

I did try searching, but I never found what I was looking for. This
thread has been very useful and informative. Thanks for all your
help! I was able to fix my problem. :)
 
D

Duncan Booth

Jeff Schwab said:
Christian said:
Dennis said:
What's wrong with just

str(0.3)

that's what "print" invokes, whereas the interpreter prompt is using

repr(0.3)

No, print invokes the tp_print slot of the float type. Some core types
have a special handler for print. The tp_print slot is not available
from Python code and most people don't know about it. :]

Why does print use the tp_print slot, rather than str()? Are the two
effectively redundant? If (non-repr) string representations are
frequently needed for a given type, could str() be implemented as a
reference to tp_slot, via a C-language extension?

The tp_print slot is used only when printing to a C file descriptor. In
most cases where it is used it simply duplicates the str and repr
functionality but avoids building the entire output in memory. It also
takes a flag argument indicating whether it should output the str or repr,
the latter being used when rendering the content inside an object such as a
dict or list.

So for example a dict's repr builds a list containing the repr of each
key/value pair and then joins the list using a comma separator. The
tp_print simply outputs the '{', then uses tp_print to output the repr of
the key and repr of the value with appropriate separators and finally the
closing '}'. It would not suprise me if by replacing the output of a single
large string with a lot of small calls to fputs 'print x' could be slower
than 'print str(x)'.
 
Z

Zentrader

That's a misconception. The decimal-module has a different base (10
instead of 2), and higher precision. But that doesn't change the fact
that it will expose the same rounding-errors as floats do - just for
different numbers.

Decimal("0.9999999999999999999999999999")

Surely you jest. Your example is exact to 28 digits. Your attempted
trick is to use a number that never ends (1/3=0.3333...). It would
only convert back to one if you have and infinite number of
significant digits. That has nothing to do with the Python decimal
module (which does what it claims). It is one of the idiosyncrasies
of the base 10 number system. Remember we are working with base 10
decimals and not fractions.
 
J

Jeff Schwab

Zentrader said:
Surely you jest. Your example is exact to 28 digits. Your attempted
trick is to use a number that never ends (1/3=0.3333...). It would
only convert back to one if you have and infinite number of
significant digits. That has nothing to do with the Python decimal
module (which does what it claims). It is one of the idiosyncrasies
of the base 10 number system. Remember we are working with base 10
decimals and not fractions.

Diez was not claiming that the decimal module did anything less than
what it promised. He just pointed out that the module does not support
infinitely precise floating-point arithmetic, any more than tradition
base-2 representations do. Please review the thread (the parts you
snipped) for clarification.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top