Why the nonsense number appears?

Discussion in 'Python' started by Johnny Lee, Oct 31, 2005.

  1. Johnny Lee

    Johnny Lee Guest

    Hi,
    Pls take a look at this code:

    ----------
    >>> t1 = "1130748744"
    >>> t2 = "461"
    >>> t3 = "1130748744"
    >>> t4 = "500"
    >>> time1 = t1+"."+t2
    >>> time2 = t3+"."+t4
    >>> print time1, time2

    1130748744.461 1130748744.500
    >>> float(time2) - float(time1)

    0.039000034332275391
    >>>


    Why are there so many nonsense tails? thanks for your help.

    Regards,
    Johnny
    Johnny Lee, Oct 31, 2005
    #1
    1. Advertising

  2. Johnny Lee wrote:
    >>>>print time1, time2

    >
    > 1130748744.461 1130748744.500
    >
    >>>>float(time2) - float(time1)

    >
    > 0.039000034332275391
    >
    >
    > Why are there so many nonsense tails? thanks for your help.


    http://en.wikipedia.org/wiki/Floating_point#Problems_with_floating-point,
    especially 'Rounding'. Or google for "gloating point precision" if you
    need more details.

    Daniel
    Daniel Dittmar, Oct 31, 2005
    #2
    1. Advertising

  3. Johnny Lee

    Yu-Xi Lim Guest

    Johnny Lee wrote:
    <snip>
    > Why are there so many nonsense tails? thanks for your help.


    I guess you were expecting 0.039? You first need to understand floating
    point numbers:

    http://docs.python.org/tut/node16.html

    What you see are the effects of representation errors.

    The solution is presented here:
    http://www.python.org/peps/pep-0327.html

    But briefly, it means your code should read:

    from decimal import *
    t1 = "1130748744"
    t2 = "461"
    t3 = "1130748744"
    t4 = "500"
    time1 = t1+"."+t2
    time2 = t3+"."+t4
    print time1, time2
    Decimal(time2) - Decimal(time1)
    Yu-Xi Lim, Oct 31, 2005
    #3
  4. Johnny Lee enlightened us with:
    > Why are there so many nonsense tails? thanks for your help.


    Because if the same reason you can't write 1/3 in decimal:

    http://docs.python.org/tut/node16.html

    Sybren
    --
    The problem with the world is stupidity. Not saying there should be a
    capital punishment for stupidity, but why don't we just take the
    safety labels off of everything and let the problem solve itself?
    Frank Zappa
    Sybren Stuvel, Oct 31, 2005
    #4
  5. Johnny Lee

    Ben O'Steen Guest

    On Mon, October 31, 2005 9:39, Sybren Stuvel said:
    > Johnny Lee enlightened us with:
    >> Why are there so many nonsense tails? thanks for your help.

    >
    > Because if the same reason you can't write 1/3 in decimal:
    >
    > http://docs.python.org/tut/node16.html
    >
    > Sybren
    > --
    > The problem with the world is stupidity. Not saying there should be a
    > capital punishment for stupidity, but why don't we just take the
    > safety labels off of everything and let the problem solve itself?
    > Frank Zappa
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >



    I think that the previous poster was asking something different. I think
    he was asking something like this:

    If

    >>> t1 = 0.500
    >>> t2 = 0.461
    >>> print t1-t2

    0.039

    Then why:

    >>> t1 += 12345678910
    >>> t2 += 12345678910
    >>> # Note, both t1 and t2 have been incremented by the same amount.
    >>> print t1-t2

    0.0389995574951

    It appears Yu-Xi Lim beat me to the punch. Using decimal as opposed to
    float sorts out this error as floats are not built to handle the size of
    number used here.

    Ben
    Ben O'Steen, Oct 31, 2005
    #5
  6. Ben O'Steen enlightened us with:
    > I think that the previous poster was asking something different.


    It all boils down to floating point inprecision.

    > If
    >
    >>>> t1 = 0.500
    >>>> t2 = 0.461
    >>>> print t1-t2

    > 0.039
    >
    > Then why:
    >
    >>>> t1 += 12345678910
    >>>> t2 += 12345678910
    >>>> # Note, both t1 and t2 have been incremented by the same amount.
    >>>> print t1-t2

    > 0.0389995574951


    It's easier to explain in decimals. Just assume you only have memory
    to keep three decimals. 12345678910.500 is internally stored as
    something like 1.23456789105e10. Strip that to three decimals, and you
    have 1.234e10. In that case, t1 - t2 = 1.234e10 - 1.234e10 = 0.

    > Using decimal as opposed to float sorts out this error as floats are
    > not built to handle the size of number used here.


    They can handle the size just fine. What they can't handle is 1/1000th
    precision when using numbers in the order of 1e10.

    Sybren
    --
    The problem with the world is stupidity. Not saying there should be a
    capital punishment for stupidity, but why don't we just take the
    safety labels off of everything and let the problem solve itself?
    Frank Zappa
    Sybren Stuvel, Oct 31, 2005
    #6
  7. Johnny Lee

    Ben O'Steen Guest

    On Mon, October 31, 2005 10:23, Sybren Stuvel said:
    > Ben O'Steen enlightened us with:
    >> Using decimal as opposed to float sorts out this error as floats are
    >> not built to handle the size of number used here.

    >
    > They can handle the size just fine. What they can't handle is 1/1000th
    > precision when using numbers in the order of 1e10.
    >


    I used the word 'size' here incorrectly, I intended to mean 'length'
    rather than numerical value. Sorry for the confusion :)



    > Sybren
    > --
    > The problem with the world is stupidity. Not saying there should be a
    > capital punishment for stupidity, but why don't we just take the
    > safety labels off of everything and let the problem solve itself?
    > Frank Zappa
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Ben O'Steen, Oct 31, 2005
    #7
  8. Ben O'Steen wrote:
    > On Mon, October 31, 2005 10:23, Sybren Stuvel said:
    >> Ben O'Steen enlightened us with:
    >>> Using decimal as opposed to float sorts out this error as floats are
    >>> not built to handle the size of number used here.

    >> They can handle the size just fine. What they can't handle is 1/1000th
    >> precision when using numbers in the order of 1e10.
    >>

    >
    > I used the word 'size' here incorrectly, I intended to mean 'length'
    > rather than numerical value. Sorry for the confusion :)
    >


    Sybren is right. The problem is not the length or the size, it's
    the fact that 0.039 cannot be represented exactly in binary, in
    just the same way that 1/3 cannot be represented exactly in
    decimal. They both give recurring numbers. If you truncate those
    recurring numbers to a finite number of digits, you lose
    precision. And this shows up when you convert the inaccurate
    number from binary into decimal representation where an exact
    representation IS possible.

    Steve
    Steve Horsley, Oct 31, 2005
    #8
  9. Johnny Lee

    Dan Bishop Guest

    Steve Horsley wrote:
    > Ben O'Steen wrote:
    > > On Mon, October 31, 2005 10:23, Sybren Stuvel said:
    > >> Ben O'Steen enlightened us with:
    > >>> Using decimal as opposed to float sorts out this error as floats are
    > >>> not built to handle the size of number used here.
    > >> They can handle the size just fine. What they can't handle is 1/1000th
    > >> precision when using numbers in the order of 1e10.

    > >
    > > I used the word 'size' here incorrectly, I intended to mean 'length'
    > > rather than numerical value. Sorry for the confusion :)

    >
    > Sybren is right. The problem is not the length or the size, it's
    > the fact that 0.039 cannot be represented exactly in binary, in
    > just the same way that 1/3 cannot be represented exactly in
    > decimal. They both give recurring numbers. If you truncate those
    > recurring numbers to a finite number of digits, you lose
    > precision. And this shows up when you convert the inaccurate
    > number from binary into decimal representation where an exact
    > representation IS possible.


    That's A source of error, but it's only part of the story. The
    double-precision binary representation of 0.039 is 5620492334958379 *
    2**(-57), which is in error by 1/18014398509481984000. By contrast,
    Johnny Lee's answer is in error by 9/262144000, which is more than 618
    billion times the error of simply representing 0.039 in floating point
    -- a loss of 39 bits.

    The problem here is catastrophic cancellation.

    1130748744.500 ~= 4742703982051328 * 2**(-22)
    1130748744.461 ~= 4742703981887750 * 2**(-22)

    Subtracting gives 163578 * 2**(-22), which has only 18 significant bits.
    Dan Bishop, Nov 1, 2005
    #9
  10. Dan Bishop wrote:

    > That's A source of error, but it's only part of the story. The
    > double-precision binary representation of 0.039 is 5620492334958379 *
    > 2**(-57), which is in error by 1/18014398509481984000. By contrast,
    > Johnny Lee's answer is in error by 9/262144000, which is more than 618
    > billion times the error of simply representing 0.039 in floating point
    > -- a loss of 39 bits.
    >
    > The problem here is catastrophic cancellation.
    >
    > 1130748744.500 ~= 4742703982051328 * 2**(-22)
    > 1130748744.461 ~= 4742703981887750 * 2**(-22)
    >
    > Subtracting gives 163578 * 2**(-22), which has only 18 significant bits.
    >


    Hmm. Good point.
    Steve Horsley, Nov 1, 2005
    #10
    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:
    4
    Views:
    11,887
    Thomas Hawtin
    Nov 17, 2005
  2. Asfand Yar Qazi
    Replies:
    3
    Views:
    557
  3. Christian Tismer
    Replies:
    0
    Views:
    252
    Christian Tismer
    Apr 2, 2004
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,655
    Smokey Grindel
    Dec 2, 2006
  5. Frederick Gotham

    Out-of-bounds nonsense

    Frederick Gotham, Nov 1, 2006, in forum: C Programming
    Replies:
    63
    Views:
    1,210
    Frederick Gotham
    Nov 3, 2006
Loading...

Share This Page