results of division

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

    #1

    results of division

    Hello,

    What is the proper way to limit the results of division to only a few
    spaces after the decimal? I don't need rocket-science like precision.
    Here's an example:

    1.775 is as exact as I need to be and normally, 1.70 will do.

    Thank you,
    Brad
  • Simon Brunning

    #2
    Re: results of division

    On Thu, 09 Dec 2004 09:38:55 -0500, Brad Tilley <bradtilley@gma il.com> wrote:[color=blue]
    > What is the proper way to limit the results of division to only a few
    > spaces after the decimal? I don't need rocket-science like precision.
    > Here's an example:
    >
    > 1.775 is as exact as I need to be and normally, 1.70 will do.[/color]

    Use the new decimal type - <http://www.python.org/doc/2.4/whatsnew/node9.html>.

    --
    Cheers,
    Simon B,
    simon@brunningo nline.net,

    Comment

    • Paul Rubin

      #3
      Re: results of division

      Brad Tilley <bradtilley@gma il.com> writes:[color=blue]
      > What is the proper way to limit the results of division to only a few
      > spaces after the decimal? I don't need rocket-science like
      > precision. Here's an example:
      >
      > 1.775 is as exact as I need to be and normally, 1.70 will do.[/color]

      "%.2f"% 1.775

      Comment

      • Aahz

        #4
        Re: results of division

        In article <cp9o1v$ibq$1@s olaris.cc.vt.ed u>,
        Brad Tilley <bradtilley@gma il.com> wrote:[color=blue]
        >
        >What is the proper way to limit the results of division to only a few
        >spaces after the decimal? I don't need rocket-science like precision.
        >Here's an example:
        >
        >1.775 is as exact as I need to be and normally, 1.70 will do.[/color]

        You have two options: use floating point and round manually or use the
        new Decimal class and specify your precision. However, if you restrict
        your calculations, you will have errors after chaining more than one or
        two operations. Your best bet is to perform rounding only at the end of
        your calculations, at which point you can either round the result
        directly or round for display only (by using appropriate % formatting).
        --
        Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

        "19. A language that doesn't affect the way you think about programming,
        is not worth knowing." --Alan Perlis

        Comment

        • Peter Hansen

          #5
          Re: results of division

          Brad Tilley wrote:[color=blue]
          > What is the proper way to limit the results of division to only a few
          > spaces after the decimal? I don't need rocket-science like precision.
          > Here's an example:
          >
          > 1.775 is as exact as I need to be and normally, 1.70 will do.[/color]

          The answer is "what are you trying to do?". The others have
          given options and good advice, but the "right" approach
          depends on what exactly you are doing. Is this just for
          display purposes, or is there more significant (though
          perhaps not "precision-critical") calculation going on?

          -Peter

          Comment

          • Paul McGuire

            #6
            Re: results of division

            "Paul Rubin" <http://phr.cx@NOSPAM.i nvalid> wrote in message
            news:7xacsnjzj5 .fsf@ruckus.bro uhaha.com...[color=blue]
            > Brad Tilley <bradtilley@gma il.com> writes:[color=green]
            > > What is the proper way to limit the results of division to only a few
            > > spaces after the decimal? I don't need rocket-science like
            > > precision. Here's an example:
            > >
            > > 1.775 is as exact as I need to be and normally, 1.70 will do.[/color]
            >
            > "%.2f"% 1.775[/color]

            At the risk of kicking off *another* floating-point representation thread,
            here is some odd string interp behavior (Python 2.3.4).

            I seemed to recall in the past finding that the above syntax would not
            round, but would instead truncate (old C runtime perhaps), so that even
            printing 1.779 to 2 decimal places would print only "1.77". So I tried a
            few things at the Python prompt, and got some odd behavior.
            [color=blue][color=green][color=darkred]
            >>> print "%.2f" % 1.776[/color][/color][/color]
            1.78[color=blue][color=green][color=darkred]
            >>> print "%.2f" % 1.774[/color][/color][/color]
            1.77

            Good so far, now let's try the borderline case:
            [color=blue][color=green][color=darkred]
            >>> print "%.2f" % 1.775[/color][/color][/color]
            1.77

            Hmmm, if we rounded, I would have expected 1.775 to round up to 1.78.
            Perhaps this is a floating point rep issue, that we are really rounding
            1.7749999999999 999999 or something. Sure enough, repr shows us:
            [color=blue][color=green][color=darkred]
            >>> repr(1.775)[/color][/color][/color]
            '1.774999999999 9999'

            So I added a wee bit to 1.775:
            [color=blue][color=green][color=darkred]
            >>> print "%.2f" % 1.775000000001[/color][/color][/color]
            1.78

            Ok, that looks better. What if I round explicitly?
            [color=blue][color=green][color=darkred]
            >>> print "%.2f" % round(1.775,2)[/color][/color][/color]
            1.78

            Errr? How come round() is able to understand 1.775 correctly, whereas
            string interp is not? I'm guessing that round() adds some small epsilon to
            the value to be rounded, or perhaps even does the brute force rounding I
            learned in FORTRAN back in the 70's: add 0.5 and truncate. But this would
            still truncate 1.779999999 to two places, so this theory fails also. What
            magic is round() doing, and should this same be done in the string interp
            code?

            -- Paul



            Comment

            • Brad Tilley

              #7
              Re: results of division

              Simon Brunning wrote:[color=blue]
              > On Thu, 09 Dec 2004 09:38:55 -0500, Brad Tilley <bradtilley@gma il.com> wrote:
              >[color=green]
              >>What is the proper way to limit the results of division to only a few
              >>spaces after the decimal? I don't need rocket-science like precision.
              >>Here's an example:
              >>
              >>1.775 is as exact as I need to be and normally, 1.70 will do.[/color]
              >
              >
              > Use the new decimal type - <http://www.python.org/doc/2.4/whatsnew/node9.html>.[/color]

              Ah, quantize() works great. Thank you for the tip.

              Comment

              • Brad Tilley

                #8
                Re: results of division

                Peter Hansen wrote:[color=blue]
                > Brad Tilley wrote:
                >[color=green]
                >> What is the proper way to limit the results of division to only a few
                >> spaces after the decimal? I don't need rocket-science like precision.
                >> Here's an example:
                >>
                >> 1.775 is as exact as I need to be and normally, 1.70 will do.[/color]
                >
                >
                > The answer is "what are you trying to do?". The others have
                > given options and good advice, but the "right" approach
                > depends on what exactly you are doing. Is this just for
                > display purposes, or is there more significant (though
                > perhaps not "precision-critical") calculation going on?
                >
                > -Peter[/color]

                I'm summing up the bytes in use on a hard disk drive and generating a
                report that's emailed based on the percentage of the drive in use. I
                know there are other ways to do this, but I like Python and I like to
                write my own code. I always find comp.lang.pytho n a very helpful place.

                Thank you,

                Brad

                Comment

                • Tim Peters

                  #9
                  Re: results of division

                  [Paul McGuire]
                  ....[color=blue][color=green][color=darkred]
                  > >>> print "%.2f" % 1.775[/color][/color]
                  > 1.77
                  >
                  > Hmmm, if we rounded, I would have expected 1.775 to round up
                  > to 1.78.[/color]

                  Platform-dependent. 1.775 isn't exactly representable regardless, but
                  whether exactly-half-way numbers that are exactly representable round
                  up or truncate varies across platform C libraries. For example, 1.25
                  is exactly representable in binary fp, but '%.1f' % 1.25 produces 1.3
                  on Windows but 1.2 on most other platforms (most non-Microsoft C
                  runtimes use the IEEE "round to nearest or even" rule).
                  [color=blue]
                  > Perhaps this is a floating point rep issue, that we are really
                  > rounding 1.7749999999999 999999 or something. Sure enough,
                  > repr shows us:
                  >[color=green][color=darkred]
                  > >>> repr(1.775)[/color][/color]
                  > '1.774999999999 9999'
                  >
                  > So I added a wee bit to 1.775:
                  >[color=green][color=darkred]
                  > >>> print "%.2f" % 1.775000000001[/color][/color]
                  > 1.78
                  >
                  > Ok, that looks better. What if I round explicitly?
                  >[color=green][color=darkred]
                  > >>> print "%.2f" % round(1.775,2)[/color][/color]
                  > 1.78
                  >
                  > Errr? How come round() is able to understand 1.775 correctly,
                  > whereas string interp is not? I'm guessing that round() adds
                  > some small epsilon to the value to be rounded,[/color]

                  No way -- that would be insane.
                  [color=blue]
                  > or perhaps even does the brute force rounding I learned in
                  > FORTRAN back in the 70's: add 0.5 and truncate.[/color]

                  Yes, that's what Python's round() does.
                  [color=blue]
                  > But this would still truncate 1.779999999 to two places, so this
                  > theory fails also.[/color]

                  No:
                  [color=blue][color=green][color=darkred]
                  >>> 1.775[/color][/color][/color]
                  1.7749999999999 999[color=blue][color=green][color=darkred]
                  >>> 1.775 * 100.0[/color][/color][/color]
                  177.5[color=blue][color=green][color=darkred]
                  >>> 1.775*100 + 0.5[/color][/color][/color]
                  178.0[color=blue][color=green][color=darkred]
                  >>>[/color][/color][/color]

                  That is, before adding 0.5, it multiplies by 100.0. The vagaries of
                  binary fp are such that machine_value_f or(1.755) * 100 is exactly
                  175.5, and adding 0.5 to that gives 178 exactly.
                  [color=blue]
                  > What magic is round() doing, and should this same be done in the
                  > string interp code?[/color]

                  Python implements round() itself. Float string formatting is done by
                  the platform C sprintf(). If you care about decimal representations
                  so much that you can't tolerate vagaries due to differences in the
                  53rd significant bit, use the new decimal module instead.

                  Comment

                  • Peter Hansen

                    #10
                    Re: results of division

                    Brad Tilley wrote:[color=blue]
                    > Peter Hansen wrote:[color=green]
                    >> The answer is "what are you trying to do?". The others have
                    >> given options and good advice, but the "right" approach
                    >> depends on what exactly you are doing. Is this just for
                    >> display purposes, or is there more significant (though
                    >> perhaps not "precision-critical") calculation going on?[/color]
                    >
                    > I'm summing up the bytes in use on a hard disk drive and generating a
                    > report that's emailed based on the percentage of the drive in use. I
                    > know there are other ways to do this, but I like Python and I like to
                    > write my own code. I always find comp.lang.pytho n a very helpful place.[/color]

                    So, from the sounds of it, you really care about this
                    rounding operation in the displayed values, in which
                    case the "'%.2f' % value" approach ought to be fine.

                    -Peter

                    Comment

                    • Christopher A. Craig

                      #11
                      Re: results of division

                      "Paul McGuire" <ptmcg@austin.r r._bogus_.com> writes:
                      [color=blue]
                      > Errr? How come round() is able to understand 1.775 correctly, whereas
                      > string interp is not? I'm guessing that round() adds some small epsilon to
                      > the value to be rounded, or perhaps even does the brute force rounding I
                      > learned in FORTRAN back in the 70's: add 0.5 and truncate. But this would
                      > still truncate 1.779999999 to two places, so this theory fails also. What
                      > magic is round() doing, and should this same be done in the string interp
                      > code?[/color]

                      Consulting bltinmodule.c would tell you. round(x,n) in (Python 2.4):

                      multiplies x by 10**n
                      adds .5
                      truncates
                      divides by 10**n.

                      Don't confuse this trick with giving us the correct result though,
                      it's still floating point:
                      [color=blue][color=green][color=darkred]
                      >>> round(1.7749999 9999999999, 2)[/color][/color][/color]
                      1.78

                      --
                      Christopher A. Craig <com-nospam@ccraig.o rg>
                      "[Windows NT is] not about 'Where do you want to go today?'; it's more like
                      'Where am I allowed to go today?'" -- Mike Mitchell, NT Systems Administrator

                      Comment

                      • Donn Cave

                        #12
                        Re: results of division

                        In article <cp9ska$s1o$1@s olaris.cc.vt.ed u>,
                        Brad Tilley <bradtilley@gma il.com> wrote:[color=blue][color=green]
                        > > Brad Tilley wrote:
                        > >[color=darkred]
                        > >> What is the proper way to limit the results of division to only a few
                        > >> spaces after the decimal? I don't need rocket-science like precision.
                        > >> Here's an example:
                        > >>
                        > >> 1.775 is as exact as I need to be and normally, 1.70 will do[/color][/color][/color]
                        ....[color=blue]
                        > I'm summing up the bytes in use on a hard disk drive and generating a
                        > report that's emailed based on the percentage of the drive in use.[/color]

                        Stilling guessing a little about what you're trying to do -
                        probably implicitly or explicitly invoking the "repr" function
                        on this values (implicitly for example via repr() or str() on
                        a sequence of them.) So,

                        a = [1.775, 1.949]
                        print a
                        yields
                        [1.7749999999999 999, 1.9490000000000 001]

                        You will get something more like what you want with
                        the str() function instead. str(1.775) == '1.775'



                        from types import FloatType
                        class ClassicFloat(Fl oatType):
                        def __repr__(self):
                        return self.__str__()

                        print map(ClassicFloa t, [1.775, 1.949])

                        yields
                        [1.775, 1.949]


                        (Seems to me the standard float type behaved like
                        this in Python 1.5.4, hence "classic".)

                        Donn Cave, donn@u.washingt on.edu

                        Comment

                        • Dan Bishop

                          #13
                          Re: results of division

                          Brad Tilley wrote:[color=blue]
                          > Hello,
                          >
                          > What is the proper way to limit the results of division to only a few[/color]
                          [color=blue]
                          > spaces after the decimal? I don't need rocket-science like precision.[/color]
                          [color=blue]
                          > Here's an example:[/color]

                          If your only complaint is that it's ugly to display 17 digits, then use
                          the % operator to display however many digits you want.

                          print "%.3f" % x # prints 3 digits after the decimal point

                          If you're referring to internal calculations, then you seem to have a
                          misunderstandin g of the way floating-point math works. Intel hardware
                          does all arithmetic with 64 significant bits (which get rounded to 53
                          when stored as "double precision"), and there's no way to tell it
                          "Don't bother calculating all 64 bits; I only need 11." It would take
                          extra code to get rid of the extra bits, and why bother slowing down
                          your program to make the math *less* accurate?

                          Comment

                          • Aahz

                            #14
                            Re: results of division

                            In article <cpa0dq$i10$1@u tornnr1pp.group telecom.net>,
                            Peter Hansen <peter@engcorp. com> wrote:[color=blue]
                            >Brad Tilley wrote:[color=green]
                            >> Peter Hansen wrote:[color=darkred]
                            >>> The answer is "what are you trying to do?". The others have
                            >>> given options and good advice, but the "right" approach
                            >>> depends on what exactly you are doing. Is this just for
                            >>> display purposes, or is there more significant (though
                            >>> perhaps not "precision-critical") calculation going on?[/color]
                            >>
                            >> I'm summing up the bytes in use on a hard disk drive and generating a
                            >> report that's emailed based on the percentage of the drive in use. I
                            >> know there are other ways to do this, but I like Python and I like to
                            >> write my own code. I always find comp.lang.pytho n a very helpful place.[/color]
                            >
                            >So, from the sounds of it, you really care about this[/color]
                            ^don't[color=blue]
                            >rounding operation in the displayed values, in which
                            >case the "'%.2f' % value" approach ought to be fine.[/color]

                            Right?
                            --
                            Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

                            "19. A language that doesn't affect the way you think about programming,
                            is not worth knowing." --Alan Perlis

                            Comment

                            • Peter Hansen

                              #15
                              Re: results of division

                              Aahz wrote:[color=blue]
                              > In article <cpa0dq$i10$1@u tornnr1pp.group telecom.net>,
                              > Peter Hansen <peter@engcorp. com> wrote:[color=green]
                              >>So, from the sounds of it, you really care about this[/color]
                              >
                              > ^don't
                              >[color=green]
                              >>rounding operation in the displayed values, in which
                              >>case the "'%.2f' % value" approach ought to be fine.[/color]
                              >
                              > Right?[/color]

                              I think what I meant to say was "you really care about
                              this *only* in the displayed values", but with that
                              "don't" in there it comes out the same in the wash. :-)

                              -Peter

                              Comment

                              Working...