simple float numbers problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vio

    simple float numbers problem

    I need to test for equality between simple 2 decimal numbers. For example:

    if (10 + 15.99) == 25.99:
    do some stuff...

    The preceding sentence should be TRUE, but to Python it appears FALSE.
    Which is wrong.

    Perhaps because Python translates "25.99" to "25.98999999999 999998" and
    not "25.99", which may be the reason for this error (me guessing...). If
    that's the case, how do I force Python to only use 2 decimal points, and
    not "make up" superfluous decimals? Or if that's not the cause for the
    problem, how do I make Python see my math expression as TRUE (as it
    "should" be)?

    Cheers,
    Vio

    PS. If it's of any help, I'm using Python2.3 (GCC 2.95.4 20011002
    (Debian prerelease))



  • Dennis Lee Bieber

    #2
    Re: simple float numbers problem

    Vio fed this fish to the penguins on Friday 07 November 2003 05:34 am:
    [color=blue]
    >
    > Perhaps because Python translates "25.99" to "25.98999999999 999998"
    > and not "25.99", which may be the reason for this error (me
    > guessing...). If that's the case, how do I force Python to only use 2
    > decimal points, and not "make up" superfluous decimals? Or if that's
    > not the cause for the problem, how do I make Python see my math
    > expression as TRUE (as it "should" be)?
    >[/color]
    You don't... Computer floating point arithmetic is not precise. {I
    seem to have misplaced my copy, but there is a book with a title
    something like "Real Math Made Real" that discusses this}

    The recommendation from my old computer classes is that you never test
    floats for equality -- you test the difference between floats against
    some acceptable error limit.

    epsilon = 0.0000001
    if abs( (10 + 15.99) - 25.99) < epsilon:
    # considered equal

    -=-=-=-=-=-=-
    Python 2.2 (#1, Nov 5 2002, 15:43:24)
    [GCC 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)] on linux-i386
    Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
    >>> epsilon = 0.0000001
    >>> a = 10 + 15.99
    >>> if abs(a - 25.99) < epsilon:[/color][/color][/color]
    .... print a, " is equal to ", 25.99
    ....
    25.99 is equal to 25.99[color=blue][color=green][color=darkred]
    >>> print a[/color][/color][/color]
    25.99[color=blue][color=green][color=darkred]
    >>> print 25.99[/color][/color][/color]
    25.99[color=blue][color=green][color=darkred]
    >>> 25.99[/color][/color][/color]
    25.989999999999 998[color=blue][color=green][color=darkred]
    >>> a[/color][/color][/color]
    25.990000000000 002[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]



    --[color=blue]
    > =============== =============== =============== =============== == <
    > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
    > wulfraed@dm.net | Bestiaria Support Staff <
    > =============== =============== =============== =============== == <
    > Bestiaria Home Page: http://www.beastie.dm.net/ <
    > Home Page: http://www.dm.net/~wulfraed/ <[/color]

    Comment

    • Tim Roberts

      #3
      Re: simple float numbers problem

      Vio <vmilitaru@symp atico.ca> wrote:[color=blue]
      >
      >I need to test for equality between simple 2 decimal numbers. For example:
      >
      >if (10 + 15.99) == 25.99:
      > do some stuff...
      >
      >The preceding sentence should be TRUE, but to Python it appears FALSE.
      >Which is wrong.[/color]

      And the same thing would happen if you wrote the same sentence in C. The
      problem is that 15.99 in binary is an infinitely repeating decimal. It
      cannot be represented exactly.
      [color=blue]
      >If that's the case, how do I force Python to only use 2 decimal points,
      >and not "make up" superfluous decimals?[/color]

      There are two good solutions. One, as others have suggested, is to store
      everything in units of cents. Your expression becomes:

      if 1000 + 1599 == 2599:
      do some stuff...

      All you need to do is translate when you do input and output. This is the
      approach Visual Basic takes with its Currency data type (although it
      actually multiples by 1000, not 100).

      Another solution is to use a "CloseTo" function to do the comparison:

      def CloseTo(x,y):
      return abs(x-y) < 0.005

      if (10.00 + 15.99, 25.99):
      do some thuff...
      [color=blue]
      >Or if that's not the cause for the problem, how do I make
      >Python see my math expression as TRUE (as it "should" be)?[/color]

      In a binary computer, your statement is false. Just that simple. You need
      to find a way to express your statement in a way that produces the results
      you want.
      --
      - Tim Roberts, timr@probo.com
      Providenza & Boekelheide, Inc.

      Comment

      • Ben Finney

        #4
        Re: simple float numbers problem

        On Sun, 09 Nov 2003 00:10:14 -0800, Tim Roberts wrote:[color=blue]
        > Another solution is to use a "CloseTo" function to do the comparison:
        >
        > def CloseTo(x,y):
        > return abs(x-y) < 0.005[/color]

        A modified CloseTo() that allows a varying epsilon:

        def CloseTo( x, y, epsilon=0.005 ):
        return ( abs( x - y ) < epsilon )

        --
        \ "During the Middle Ages, probably one of the biggest mistakes |
        `\ was not putting on your armor because you were 'just going down |
        _o__) to the corner.'" -- Jack Handey |
        Ben Finney <http://bignose.squidly .org/>

        Comment

        • Christopher A. Craig

          #5
          Re: simple float numbers problem

          "Ladvánszky Károly" <aa@bb.cc> writes:
          [color=blue]
          > Lisp does the right thing:
          > (= (+ 10 15.99) 25.99)
          > T
          >
          > Does Lisp not use the math processor?[/color]

          I don't know which Lisp you're speaking of here, but chances are very
          good that 15.99 is not a float in this particular lisp. I'd guess
          it's probably rational. You can do that with Python if you get a
          rational library such as the one I mentioned in my previous post to
          this thread. The problem is that rationals are notoriously slow. If
          you tried to implement

          a = 0
          for i in range(1,5000):
          a += 1./i

          in this lisp, and I'm right, it should take longer than Python (but
          will give the "right" answer instead of Python's approximate one)

          --
          Christopher A. Craig <list-python@ccraig.o rg>
          "The mistakes made by Congress wouldn't be so bad if the next Congress
          didn't keep trying to correct them." Cullen Hightower


          Comment

          • Ladvánszky Károly

            #6
            Re: simple float numbers problem

            I'm running CLISP.
            (type-of 25.99) gives SINGLE-FLOAT
            (type-of (+ 10 15.99)) gives SINGLE-FLOAT
            I'm going to post it on the List group to see what Lispers say about it.
            By the way, Smalltalk also gives the right answer.

            "Christophe r A. Craig" <list-python@ccraig.o rg> az alábbiakat írta a
            következo hírüzenetben: mailman.602.106 8475270.702.pyt hon-list@python.org...[color=blue]
            > "Ladvánszky Károly" <aa@bb.cc> writes:
            >[color=green]
            > > Lisp does the right thing:
            > > (= (+ 10 15.99) 25.99)
            > > T
            > >
            > > Does Lisp not use the math processor?[/color]
            >
            > I don't know which Lisp you're speaking of here, but chances are very
            > good that 15.99 is not a float in this particular lisp. I'd guess
            > it's probably rational. You can do that with Python if you get a
            > rational library such as the one I mentioned in my previous post to
            > this thread. The problem is that rationals are notoriously slow. If
            > you tried to implement
            >
            > a = 0
            > for i in range(1,5000):
            > a += 1./i
            >
            > in this lisp, and I'm right, it should take longer than Python (but
            > will give the "right" answer instead of Python's approximate one)
            >
            > --
            > Christopher A. Craig <list-python@ccraig.o rg>
            > "The mistakes made by Congress wouldn't be so bad if the next Congress
            > didn't keep trying to correct them." Cullen Hightower
            >
            >[/color]


            Comment

            Working...