473,543 Members | 1,908 Online

# floating point glitch

Is this only on solaris ?

Python 2.3.3 (#1, Mar 19 2004, 16:18:33)
[GCC 2.95.2 19991024 (release)] on sunos5
a=[66.6, 333, 333, 1, 1234.5]
print a.count(333), a.count(66.6), a.count('x') 2 1 0 a.append(333)
print a

[66.599999999999 994, 333, 333, 1, 1234.5, 333]

Jul 18 '05 #1
15 1566
David O'Farrell <Da************ @ericsson.com> writes:
Is this only on solaris ?

No, it's inherent in how floating point conversions work. It happens
on all IEEE 754 machines. You don't need that fancy list-append stuff
to see it happen. Just type
66.6

66.599999999999 994

Jul 18 '05 #2
In article <7x************ @ruckus.brouhah a.com>,
Paul Rubin <http://ph****@NOSPAM.i nvalid> wrote:
David O'Farrell <Da************ @ericsson.com> writes:
Is this only on solaris ?

No, it's inherent in how floating point conversions work. It happens
on all IEEE 754 machines. You don't need that fancy list-append stuff
to see it happen. Just type
66.6

66.59999999999 9994

Next time someone tries to Wikify the definitive response to these
FAQs (I don't feel up to it myself, this week), let me recommend
mention of "Computing over the Reals: Where Turing Meets Newton"
<URL: http://www.ams.org/notices/200409/fea-blum.pdf >.
Jul 18 '05 #3
David O'Farrell <Da************ @ericsson.com> wrote:

Is this only on solaris ?
Every IEEE754 processor, every language.
Python 2.3.3 (#1, Mar 19 2004, 16:18:33)
[GCC 2.95.2 19991024 (release)] on sunos5
a=[66.6, 333, 333, 1, 1234.5]
print a.count(333), a.count(66.6), a.count('x')2 1 0 a.append(333)
print a[66.599999999999 994, 333, 333, 1, 1234.5, 333]

This is a FAQ. The short answer is that 66.6 cannot be represented exactly
in binary. It is an infinitely repeating fraction. (1234.5 is not, which
is why the same thing didn't happen to it.)

When you use print, it calls repr() to get the string representation. repr
tells you the exact value, as close as possible. That value is as close as
you can get to 66.6 using a 64-bit IEEE754 float.

str() lies to you to make you happy:
str(a[0])

66.6
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 18 '05 #4
Tim Roberts wrote:
>a=[66.6, 333, 333, 1, 1234.5]
>print a.count(333), a.count(66.6), a.count('x')

2 1 0
>a.append(3 33)
>print a

[66.599999999999 994, 333, 333, 1, 1234.5, 333]

This is a FAQ. The short answer is that 66.6 cannot be represented exactly
in binary. It is an infinitely repeating fraction. (1234.5 is not, which
is why the same thing didn't happen to it.)

When you use print, it calls repr() to get the string representation.

Actually, print essentialy uses str() to get the string representation.
But repr(list) or str(list) still gets the repr() of each item of the
list rather than the str():
class TestObject(obje ct): .... def __str__(self):
.... return "<str() called>"
.... def __repr__(self):
.... return "<repr() called>"
.... t = TestObject()
str(t) '<str() called>' repr(t) '<repr() called>' print t <str() called> t <repr() called> l = [TestObject()]
str(l) '[<repr() called>]' repr(l) '[<repr() called>]' print l [<repr() called>] l [<repr() called>]

One way around this is to call str for each item yourself:
"[%s]" % ", ".join(map( str, l))

'[<str() called>]'

You could also define a list subclass that does this for you.
--
Michael Hoffman
Jul 18 '05 #5
Michael Hoffman <m.************ *************** ******@example. com> writes:
Actually, print essentialy uses str() to get the string
representation. But repr(list) or str(list) still gets the repr() of
each item of the list rather than the str():

print .66 0.66 print [.66] [0.6600000000000 0003]

Yucch! Also, str is not invertible:
a=.66
b=a+1e-16
a==b False str(a) '0.66' str(b)

'0.66'
Jul 18 '05 #6
Paul Rubin <http://ph****@NOSPAM.i nvalid> wrote:
Michael Hoffman <m.************ *************** ******@example. com> writes:
Actually, print essentialy uses str() to get the string
representation. But repr(list) or str(list) still gets the repr() of
each item of the list rather than the str():

>>> print .66 0.66 >>> print [.66]

[0.6600000000000 0003]

Yucch! Also, str is not invertible:

Right! That's the point. str() is the perfect solution in those cases
where you want the language to lie to you. In many cases, that IS what you
want. repr() is the perfect solution when you need an invertible function.

And that's really the lesson that needs to be taught when this FAQ is A-ed.
--
- Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Jul 18 '05 #7
On Mon, 27 Sep 2004 23:21:12 -0700, Tim Roberts wrote:
Paul Rubin <http://ph****@NOSPAM.i nvalid> wrote:
Michael Hoffman <m.************ *************** ******@example. com> writes:
Actually, print essentialy uses str() to get the string
representation. But repr(list) or str(list) still gets the repr() of
each item of the list rather than the str():
>>> print .66

0.66
>>> print [.66]

[0.6600000000000 0003]

Yucch! Also, str is not invertible:

Right! That's the point. str() is the perfect solution in those cases
where you want the language to lie to you. In many cases, that IS what you
want. repr() is the perfect solution when you need an invertible function.

The "perfect solution" is either: (a) to print the minimal number of
digits that can maintain print/read consistency -- in this case, that
means printing "0.66", or (b) to print the actual, exact, decimal
representation of the value -- in this case, that means printing
"0.660000000000 000031086244689 504383131861686 70654296875"

And I think (a) is more perfect than (b) :-)
--
Malum est consilium quod mutari non potest -- Publilius Syrus

(concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz> "))
Jul 18 '05 #8
Paul Foley <se*@below.inva lid> writes:
The "perfect solution" is either: (a) to print the minimal number of
digits that can maintain print/read consistency -- in this case, that
means printing "0.66",

Nah, you can do that by printing everything as zero.
Jul 18 '05 #9
>>>>> Paul Rubin <http://ph****@NOSPAM.i nvalid> (PR) wrote:

PR> Paul Foley <se*@below.inva lid> writes:
The "perfect solution" is either: (a) to print the minimal number of
digits that can maintain print/read consistency -- in this case, that
means printing "0.66",

PR> Nah, you can do that by printing everything as zero.

That would not maintain print/read consistency, i.e. if you read back the
printed value you don't get the original value.
--
Piet van Oostrum <pi**@cs.uu.n l>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.***********@h ccnet.nl
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.