round in 2.6 and 2.7

Discussion in 'Python' started by Hrvoje Niksic, Dec 23, 2010.

  1. I stumbled upon this. Python 2.6:

    Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 9.95

    9.9499999999999993
    >>> "%.16g" % 9.95

    '9.949999999999999'
    >>> round(9.95, 1)

    10.0

    So it seems that Python is going out of its way to intuitively round
    9.95, while the repr retains the unnecessary digits. However, with 2.7
    it's exactly the opposite:

    Python 2.7.0+ (r27:82500, Sep 15 2010, 18:04:55)
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 9.95

    9.95
    >>> "%.16g" % 9.95

    '9.949999999999999'
    >>> round(9.95, 1)

    9.9

    Is the change to round() expected?
    Hrvoje Niksic, Dec 23, 2010
    #1
    1. Advertising

  2. Hrvoje Niksic

    macm Guest

    On Dec 23, 4:57 pm, Hrvoje Niksic <> wrote:
    > I stumbled upon this.  Python 2.6:
    >
    > Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
    > [GCC 4.4.5] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.>>> 9.95
    > 9.9499999999999993
    > >>> "%.16g" % 9.95

    > '9.949999999999999'
    > >>> round(9.95, 1)

    >
    > 10.0
    >
    > So it seems that Python is going out of its way to intuitively round
    > 9.95, while the repr retains the unnecessary digits.  However, with 2.7
    > it's exactly the opposite:
    >
    > Python 2.7.0+ (r27:82500, Sep 15 2010, 18:04:55)
    > [GCC 4.4.5] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.>>> 9.95
    > 9.95
    > >>> "%.16g" % 9.95

    > '9.949999999999999'
    > >>> round(9.95, 1)

    >
    > 9.9
    >
    > Is the change to round() expected?



    My guess is

    use decimal module.

    Regards

    mario
    macm, Dec 23, 2010
    #2
    1. Advertising

  3. > Type "help", "copyright", "credits" or "license" for more information.
    >>>> 9.95

    > 9.9499999999999993
    >>>> "%.16g" % 9.95

    > '9.949999999999999'
    >>>> round(9.95, 1)

    > 10.0
    >
    > So it seems that Python is going out of its way to intuitively round
    > 9.95, while the repr retains the unnecessary digits.


    The 2.6 result is simply incorrect. 9.95 cannot be represented as a
    floating point number; the number that is closest to it is actually
    smaller than 9.95. Rounding that number should give 9.9 (or something
    close to it - 9.9 cannot be represented, either), not 10.0.

    >>>> round(9.95, 1)

    > 9.9
    >
    > Is the change to round() expected?


    Yes. It's a bug fix described in "What's new in Python 2.7" thus:

    Float-to-string and string-to-float conversions are correctly rounded.
    The round() function is also now correctly rounded.

    Not sure that this is correct English; I think it means that the
    round() function is now correct.

    Regards,
    Martin
    Martin v. Loewis, Dec 23, 2010
    #3
  4. Am 23.12.2010 19:57, schrieb Hrvoje Niksic:
    > I stumbled upon this. Python 2.6:
    >
    > Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
    > [GCC 4.4.5] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    >>>> 9.95

    > 9.9499999999999993
    >>>> "%.16g" % 9.95

    > '9.949999999999999'
    >>>> round(9.95, 1)

    > 10.0
    >
    > So it seems that Python is going out of its way to intuitively round
    > 9.95, while the repr retains the unnecessary digits. However, with 2.7
    > it's exactly the opposite:
    >
    > Python 2.7.0+ (r27:82500, Sep 15 2010, 18:04:55)
    > [GCC 4.4.5] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    >>>> 9.95

    > 9.95
    >>>> "%.16g" % 9.95

    > '9.949999999999999'
    >>>> round(9.95, 1)

    > 9.9
    >
    > Is the change to round() expected?

    Indeed:
    http://svn.python.org/view?view=rev&revision=76373
    Stefan Sonnenberg-Carstens, Dec 23, 2010
    #4
  5. "Martin v. Loewis" <> writes:

    >> Type "help", "copyright", "credits" or "license" for more information.
    >>>>> 9.95

    >> 9.9499999999999993
    >>>>> "%.16g" % 9.95

    >> '9.949999999999999'
    >>>>> round(9.95, 1)

    >> 10.0
    >>
    >> So it seems that Python is going out of its way to intuitively round
    >> 9.95, while the repr retains the unnecessary digits.

    >
    > The 2.6 result is simply incorrect.

    [...]
    > Yes. It's a bug fix described in "What's new in Python 2.7" thus:


    That makes sense, thanks. Even within Python 2.6, rounding with
    different methods could produce inconsistent results:

    >>> round(9.95, 1)

    10.0
    >>> '%.1f' % 9.95

    '9.9'
    Hrvoje Niksic, Dec 24, 2010
    #5
  6. On Dec 23, 6:57 pm, Hrvoje Niksic <> wrote:
    > I stumbled upon this.  Python 2.6:
    >
    > >>> round(9.95, 1)

    >
    > 10.0
    >
    > So it seems that Python is going out of its way to intuitively round
    > 9.95, while the repr retains the unnecessary digits.


    No, Python's not doing anything clever here. Python 2.6 uses a simple
    rounding algorithm that frequently gives the wrong answer for halfway
    or near-halfway cases. It's just luck that in this particular case it
    gives the apparently-correct (but actually incorrect) answer.
    Martin's already explained that the 2.7 behaviour is correct, and
    agrees with string formatting. However, note that there's still a
    disconnect between these two operations in Python 2.7:

    >>> round(1.25, 1)

    1.3
    >>> format(1.25, '.1f')

    '1.2'

    That's because 'round' in Python 2.x (including 2.7) still rounds
    exact halfway cases away from zero, while string formatting rounds
    them to the value with even last digit. In Python 3.x, even this
    discrepancy is fixed---everything does round-halfway-to-even.

    > Is the change to round() expected?


    Expected, and intentional. :)

    [Martin]
    > "Float-to-string and string-to-float conversions are correctly rounded.
    > The round() function is also now correctly rounded."
    >
    > Not sure that this is correct English; I think it means that the
    > round() function is now correct.


    Well, the correct result of the example the OP gave would be 9.9
    exactly. But since 9.9 isn't exactly representable as a Python float,
    we necessarily get an approximation. The language above is intended
    to convey that it's the 'correctly rounded' approximation---that is,
    the closest Python float to the true value of 9.9 (with halfway cases
    rounded to even, as usual).

    Mark
    Mark Dickinson, Dec 27, 2010
    #6
  7. >> "Float-to-string and string-to-float conversions are correctly rounded.
    >> The round() function is also now correctly rounded."
    >>
    >> Not sure that this is correct English; I think it means that the
    >> round() function is now correct.

    >
    > Well, the correct result of the example the OP gave would be 9.9
    > exactly. But since 9.9 isn't exactly representable as a Python float,
    > we necessarily get an approximation. The language above is intended
    > to convey that it's the 'correctly rounded' approximation


    I see. Shouldn't it say then "The round() function
    gives/produces/returns correctly rounded results now", instead of saying
    that
    the round function *is* correctly rounded? ISTM that the round
    function cannot be rounded (correctly or not):

    py> round(round)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: a float is required

    But then, I'm not a native speaker (of English).

    Regards,
    Martin
    Martin v. Loewis, Dec 28, 2010
    #7
  8. Hrvoje Niksic

    Terry Reedy Guest

    On 12/28/2010 4:47 PM, Martin v. Loewis wrote:
    >>> "Float-to-string and string-to-float conversions are correctly rounded.
    >>> The round() function is also now correctly rounded."


    The second line was written to be parallel to the first, but the first
    is slightly ambiguous in that 'conversions' can refer to either process
    (not rounded, correctly or otherwise ;-) or result. However the
    parallelism does not does as 'round() function' is the instrument of the
    process and definitly not the result.

    ....

    > I see. Shouldn't it say then "The round() function
    > gives/produces/returns correctly rounded results now", instead of saying
    > that
    > the round function *is* correctly rounded? ISTM that the round
    > function cannot be rounded (correctly or not):


    In 2.7 "Float-to-string and string-to-float conversion results are
    correctly rounded, as are the results of the round() function."

    --
    Terry Jan Reedy
    Terry Reedy, Dec 28, 2010
    #8
  9. On Dec 28, 9:47 pm, "Martin v. Loewis" <> wrote:
    > >> "Float-to-string and string-to-float conversions are correctly rounded..
    > >> The round() function is also now correctly rounded."

    >
    > >> Not sure that this is correct English; I think it means that the
    > >> round() function is now correct.

    >
    > > Well, the correct result of the example the OP gave would be 9.9
    > > exactly.  But since 9.9 isn't exactly representable as a Python float,
    > > we necessarily get an approximation.  The language above is intended
    > > to convey that it's the 'correctly rounded' approximation

    >
    > I see. Shouldn't it say then "The round() function
    > gives/produces/returns correctly rounded results now", instead of saying
    > that
    > the round function *is* correctly rounded? ISTM that the round
    > function cannot be rounded (correctly or not):
    >
    > py> round(round)
    > Traceback (most recent call last):
    >   File "<stdin>", line 1, in <module>
    > TypeError: a float is required
    >
    > But then, I'm not a native speaker (of English).


    I dare say that you're just as much a native speaker as anyone else
    when it comes to the language of floating-point arithmetic. Not sure
    English comes into it that much. :)

    Sure, I agree it's probably a slight abuse of language to refer to a
    function as 'correctly rounded', but I think it's a fairly standard
    abuse. From the two nearest references to hand: IEEE 754-2008 has a
    whole section entitled 'Recommended correctly rounded functions' (nit:
    shouldn't there be a hyphen in that title?), and persists in referring
    to 'correctly rounded' conversions. The more formal uses in that
    document do indeed refer to single values, though. ("A conforming
    function shall return results correctly rounded ...") The 'Handbook of
    Floating-Point Arithmetic' by Muller et. al. gives a definition of a
    correctly rounded function in section 2.2. "When the exact result of
    a function is rounded according to a given rounding mode ..., one says
    that the function is *correctly rounded*."

    It's not so dissimilar from other mathematical abuses, like describing
    a real-valued function as 'positive', when what you actually mean is
    that all its values are positive.

    It's also slightly unsettling usage for me, not least because the
    statement 'f is correctly rounded' for a floating-point function f is
    really a statement about *two* functions: namely, f (a function from
    floating-point numbers to floating-point numbers) and the true
    mathematical function that it's based on; the identity of the
    underlying mathematical function is left implicit.

    --
    Mark
    Mark Dickinson, Dec 29, 2010
    #9
    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. Mike

    ListBox and round-trips

    Mike, May 4, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    386
  2. Replies:
    0
    Views:
    1,073
  3. OliverMarchand

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

    OliverMarchand, Apr 12, 2006, in forum: Ruby
    Replies:
    2
    Views:
    212
    OliverMarchand
    Apr 12, 2006
  4. cerr

    reading file round and round

    cerr, Mar 19, 2010, in forum: Perl Misc
    Replies:
    6
    Views:
    171
    Peter J. Holzer
    Mar 20, 2010
  5. VK
    Replies:
    15
    Views:
    1,130
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page