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

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

  1. Adam W.

    Adam W. Guest

    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?
    Adam W., Aug 11, 2007
    #1
    1. Advertising

  2. 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
    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
    Marc 'BlackJack' Rintsch, Aug 11, 2007
    #2
    1. Advertising

  3. Adam W.

    Adam W. Guest

    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
    > 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...
    Adam W., Aug 11, 2007
    #3
  4. 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:
    >
    >>>> 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
    #4
  5. 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
    >> 0.10000000000000000555111512312578270211815834045410156250 instead?

    >
    > 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
    #5
  6. Adam W.

    Zentrader Guest

    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/
    Zentrader, Aug 11, 2007
    #6
  7. Adam W.

    Steve Holden Guest

    Roel Schroeven wrote:
    > 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:
    >>
    >>>>> 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
    #7
  8. Adam W.

    John Machin Guest

    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
    #8
  9. Adam W. wrote:

    > 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
    #9
  10. Adam W.

    A.T.Hofkamp Guest

    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
    #10
  11. Adam W.

    Donn Cave Guest

    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
    #11
  12. Adam W.

    Larry Bates Guest

    Steve Holden wrote:
    > Roel Schroeven wrote:
    >> 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:
    >>>
    >>>>>> 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
    #12
  13. Adam W.

    A.T.Hofkamp Guest

    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
    #13
  14. Adam W.

    John Nagle Guest

    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
    #14
  15. Adam W.

    Neil Cerutti Guest

    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
    #15
  16. 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
    #16
  17. Adam W.

    Chris Mellon Guest

    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
    #17
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    1,069
  2. Schnoffos
    Replies:
    2
    Views:
    1,195
    Martien Verbruggen
    Jun 27, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,609
    Old Wolf
    Jan 20, 2004
  4. OliverMarchand

    Float.round - should it be round-to-even

    OliverMarchand, Apr 12, 2006, in forum: Ruby
    Replies:
    2
    Views:
    208
    OliverMarchand
    Apr 12, 2006
  5. cerr

    reading file round and round

    cerr, Mar 19, 2010, in forum: Perl Misc
    Replies:
    6
    Views:
    168
    Peter J. Holzer
    Mar 20, 2010
Loading...

Share This Page