Who told str() to round my int()'s!!!

A

Adam W.

After a fair amount of troubleshooting of why my lists were coming
back a handful of digits short, and the last digit rounded off, I
determined the str() function was to blame:

Why in the world does str() have any business rounding my numbers, and
how do I get around this?
 
M

Marc 'BlackJack' Rintsch

After a fair amount of troubleshooting of why my lists were coming
back a handful of digits short, and the last digit rounded off, I
determined the str() function was to blame:


Why in the world does str() have any business rounding my numbers, and
how do I get around this?

If `str()` would not round you would get very long numbers because of the
inaccuracies of floating point values. I know Python is lying when 0.1
prints as 0.1, but do you really want to see
0.10000000000000000555111512312578270211815834045410156250 instead?

Use string formatting to tell the number of digits you want to see:

In [16]: '%.56f' % 0.1
Out[16]: '0.10000000000000000555111512312578270211815834045410156250'

Ciao,
Marc 'BlackJack' Rintsch
 
A

Adam W.

If `str()` would not round you would get very long numbers because of the
inaccuracies of floating point values. I know Python is lying when 0.1
prints as 0.1, but do you really want to see
0.10000000000000000555111512312578270211815834045410156250 instead?

I want str() to convert whatever I give it to a string and do nothing
else. I will worry about long FP values in previous steps. I still
find it very disturbing that str() is doing this AND it is
undocumented in all of my books.
Use string formatting to tell the number of digits you want to see:

In [16]: '%.56f' % 0.1
Out[16]: '0.10000000000000000555111512312578270211815834045410156250'

The book I used to learn Python never introduced string formatting, I
suppose I will have to use another and learn it if that is the only
way...
 
R

Roel Schroeven

Adam W. schreef:
After a fair amount of troubleshooting of why my lists were coming
back a handful of digits short, and the last digit rounded off, I
determined the str() function was to blame:

'0.00712997203847'

Why in the world does str() have any business rounding my numbers, and
how do I get around this?

You could use repr() instead of str() (AFAIK that's what the interactive
interpreter used to print your foonum), but in any case you should be
aware of the limits inherent in floating point arithmetic and in
conversions between decimal and binary fractions. See e.g.
http://docs.python.org/tut/node16.html
 
M

Marc 'BlackJack' Rintsch

I want str() to convert whatever I give it to a string and do nothing
else.

But those long numbers are very disturbing and nobody wants them as usual
string representation. Most programming languages "lie" at this point to
the user so it would be very unexpected too.
I will worry about long FP values in previous steps.

What do you mean here? Have you looked at the example above? That is the
closest you get to 0.1 -- there's no way to round the floating point
value, it can only be done by converting to `str()`.

Ciao,
Marc 'BlackJack' Rintsch
 
Z

Zentrader

After a fair amount of troubleshooting of why my lists were coming
back a handful of digits short, and the last digit rounded off, I
determined the str() function was to blame:

'0.00712997203847'

Why in the world does str() have any business rounding my numbers, and
how do I get around this?

If 15 digit precision is a concern, I would suggest that you us the
decimal class instead of floating points. Floating point problems on
X86 machines are well documented.
http://docs.python.org/lib/module-decimal.html
http://pydoc.org/2.4.1/decimal.html
http://gmpy.sourceforge.net/
 
S

Steve Holden

Roel said:
Adam W. schreef:

You could use repr() instead of str() (AFAIK that's what the interactive
interpreter used to print your foonum), but in any case you should be
aware of the limits inherent in floating point arithmetic and in
conversions between decimal and binary fractions. See e.g.
http://docs.python.org/tut/node16.html
I should also point out that the subject line for this thread is
inaccurate, as it wasn't rounding ints at all.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
J

John Machin

If 15 digit precision is a concern, I would suggest that you us the
decimal class instead of floating points. Floating point problems on
X86 machines are well documented.http://docs.python.org/lib/module-d....4.1/decimal.htmlhttp://gmpy.sourceforge.net/

If you are concerned with precision of *communication*:

The problem is not with floating "points" in general; floating point
arithmetic can be done using a decimal representation for the numbers.
The problem is not with "X86" machines in particular; just about all
modern machines have floating point hardware which implements the IEEE
754 standard for binary flaoting point arithmetic. The problem is with
trying to represent in one base (e.g. 10) a non-integer number that is
expressed in a different base (e.g. 2) -- where the number can be
represented exactly only in one base (e.g. 1./10.) or in neither (e.g.
1./3.)
 
B

Bjoern Schliessmann

Adam said:
Why in the world does str() have any business rounding my numbers,

You are at the floating point numbers precision limit. Using str,
numbers are rounded to your machine's float precision in decimal
notation. Since floats are internally represented in binary
notation of constant precision, the decimal precision expressed in
number of places is not constant. Thus, safe rounding must be
applied to get consistent results.
and how do I get around this?

If you don't want this (and thus introduce random deviations if you
assume greater precision than the number of places str gives you),
use repr. You've been warned.
'0.0071299720384678782'

Regards,


Björn
 
A

A.T.Hofkamp

After a fair amount of troubleshooting of why my lists were coming
back a handful of digits short, and the last digit rounded off, I
determined the str() function was to blame:


Why in the world does str() have any business rounding my numbers, and
how do I get around this?

You have got a few good reactions already. What is not mentioned yet however is
the difference between str() and repr().


Python has two ways to stringify an object:

str() is intended to deliver a 'human-readable' representation of its argument,
and typically, humans think a few digits of a float is enough.

The repr() on the other hand is intended to deliver a 'machine-reproducible'
string representation of its argument, ie after "y = eval(repr(x))" y == x
should hold.

Note that no rounding occurs with the floating point number, arguments of both
str() and repr() are not changed.


So, depending on your intentions of str(foonum), you should either explicitly
format your floating point number yourself (ie if you want a more precise
human-readable representation of the number), or you should use repr() (if you
intend to use the string representation for reproducing the same object
elsewhere by a machine).


Albert
 
D

Donn Cave

"A.T.Hofkamp said:
You have got a few good reactions already. What is not mentioned yet however
is
the difference between str() and repr().

If only it could have stayed that way.
Python has two ways to stringify an object:

str() is intended to deliver a 'human-readable' representation of its
argument,
and typically, humans think a few digits of a float is enough.

This is precisely the problem with this notion though: you don't
have a good way to predict what will be "readable" (or worse, "friendly"
as people used to say in this context) to a human. Adam W reads the
output of str() and it isn't what he expected, though usually it's
the other way around where people complain about repr().

More generally, there just isn't any humanity in the way we render
objects as text strings, a priori. If there is any such thing, it
depends completely on the context. To invite the author of an object
to devise a text rendition that will be humane (friendly, readable
or whatever) is to waste his or her time. There are better ways to
conceive of this str/repr distinction, and they've been discussed
to death. python.org documentation will probably never be fixed.

Donn Cave, (e-mail address removed)
 
L

Larry Bates

Steve said:
I should also point out that the subject line for this thread is
inaccurate, as it wasn't rounding ints at all.

regards
Steve

What are they teaching in schools these days? I see questions like this and the
equally perplexing "why don't floats represent numbers exactly?" or the mildy
amusing "how do I write bytes not characters to a file" questions at least once
a week on this forum.

-Larry
 
A

A.T.Hofkamp

What are they teaching in schools these days? I see questions like this and the
equally perplexing "why don't floats represent numbers exactly?" or the mildy
amusing "how do I write bytes not characters to a file" questions at least once
a week on this forum.

Who says that schools teach that to every body?
Python is a popular language, so there are a lot non-cs people here. I can
imagine that eg a user with a background in history or geography has never
encountered these things before.
(Python got to start programming, and now they suddenly have to deal with
inaccurate floats of the otherwise so precise computer :) )


Albert
 
J

John Nagle

Actually, that's a reasonable question, and one that Python didn't do
quite right.

Remember, in the beginning, Python had only ASCII strings, which
were equivalent to arrays of bytes. Then came Unicode strings. Then
came the restriction of ASCII chars to 0..127. Except that you can
still store binary bytes in ASCII strings, subject to some limitations.

The next logical step is a complete separation of binary data handling
from text string handling, probably using some type in "numarray" for
arrays of bytes.

John Nagle
 
N

Neil Cerutti

Actually, that's a reasonable question, and one that Python didn't do
quite right.

Remember, in the beginning, Python had only ASCII strings, which
were equivalent to arrays of bytes. Then came Unicode strings. Then
came the restriction of ASCII chars to 0..127. Except that you can
still store binary bytes in ASCII strings, subject to some limitations.

The next logical step is a complete separation of binary data handling
from text string handling, probably using some type in "numarray" for
arrays of bytes.

Python 3000 makes unicode the standard string type, and ushers in
a new type name for the old str type called, I think, 'bytes'. So
the 3000 devs seem to agree with you to some extent.
 
D

Diez B. Roggisch

John said:
Actually, that's a reasonable question, and one that Python didn't do
quite right.

Remember, in the beginning, Python had only ASCII strings, which
were equivalent to arrays of bytes. Then came Unicode strings. Then
came the restriction of ASCII chars to 0..127. Except that you can
still store binary bytes in ASCII strings, subject to some limitations.

Sorry, but that's bogus. Python had byte-strings from the beginning.
Nothing to do with ASCII. Which is an encoding-standard that has ALWAYS
been limited to the numbers 0..127.

All that changed was the introduction of unicode-objects and due to the
fact that these need to be serialized to/from bytestrings the
introduction of ASCII as default-encoding.

So no "still storing" or anything such.

Diez
 
C

Chris Mellon

Actually, that's a reasonable question, and one that Python didn't do
quite right.

No it isn't. You can't write anything except bytes to a file (or to a
socket, or, in fact, to any form of IO) and anyone who thinks they can
do anything different is confused.
Remember, in the beginning, Python had only ASCII strings, which
were equivalent to arrays of bytes. Then came Unicode strings. Then
came the restriction of ASCII chars to 0..127. Except that you can
still store binary bytes in ASCII strings, subject to some limitations.

I agree that the name of the string object is a misnomer, because it's
actually a sequence of bytes.

There's no limitation to anything you can stick it - a python 2.x
string object can contain any arbitrary sequence of bytes.

Where you may believe that you see a limitation is in the default
implicit unicode conversion, which assumes non-extended ascii and
errors on values over 127. This is a pragmatic decision which assumes
that being able to print unicode objects without hoop-jumping is
preferable to preventing the errors and confusion caused by implicit
conversion. I am not 100% certain the correct decision was made -
there's a lot of confusion on this list that would be easier to
explain if any attempt to convert unicode to bytes or vice versa
required an explicit encoding.
The next logical step is a complete separation of binary data handling
from text string handling, probably using some type in "numarray" for
arrays of bytes.

There are still lots of cases where it's convenient to work with
binary data as if it were ascii text, and overlap between "real"
binary data work and textual data work.
 

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

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top