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

Discussion in 'Python' started by Adam W., Aug 11, 2007.

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:

>>> foonum

0.0071299720384678782
>>> str(foonum)

'0.00712997203847'
>>>

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

2. ### Marc 'BlackJack' RintschGuest

On Sat, 11 Aug 2007 16:40:02 +0000, Adam W. wrote:

> 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:
>
>>>> foonum

> 0.0071299720384678782
>>>> str(foonum)

> '0.00712997203847'
>>>>

>
> 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

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

Marc 'BlackJack' Rintsch, Aug 11, 2007

On Aug 11, 12:53 pm, Marc 'BlackJack' Rintsch <> wrote:
> 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

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...

4. ### Roel SchroevenGuest

> 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:
>
>>>> foonum

> 0.0071299720384678782
>>>> str(foonum)

> '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

--
If I have been able to see further, it was only because I stood
on the shoulders of giants. -- Isaac Newton

Roel Schroeven

Roel Schroeven, Aug 11, 2007
5. ### Marc 'BlackJack' RintschGuest

On Sat, 11 Aug 2007 17:10:05 +0000, Adam W. wrote:

> On Aug 11, 12:53 pm, Marc 'BlackJack' Rintsch <> wrote:
>> 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

>
> 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

Marc 'BlackJack' Rintsch, Aug 11, 2007

On Aug 11, 9:40 am, "Adam W." <> wrote:
> 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:
>
> >>> foonum

>
> 0.0071299720384678782
>
> >>> str(foonum)

> '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/

7. ### Steve HoldenGuest

Roel Schroeven wrote:
>> 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:
>>
>>>>> foonum

>> 0.0071299720384678782
>>>>> str(foonum)

>> '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
>
>

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 -------------

Steve Holden, Aug 11, 2007
8. ### John MachinGuest

On Aug 12, 5:37 am, Zentrader <> wrote:
> On Aug 11, 9:40 am, "Adam W." <> wrote:
>
> > 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:

>
> > >>> foonum

>
> > 0.0071299720384678782

>
> > >>> str(foonum)

> > '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-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.)

John Machin, Aug 11, 2007
9. ### Bjoern SchliessmannGuest

> 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.

>>> foonum = .0071299720384678782
>>> foonum

0.0071299720384678782
>>> str(foonum)

'0.00712997203847'
>>> repr(foonum)

'0.0071299720384678782'

Regards,

Björn

--
BOFH excuse #5:

static from plastic slide rules

Bjoern Schliessmann, Aug 11, 2007
10. ### A.T.HofkampGuest

On 2007-08-11, Adam W. <> wrote:
> 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:
>
>>>> foonum

> 0.0071299720384678782
>>>> str(foonum)

> '0.00712997203847'
>>>>

>
> 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

A.T.Hofkamp, Aug 15, 2007
11. ### Donn CaveGuest

In article <>,
"A.T.Hofkamp" <> wrote:

> On 2007-08-11, Adam W. <> wrote:
> > 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:
> >
> >>>> foonum

> > 0.0071299720384678782
> >>>> str(foonum)

> > '0.00712997203847'
> >>>>

> >
> > 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().

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,

Donn Cave, Aug 15, 2007
12. ### Larry BatesGuest

Steve Holden wrote:
> Roel Schroeven wrote:
>>> 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:
>>>
>>>>>> foonum
>>> 0.0071299720384678782
>>>>>> str(foonum)
>>> '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
>>
>>

> 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

Larry Bates, Aug 15, 2007
13. ### A.T.HofkampGuest

On 2007-08-15, Larry Bates <> wrote:
>
> 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

A.T.Hofkamp, Aug 16, 2007
14. ### John NagleGuest

A.T.Hofkamp wrote:
> On 2007-08-15, Larry Bates <> wrote:
>
>>or the mildy
>>amusing "how do I write bytes not characters to a file" questions at least once
>>a week on this forum.

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

John Nagle, Aug 16, 2007
15. ### Neil CeruttiGuest

On 2007-08-16, John Nagle <> wrote:
>>>or the mildy amusing "how do I write bytes not characters to a
>>>file" questions at least once a week on this forum.

>
> 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.

--
Neil Cerutti
Ushers will eat latecomers. --Church Bulletin Blooper

Neil Cerutti, Aug 16, 2007
16. ### Diez B. RoggischGuest

John Nagle schrieb:
> A.T.Hofkamp wrote:
>> On 2007-08-15, Larry Bates <> wrote:
>>
>>> or the mildy
>>> amusing "how do I write bytes not characters to a file" questions at
>>> least once
>>> a week on this forum.

>
> 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

Diez B. Roggisch, Aug 16, 2007
17. ### Chris MellonGuest

On 8/16/07, John Nagle <> wrote:
> A.T.Hofkamp wrote:
> > On 2007-08-15, Larry Bates <> wrote:
> >
> >>or the mildy
> >>amusing "how do I write bytes not characters to a file" questions at least once
> >>a week on this forum.

>
> 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.

> John Nagle
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Chris Mellon, Aug 16, 2007