Rounding double

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dik T. Winter

    Re: Rounding double

    In article <NQB2j.14278$Mg 1.2787@trndny03 James Kuyper <jameskuyper@ve rizon.netwrites :
    Richard Heathfield wrote:
    ....
    No, I'm only asserting that the original problem, as stated, is impossible
    to solve.
    >
    The original problem as stated was, IMO, probably not intended to be
    read with the unconventionall y strict interpretation you're using. I
    believe that Jacob is correctly describing the problem as clearly
    expressed by the OP.
    I do not think so. I have seen too many articles posted in this newsgroup
    asking why (when 0.33333333 is rounded to two decimals), the result is
    printed as 0.3299999999, and not as 0.33000000 (or something similar) ...
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

    Comment

    • Keith Thompson

      Re: Rounding double

      jacob navia wrote:
      Richard Heathfield wrote:
      >jacob navia said:
      [...]
      >>Of course I agree with your short description of these people.
      >>And one of their "word games" was precisely to say that it is
      >>impossible to write:
      >>>
      >>double rounto(double x, unsigned places);
      >>
      >No, of course you can *write* it (duh). It just won't do what you
      >claim it does, that's all.
      >
      I claim that this will deliver the best approximation to the
      rounding to n decimal places, and I have never claimed otherwise.
      >
      If you do not agree, produce a better function.
      [code snipped]

      Provide a better function to do what?

      jacob, you persist in missing the point, even as you implicitly
      acknowledge it.

      The OP did *not* ask for a function to provide *the best approximation
      of* a double value rounded to n decimal places. The OP asked for a
      function to provide *a double rounded to n decimal places*. You have
      simply assumed that, since what he literally asked for is impossible, he
      must really be asking for something that's similar but possible.

      How do you know what the OP really wants?

      When someone asks a question with incompletely specified requirements,
      as has happened here, we can ask for clarification (as we've done, but
      the OP has so far failed to offer it), or we can make reasonable
      assumptions. You've assumed that a close approximation is good enough.
      You *might* be correct, but your solution, though it may meet the OP's
      requirements when coupled with your assumption, is IMHO not particularly
      useful. (Think about it for a moment. Given a function such that
      roundto(3.14159 , 2) yields *approximately* 3.14, most likely something
      like 3.1400000000000 001243449787580 175325274467468 26171875, would *you*
      have any real use for such a thing? You might provide it in your
      library, but would you really use it in your own code?)

      What I and most others here have assumed instead is that what the OP
      really wants is something *useful*. Given this assumption (which I
      acknowledge is just an assumption), the OP needs to step back a bit and
      re-think the problem. He probably really wants a *textual*
      representation of "3.14", which is exact, rather than a floating-point
      representation that can only be approximate, and whose only likely
      purpose is to produce the exact textual representation anyway. The
      point I suspect he's missing is that the original floating-point value
      (an approximation of 3.14159) is just as useful as an approximation of
      3.14 for the purpose of producing the string or output "3.14".

      If you choose to make an assumption about what the OP really wants,
      that's fine. You might even be correct. What I find annoying is your
      stubborn insistence that no other assumption is possible.

      There's another possibility that I don't recall anyone mentioning.
      Perhaps this is a homework assignment, and perhaps it's the instructor
      who fails to realize that decimal rounding of binary floating-point
      values is not useful.

      --
      Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
      Looking for software development work in the San Diego area.
      "We must do something. This is something. Therefore, we must do this."
      -- Antony Jay and Jonathan Lynn, "Yes Minister"

      Comment

      • Gordon Burditt

        Re: Rounding double

        >jacob, you persist in missing the point, even as you implicitly
        >acknowledge it.
        >
        >The OP did *not* ask for a function to provide *the best approximation
        >of* a double value rounded to n decimal places. The OP asked for a
        >function to provide *a double rounded to n decimal places*. You have
        >simply assumed that, since what he literally asked for is impossible, he
        >must really be asking for something that's similar but possible.
        It is possible to provide a rounded double that will have N decimal
        places and be rounded exactly (when represented in binary floating
        point). Round to the nearest multiple of 2**-N . (** is an
        exponentiation operator, which C doesn't have and mathematics uses
        superscript for, which is a bit difficult in ASCII text.) When
        converted to decimal, it will have N decimal places. It will also
        be representable exactly provided you've got enough mantissa bits.
        However, I seriously doubt that anyone would actually ask for this,
        except as a puzzle or to win a bet.

        >There's another possibility that I don't recall anyone mentioning.
        >Perhaps this is a homework assignment, and perhaps it's the instructor
        >who fails to realize that decimal rounding of binary floating-point
        >values is not useful.
        Unfortunately, I think fixing this problem would exhaust the world
        supply of clue-bats.

        Comment

        • Bart

          Re: Rounding double

          On Nov 27, 1:11 am, Keith Thompson <ks...@mib.orgw rote:
          >...is IMHO not particularly
          useful. (Think about it for a moment. Given a function such that
          roundto(3.14159 , 2) yields *approximately* 3.14, most likely something
          like 3.1400000000000 001243449787580 175325274467468 26171875, would *you*
          have any real use for such a thing? You might provide it in your
          library, but would you really use it in your own code?)
          Definitely. The error is not significant, I can live with it.

          There are many reasons why this kind of rounding is useful in the real
          world, often to deal with noise reduction. There seems to be a
          remarkable lack of imagination from many contributors here who think
          rounding is only useful in printing numbers.

          Having a round(x) that was magically exact wouldn't change anything
          because nobody would know what to do with it!

          But round(x) isn't exact, although neither is, say, reciprocal(x), so
          that would be banned too.
          who fails to realize that decimal rounding of binary floating-point
          values is not useful.
          By rounding, I can compare my noisy data with yours; if the difference
          is less than some tolerance, it can be considered the same!

          And it can look cleaner when printed without having to depend on
          highly specific printf formats. If I know my data doesn't contain more
          than 3 decimals of info, but might be printed with 6 decimals,
          rounding will clean it up. Maybe I don't even know who will print it
          and in what format.

          Bart

          Comment

          • Richard Heathfield

            Re: Rounding double

            Bart said:
            On Nov 27, 1:11 am, Keith Thompson <ks...@mib.orgw rote:
            >
            >>...is IMHO not particularly
            >useful. (Think about it for a moment. Given a function such that
            >roundto(3.1415 9, 2) yields *approximately* 3.14, most likely something
            >like 3.1400000000000 001243449787580 175325274467468 26171875, would *you*
            >have any real use for such a thing? You might provide it in your
            >library, but would you really use it in your own code?)
            >
            Definitely. The error is not significant, I can live with it.
            >
            There are many reasons why this kind of rounding is useful in the real
            world, often to deal with noise reduction.
            We don't call that "rounding", though. We call it "approximating" . Nobody
            denies its utility. But rounding it ain't.

            <snip>

            --
            Richard Heathfield <http://www.cpax.org.uk >
            Email: -http://www. +rjh@
            Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
            "Usenet is a strange place" - dmr 29 July 1999

            Comment

            • Keith Thompson

              Re: Rounding double

              James Kuyper <jameskuyper@ve rizon.netwrites :
              Bart wrote:
              ...
              >Not many posting here seem to believe there are real and practical
              >reasons for rounding values to so many decimals (or rounding to a
              >nearest fraction, a related problem).
              >
              Incorrect. What I believe is that the real and practical reasons tend
              to fall into two categories:
              >
              a) Conversion of floating point numbers to digit strings, usually for
              output.
              >
              b) Calculations that should, properly, be carried out in fixed-point
              arithmetic. In the absence of direct language support for fixed-point,
              it should be emulated by the programmer using, for instance, an
              integer to represent 1000 times the actual value, if that value is to
              be stored with 3 digits after the decimal place. All of the example
              you gave should fall into this second category.
              [...]

              Yes, there are good reasons for wanting to round a numeric value to a
              specified number of decimal places, but neither example you provided
              (nor any other reasonable example I can think of) calls for storing
              the resulting rounded value in a double.

              --
              Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
              Looking for software development work in the San Diego area.
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              • Bart

                Re: Rounding double

                On Nov 27, 7:11 am, Richard Heathfield <r...@see.sig.i nvalidwrote:

                There are many reasons why this kind of rounding is useful in the real
                world, often to deal with noise reduction.
                >
                We don't call that "rounding", though. We call it "approximating" . Nobody
                denies its utility.
                I think Keith Thompson and one or two others were.
                >But rounding it ain't.
                I'm intrigued, why are you so prejudiced about poor old round(x)
                function for reasons that could be applied to nearly anything, like
                (slightly contrived) a reciprocal(x) function for example? In fact in
                seems Divide is the real culprit because often you don't get exactly
                what it says on the box.

                Bart

                Comment

                • Richard Heathfield

                  Re: Rounding double

                  Bart said:
                  On Nov 27, 7:11 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
                  >
                  >
                  There are many reasons why this kind of rounding is useful in the real
                  world, often to deal with noise reduction.
                  >>
                  >We don't call that "rounding", though. We call it "approximating" .
                  >Nobody denies its utility.
                  >
                  I think Keith Thompson and one or two others were.
                  >
                  >>But rounding it ain't.
                  >
                  I'm intrigued, why are you so prejudiced about poor old round(x)
                  function for reasons that could be applied to nearly anything, like
                  (slightly contrived) a reciprocal(x) function for example?
                  I'm not sure that "prejudiced " is the right word. I don't /use/ it, but
                  that's only for the same reason that I don't use any C99 features in code
                  intended to be portable. But round() doesn't actually round to a given
                  number of decimal places (or rather, it does, provided that the number of
                  decimal places you want is zero!).

                  If you try to use it to round 0.33 to one decimal place, e.g. like this:

                  f = round(f * 10) / 10;

                  then you'll get 0.3000000000000 0000001 or 0.2999999999999 9998 or something
                  like that. What you won't get is *precisely* 0.3 in f.

                  In fact in
                  seems Divide is the real culprit because often you don't get exactly
                  what it says on the box.
                  Whatever the culprit, the crime remains - you can't (in the general case)
                  store an arbitrary value in a double to precisely n decimal places, for
                  any value of n 0. (You *can* store particular values, of course: 0.5,
                  0.75, and so on.)

                  --
                  Richard Heathfield <http://www.cpax.org.uk >
                  Email: -http://www. +rjh@
                  Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                  "Usenet is a strange place" - dmr 29 July 1999

                  Comment

                  • James Kuyper

                    Re: Rounding double

                    Richard Heathfield wrote:
                    Bart said:
                    ....
                    >I'm intrigued, why are you so prejudiced about poor old round(x)
                    >function for reasons that could be applied to nearly anything, like
                    >(slightly contrived) a reciprocal(x) function for example?
                    >
                    I'm not sure that "prejudiced " is the right word. I don't /use/ it, but
                    that's only for the same reason that I don't use any C99 features in code
                    intended to be portable. But round() doesn't actually round to a given
                    number of decimal places (or rather, it does, provided that the number of
                    decimal places you want is zero!).
                    I suspect that he was not talking about the C99 round(); it sounded more
                    like he was unaware of it's existence. round() can calculate it's result
                    exactly, at least for it's typical argument values.

                    I think he using "round()" as a name for the kind of function we've been
                    talking about in this thread. It takes a double value, and an integer
                    number of digits, and returns the best possible approximation to the
                    provided value rounded to the specified number of digits after the
                    decimal place. For most typical argument values this function cannot
                    return exactly the mathematical value we would like it to return. In
                    that regard, it is no different from most other operations on floating
                    point values, or most other functions taking floating point arguments.
                    If you try to use it to round 0.33 to one decimal place, e.g. like this:
                    >
                    f = round(f * 10) / 10;
                    >
                    then you'll get 0.3000000000000 0000001 or 0.2999999999999 9998 or something
                    like that. What you won't get is *precisely* 0.3 in f.
                    For the same reason, reciprocal(5.0) can't give you precisely 0.2. So?
                    Why is one inaccuracy acceptable, and the other is not? Or are you
                    suggesting that they're both unacceptable?

                    Comment

                    • Richard Heathfield

                      Re: Rounding double

                      James Kuyper said:
                      Richard Heathfield wrote:
                      <snip>
                      >If you try to use it to round 0.33 to one decimal place, e.g. like this:
                      >>
                      >f = round(f * 10) / 10;
                      >>
                      >then you'll get 0.3000000000000 0000001 or 0.2999999999999 9998 or
                      >something like that. What you won't get is *precisely* 0.3 in f.
                      >
                      For the same reason, reciprocal(5.0) can't give you precisely 0.2. So?
                      Why is one inaccuracy acceptable, and the other is not? Or are you
                      suggesting that they're both unacceptable?
                      This was well answered elseperson elsethread. Let me see if I can find it.

                      Ah, here we go: Message-ID: <fi7g66$pqr$1@a ioe.org>

                      in which Keith writes:

                      "But there's a fundamental difference between sqrt() and a function
                      that purports to round a floating-point value to a specified number
                      of decimal places.

                      "For the sqrt() function, obtaining a close approximation to the
                      mathematical result is obviously a useful thing to do. There are
                      some contexts in which you might want to throw up your hands and
                      say "Sorry, it's not possible to compute sqrt(2.0) exactly" -- but
                      obtaining a close approximation is both useful and expected.

                      "For the rounding function, sure, you could write a function that,
                      given arguments (3.14159, 2) would return the closest floating-point
                      approximation of the mathematical value 3.14. But it's not at all
                      clear either that this would be useful, or that it's really what the
                      original poster wants."

                      --
                      Richard Heathfield <http://www.cpax.org.uk >
                      Email: -http://www. +rjh@
                      Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                      "Usenet is a strange place" - dmr 29 July 1999

                      Comment

                      • Bart

                        Re: Rounding double

                        On Nov 27, 2:33 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
                        James Kuyper said:
                        For the same reason, reciprocal(5.0) can't give you precisely 0.2. So?
                        This was well answered elseperson elsethread. Let me see if I can find it.
                        in which Keith writes:
                        >
                        "But there's a fundamental difference between sqrt() and a function
                        that purports to round a floating-point value to a specified number
                        of decimal places.
                        So, the thing about rounddouble(x,n ) is that it always gives an exact
                        result in decimal arithmetic, compared with reciprocal(x) (sometimes
                        exact) or sqrt(x) (rarely exact)?

                        Due to dividing by 10^n which is no problem in decimal but causes
                        grief in binary?

                        OK. But back in the practical world, it can still be useful to class a
                        rounddouble(x) function with sqrt, reciprocal and the like provided
                        the limitations are known.

                        Bart.

                        Comment

                        • Richard Heathfield

                          Re: Rounding double

                          Bart said:

                          <snip>
                          OK. But back in the practical world,
                          I rarely leave it, which is why I think it's so important to get things
                          right.
                          it can still be useful to class a
                          rounddouble(x) function with sqrt, reciprocal and the like provided
                          the limitations are known.
                          Of course it can be useful, and nobody denies this - provided, as you say,
                          the limitations are known. That is why I have laid such stress on pointing
                          out the limitations (which, it seemed to me, the phrasing of the OP's
                          question suggested that he didn't know).

                          --
                          Richard Heathfield <http://www.cpax.org.uk >
                          Email: -http://www. +rjh@
                          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                          "Usenet is a strange place" - dmr 29 July 1999

                          Comment

                          Working...