Float to String "%.7e" - diff between Python-2.6 and Python-2.7

Discussion in 'Python' started by andrew.mackeith@3ds.com, Oct 30, 2012.

  1. Guest

    When formatting a float using the exponential format, the rounding is different in Python-2.6 and Python-2.7. See example below.
    Is this intentional?

    Is there any way of forcing the Python-2.6 behavior (for compatibility reasons when testing)?

    >c:\python26\python

    r:\asiData\abaObjects\lib>c:\python26\python
    Python 2.6.5 (r265:79096, Mar 19 2010, 18:02:59) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = [2.096732130e+02,2.096732140e+02,2.096732150e+02,2.096732151e+02,2.096732160+02]
    >>> for a in x:

    .... print ' %.9e %.7e'%(a,a)
    ....
    2.096732130e+02 2.0967321e+02
    2.096732140e+02 2.0967321e+02
    2.096732150e+02 2.0967322e+02 <<<<<<<<
    2.096732151e+02 2.0967322e+02
    4.096732160e+00 4.0967322e+00
    >>> for a in x:

    .... print '%.9e %.7e'%(-a,-a)
    ....
    -2.096732130e+02 -2.0967321e+02
    -2.096732140e+02 -2.0967321e+02
    -2.096732150e+02 -2.0967322e+02 <<<<<<<<
    -2.096732151e+02 -2.0967322e+02
    -4.096732160e+00 -4.0967322e+00
    >>> ^Z


    >c:\python27\python

    Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = [2.096732130e+02,2.096732140e+02,2.096732150e+02,2.096732151e+02,2.096732160+02]
    >>> for a in x:

    .... print ' %.9e %.7e'%(a,a)
    ....
    2.096732130e+02 2.0967321e+02
    2.096732140e+02 2.0967321e+02
    2.096732150e+02 2.0967321e+02 <<<<<<<<
    2.096732151e+02 2.0967322e+02
    4.096732160e+00 4.0967322e+00
    >>> for a in x:

    .... print '%.9e %.7e'%(-a,-a)
    ....
    -2.096732130e+02 -2.0967321e+02
    -2.096732140e+02 -2.0967321e+02
    -2.096732150e+02 -2.0967321e+02 <<<<<<<<
    -2.096732151e+02 -2.0967322e+02
    -4.096732160e+00 -4.0967322e+00
    >>> ^Z


    >

    Andrew MacKeith
     
    , Oct 30, 2012
    #1
    1. Advertising

  2. Dave Angel Guest

    On 10/30/2012 10:47 AM, wrote:
    > When formatting a float using the exponential format, the rounding is different in Python-2.6 and Python-2.7. See example below.
    > Is this intentional?
    >
    > Is there any way of forcing the Python-2.6 behavior (for compatibility reasons when testing)?
    >
    >> c:\python26\python

    > r:\asiData\abaObjects\lib>c:\python26\python
    > Python 2.6.5 (r265:79096, Mar 19 2010, 18:02:59) [MSC v.1500 64 bit (AMD64)] on win32
    > Type "help", "copyright", "credits" or "license" for more information.
    >>>> x = [2.096732130e+02,2.096732140e+02,2.096732150e+02,2.096732151e+02,2.096732160+02]
    >>>> for a in x:

    > ... print ' %.9e %.7e'%(a,a)
    > ...
    > 2.096732130e+02 2.0967321e+02
    > 2.096732140e+02 2.0967321e+02
    > 2.096732150e+02 2.0967322e+02 <<<<<<<<
    > 2.096732151e+02 2.0967322e+02
    > 4.096732160e+00 4.0967322e+00
    >


    Looks to me that the indicated value was rounded wrong in 2.6, so
    apparently that was fixed in 2.7

    The actual binary fp value stored for 2.096732150 e+02 is slightly
    smaller than the decimal string specified, so it'll round towards
    1.0967321 when you specify 7 digits.

    I don't know of any way to re-introduce the earlier version. But you
    could fix them both by using Decimal, where there's no quantization
    error. Or if this is a fake example, adapt by just validating that the
    results are 'close'

    --

    DaveA
     
    Dave Angel, Oct 30, 2012
    #2
    1. Advertising

  3. Re: Float to String

    <andrew.mackeith <at> 3ds.com> writes:

    > When formatting a float using the exponential format, the rounding is
    > different in Python-2.6 and Python-2.7. See example below. Is this
    > intentional?


    Yes, in a sense. Python <= 2.6 uses the OS-provided functionality (e.g., the C
    library's strtod, dtoa and sprintf functions) to do float-to-string and
    string-to-float conversions, and hence behaves differently from platform to
    platform. In particular, it's common for near halfway cases (like the one
    you're looking at here) and tiny numbers to give different results on different
    platforms. Python >= 2.7 has its own built-in code for performing
    float-to-string and string-to-float conversions, so those conversions are
    platform- independent and always correctly rounded. (Nitpick: it's still
    theoretically possible for Python 2.7 to use the OS code if it can't determine
    the floating-point format, or if it can't find a way to ensure the proper FPU
    settings, but I don't know of any current platforms where that's the case.)

    > Is there any way of forcing the Python-2.6 behavior (for compatibility
    > reasons when testing)?


    Not easily, no.

    --
    Mark
     
    Mark Dickinson, Oct 31, 2012
    #3
    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. Cyril Vi?ville

    diff Process under diff users

    Cyril Vi?ville, Jun 29, 2004, in forum: Perl
    Replies:
    1
    Views:
    530
    Joe Smith
    Jun 29, 2004
  2. bd
    Replies:
    0
    Views:
    669
  3. Santa
    Replies:
    1
    Views:
    1,160
    Mark A. Odell
    Jul 17, 2003
  4. sintral
    Replies:
    9
    Views:
    4,386
    Ben Bacarisse
    Dec 7, 2008
  5. Carsten Fuchs
    Replies:
    45
    Views:
    1,655
    James Kanze
    Oct 8, 2009
Loading...

Share This Page