Rounding a floating point number

Discussion in 'C Programming' started by jacob navia, Feb 25, 2008.

  1. jacob navia

    jacob navia Guest

    Hi

    "How can I round a number to x decimal places" ?

    This question keeps appearing. I would propose the following
    solution

    #include <float.h>
    #include <math.h>

    double roundto(double x, int digits)
    {
    int sgn=1;

    if (x == 0)
    return 0;
    if (digits > DBL_DIG)
    digits = DBL_DIG;
    else if (digits < 1)
    digits = 1;

    if(x < 0.0) {
    sgn = -sgn;
    x = -x;
    }
    double p = floorl(log10l(x));
    p--;
    p = digits-p;
    double pow10 = pow(10.0, p);
    return sgn*floor(x*pow10+0.5)/pow10;
    }

    long double roundtol(long double x, int digits)
    {
    int sgn=1;

    if (x == 0)
    return 0;
    if (digits > LDBL_DIG)
    digits = LDBL_DIG;
    else if (digits < 1)
    digits = 1;

    if(x < 0.0) {
    sgn = -sgn;
    x = -x;
    }
    long double p = floorl(log10l(x));
    p--;
    p = digits-p;
    long double pow10 = powl(10.0, p);
    return sgn*floorl(x*pow10+0.5)/pow10;
    }
    #include <stdio.h>
    int main(void)
    {
    double d = 1.7888889988996678;
    long double ld = 1.7888889988996678998877L;

    for (int i = 0; i<=DBL_DIG;i++) {
    printf("i=%d: %.15g\n",i,roundto(d,i));
    }
    printf("\n 1.7888889988996678\n");
    for (int i = 0; i<=LDBL_DIG;i++) {
    printf("i=%d: %.18Lg\n",i,roundtol(ld,i));
    }
    printf("\n 1.7888889988996678998877L\n");
    return 0;
    }

    --------------------------------------------------------------------
    I would propose it to add it to the FAQ.


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Feb 25, 2008
    #1
    1. Advertising

  2. jacob navia said:

    > Hi
    >
    > "How can I round a number to x decimal places" ?
    >
    > This question keeps appearing.


    <snip>

    > I would propose it to add it to the FAQ.


    Good idea. You could call it Question 14.6.

    --
    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
     
    Richard Heathfield, Feb 25, 2008
    #2
    1. Advertising

  3. jacob navia

    Bartc Guest

    "Richard Heathfield" <> wrote in message
    news:...
    > jacob navia said:
    >
    >> Hi
    >>
    >> "How can I round a number to x decimal places" ?
    >>
    >> This question keeps appearing.

    >
    > <snip>
    >
    >> I would propose it to add it to the FAQ.

    >
    > Good idea. You could call it Question 14.6.


    14.6 is already used by How to Round a Number [to an integer]

    --
    Bart
     
    Bartc, Feb 25, 2008
    #3
  4. jacob navia

    jacob navia Guest

    Richard Heathfield wrote:
    > jacob navia said:
    >
    >> Hi
    >>
    >> "How can I round a number to x decimal places" ?
    >>
    >> This question keeps appearing.

    >
    > <snip>
    >
    >> I would propose it to add it to the FAQ.

    >
    > Good idea. You could call it Question 14.6.
    >

    Your kill file is not working apparently
    :)

    That question addresses the rounding to nearest integer.
    This answers the question of rounding to a number of decimal places

    Not the same thing. But yes, we could add this to 14.6

    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Feb 25, 2008
    #4
  5. jacob navia

    MisterE Guest


    > 14.6 is already used by How to Round a Number [to an integer]


    Then what need is there for this question? Its already answered in the faq.
    Multiply, round then divide.
     
    MisterE, Feb 25, 2008
    #5
  6. Bartc said:

    >
    > "Richard Heathfield" <> wrote in message
    > news:...
    >> jacob navia said:
    >>
    >>> Hi
    >>>
    >>> "How can I round a number to x decimal places" ?
    >>>
    >>> This question keeps appearing.

    >>
    >> <snip>
    >>
    >>> I would propose it to add it to the FAQ.

    >>
    >> Good idea. You could call it Question 14.6.

    >
    > 14.6 is already used by How to Round a Number [to an integer]


    From the FAQ, Q14.6: "You can round to a certain precision by scaling:

    (int)(x / precision + 0.5) * precision"

    (int)(3.141 / 0.01 + 0.5) * 0.01 gives us:

    (int)(314.1 + 0.5) * 0.01 which is

    (int)314.6 * 0.01 which is

    314 * 0.01 which is

    3.14

    QED

    (Of course, the usual caveats about floating point apply here.)

    --
    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
     
    Richard Heathfield, Feb 25, 2008
    #6
  7. On Mon, 25 Feb 2008 12:19:35 +0100,
    jacob navia <> wrote:
    > Richard Heathfield wrote:
    >> jacob navia said:
    >>
    >>> Hi
    >>>
    >>> "How can I round a number to x decimal places" ?
    >>>
    >>> This question keeps appearing.

    >>
    >> <snip>
    >>
    >>> I would propose it to add it to the FAQ.

    >>
    >> Good idea. You could call it Question 14.6.
    >>

    > That question addresses the rounding to nearest integer.
    > This answers the question of rounding to a number of decimal places


    It also answers the question of how to round to a certain number of
    digits:

    \begin{quote}
    You can round to a certain precision by scaling:
    \end{quote}

    Martien
    --
    |
    Martien Verbruggen | prepBut nI vrbLike adjHungarian! qWhat's
    | artThe adjBig nProblem? -- Alec Flett
    |
     
    Martien Verbruggen, Feb 25, 2008
    #7
  8. jacob navia

    Bartc Guest

    "Richard Heathfield" <> wrote in message
    news:eek:...
    > Bartc said:
    >
    >>
    >> "Richard Heathfield" <> wrote in message
    >> news:...
    >>> jacob navia said:
    >>>
    >>>> Hi
    >>>>
    >>>> "How can I round a number to x decimal places" ?
    >>>>
    >>>> This question keeps appearing.
    >>>
    >>> <snip>
    >>>
    >>>> I would propose it to add it to the FAQ.
    >>>
    >>> Good idea. You could call it Question 14.6.

    >>
    >> 14.6 is already used by How to Round a Number [to an integer]

    >
    > From the FAQ, Q14.6: "You can round to a certain precision by scaling:
    >
    > (int)(x / precision + 0.5) * precision"
    >
    > (int)(3.141 / 0.01 + 0.5) * 0.01 gives us:
    >
    > (int)(314.1 + 0.5) * 0.01 which is
    >
    > (int)314.6 * 0.01 which is
    >
    > 314 * 0.01 which is
    >
    > 3.14


    Yeah, you're right. Perhaps 14.6 should be written more clearly, with regard
    to what exactly it means by Precision. And an example added, like yours.

    >(int)(3.141 / 0.01 + 0.5) * 0.01


    Somehow I would be happier if that was written as:

    >(int)(3.141 *100 + 0.5) /100


    Then any errors due to 0.01 not being exactly 1/100 are someone else's
    fault.

    --
    Bart
     
    Bartc, Feb 25, 2008
    #8
  9. MisterE wrote:
    >> 14.6 is already used by How to Round a Number [to an integer]

    >
    > Then what need is there for this question?


    <Fx: swoosh sound of clue going over head>

    --
    Mark McIntyre

    CLC FAQ <http://c-faq.com/>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
     
    Mark McIntyre, Feb 25, 2008
    #9
  10. jacob navia <> writes:
    > "How can I round a number to x decimal places" ?
    >
    > This question keeps appearing. I would propose the following
    > solution


    Yes, the question keeps appearing. The best response, IMHO, is to ask
    the questioner why he wants to do that.

    > #include <float.h>
    > #include <math.h>
    >
    > double roundto(double x, int digits)
    > {
    > int sgn=1;
    >
    > if (x == 0)
    > return 0;
    > if (digits > DBL_DIG)
    > digits = DBL_DIG;
    > else if (digits < 1)
    > digits = 1;


    Silently changing any ``digits'' value less than 1 to 1 seems like a
    bad idea. For example, rounding to 0 digits is perfectly sensible;
    roundto(1.234, 0) should return 1.0. For that matter,
    roundto(123456.0, -2) should probably return 123400.0.

    I haven't thought much about whether values greater than DBL_DIG might
    make sense in some cases. You might just return the value of x
    directly.

    > if(x < 0.0) {
    > sgn = -sgn;
    > x = -x;
    > }
    > double p = floorl(log10l(x));


    Why do you use floorl and log10l in both roundto and roundtol?

    It's worth mentioning that floorl and long10l are new in C99, and may
    not be supported by all implementations.

    A solution not using transcendental functions *might* be faster.

    > p--;
    > p = digits-p;
    > double pow10 = pow(10.0, p);


    You're also mixing declarations and statements, which is perfectly
    legal in C99, but may not be supported by all compilers. If this were
    to be added to the FAQ, either this should be mentioned or all
    declarations should be moved to the beginning of the block.

    It's very possible that computing 10**p by repeated multiplication is
    going to be faster than calling pow(), which is a transcendental
    function. (It's also possible that some pow() implementations
    optimize the case where the second argument is equal to an integer
    value; I haven't checked.)

    It would be nice if the standard library provided a variant of the
    pow() function whose second parameter is an integer (type int is
    probably adequate).

    > return sgn*floor(x*pow10+0.5)/pow10;
    > }
    >
    > long double roundtol(long double x, int digits)

    [similar code snipped]

    > #include <stdio.h>
    > int main(void)
    > {
    > double d = 1.7888889988996678;
    > long double ld = 1.7888889988996678998877L;
    >
    > for (int i = 0; i<=DBL_DIG;i++) {
    > printf("i=%d: %.15g\n",i,roundto(d,i));
    > }
    > printf("\n 1.7888889988996678\n");
    > for (int i = 0; i<=LDBL_DIG;i++) {
    > printf("i=%d: %.18Lg\n",i,roundtol(ld,i));
    > }
    > printf("\n 1.7888889988996678998877L\n");
    > return 0;
    > }
    >
    > --------------------------------------------------------------------
    > I would propose it to add it to the FAQ.


    FAQ 14.6 proposes

    (int)(x / precision + 0.5) * precision

    Your roundto(x, 2) should be equivalent to the above with
    precision==0.01. On the other hand, the FAQ's solution fails when (x
    / precision + 0.5) is outside the range of type int.

    I compiled and ran your program and got:

    i=0: 1.79
    i=1: 1.79
    i=2: 1.789
    i=3: 1.7889
    [...]

    I've already pointed out your odd treatment of i=0. I think you have
    an off-by-one error as well.

    Finally, I question the usefulness of this entire approach (and the
    following is something that probably should be added to the FAQ).
    (And didn't we discuss this at some length a while ago?)

    To take a concrete example, rounding the value 1.2345 to 2 decimal
    places cannot be done exactly in binary floating-point. On one
    system, the actual stored value for 1.23 is
    1.229999999999999982236431605997495353221893310546875
    Certainly most of those digits are not significant; the point is that
    1.23 cannot be stored exactly, and that in this case it's
    mathematically less than 1.23.

    What is the purpose of rounding a floating-point value to N decimal
    places? 99% of the time [*], the only purpose is to provide a textual
    representation of the number. Storing an approximation of the rounded
    value in a floating-point representation is not the best way to
    accomplish that. Just pass the original *unrounded* value to printf
    (or fprintf, or sprintf) with an appropriate format:

    printf("%.2f\n", 1.2345);

    Attempting to convert 1.2345 to a floating-point representation that
    closely approximates the value 1.23 merely wastes CPU cyles and
    introduces more possiblities for error.

    The question of rounding a floating-point number to a specified number
    of decimal places is an opportunity to teach the questioner a thing or
    two about how floating-point arithmetic works. By accepting the
    premise of the question, you pass up this opportunity.

    There may well be cases where the kind of internal rounding you
    describe is useful (perhaps in financial calculations). In such
    cases, it might make more sense to store the value in fixed-point (a
    scaled integer), or to keep the unrounded value in a structure along
    with an integer specifying the rounding to be applied later. Some,
    but by not means all, financial problems can be solved by storing the
    number of cents rather than the number of dollars (or euros, or
    whatever). In the remaining cases where you really need a
    floating-point approximation of the rounded value, it's likely that a
    specific algorithm is required by financial regulations.

    In however many cases remain after that, either the solution proposed
    in the FAQ or your solution (with corrections) could be useful.

    If you can present a non-artificial case where computing an
    approximate floating-point rounded result, rather than doing the
    rounding on output, is actually required, I'd be interested in seeing
    it.

    [*] Yes, I made up the 99% figure, but it's not an unreasonable guess.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 25, 2008
    #10
  11. jacob navia

    user923005 Guest

    On Feb 25, 2:18 am, jacob navia <> wrote:
    > Hi
    >
    > "How can I round a number to x decimal places" ?
    >
    > This question keeps appearing. I would propose the following
    > solution
    >
    > #include <float.h>
    > #include <math.h>
    >
    > double roundto(double x, int digits)
    > {
    >         int sgn=1;
    >
    >         if (x == 0)
    >                 return 0;
    >         if (digits > DBL_DIG)
    >                 digits = DBL_DIG;
    >         else if (digits < 1)
    >                 digits = 1;
    >
    >         if(x < 0.0) {
    >                 sgn = -sgn;
    >                 x = -x;
    >         }
    >         double p = floorl(log10l(x));
    >         p--;
    >         p = digits-p;
    >         double pow10 = pow(10.0, p);
    >         return sgn*floor(x*pow10+0.5)/pow10;
    >
    > }
    >
    > long double roundtol(long double x, int digits)
    > {
    >         int sgn=1;
    >
    >         if (x == 0)
    >                 return 0;
    >         if (digits > LDBL_DIG)
    >                 digits = LDBL_DIG;
    >         else if (digits < 1)
    >                 digits = 1;
    >
    >         if(x < 0.0) {
    >                 sgn = -sgn;
    >                 x = -x;
    >         }
    >         long double p = floorl(log10l(x));
    >         p--;
    >         p = digits-p;
    >         long double pow10 = powl(10.0, p);
    >         return sgn*floorl(x*pow10+0.5)/pow10;}
    >
    > #include <stdio.h>
    > int main(void)
    > {
    >         double d = 1.7888889988996678;
    >         long double ld = 1.7888889988996678998877L;
    >
    >         for (int i = 0; i<=DBL_DIG;i++) {
    >                 printf("i=%d: %.15g\n",i,roundto(d,i));
    >         }
    >         printf("\n      1.7888889988996678\n");
    >         for (int i = 0; i<=LDBL_DIG;i++) {
    >                 printf("i=%d: %.18Lg\n",i,roundtol(ld,i));
    >         }
    >         printf("\n      1.7888889988996678998877L\n");
    >         return 0;
    >
    > }
    >
    > --------------------------------------------------------------------
    > I would propose it to add it to the FAQ.


    This is the snippet's solution (which is very similar to yours):
    /* round number n to d decimal points */
    double fround(double n, unsigned d)
    {
    return floor(n * pow(10., d) + .5) / pow(10., d);
    }

    Of course, no solution is really going to be satisfying, as long as
    the output format is floating point.
    Another question is "What kind of rounding?" Do we want banker's
    rounding or round to nearest or what?
    Should we create a round function for each distinct floating point
    type?
     
    user923005, Feb 25, 2008
    #11
  12. jacob navia

    user923005 Guest

    On Feb 25, 2:18 am, jacob navia <> wrote:
    > Hi
    >
    > "How can I round a number to x decimal places" ?
    >
    > This question keeps appearing. I would propose the following
    > solution
    >
    > #include <float.h>
    > #include <math.h>
    >
    > double roundto(double x, int digits)
    > {
    >         int sgn=1;
    >
    >         if (x == 0)
    >                 return 0;
    >         if (digits > DBL_DIG)
    >                 digits = DBL_DIG;
    >         else if (digits < 1)
    >                 digits = 1;
    >
    >         if(x < 0.0) {
    >                 sgn = -sgn;
    >                 x = -x;
    >         }
    >         double p = floorl(log10l(x));
    >         p--;
    >         p = digits-p;
    >         double pow10 = pow(10.0, p);
    >         return sgn*floor(x*pow10+0.5)/pow10;
    >
    > }
    >
    > long double roundtol(long double x, int digits)
    > {
    >         int sgn=1;
    >
    >         if (x == 0)
    >                 return 0;
    >         if (digits > LDBL_DIG)
    >                 digits = LDBL_DIG;
    >         else if (digits < 1)
    >                 digits = 1;
    >
    >         if(x < 0.0) {
    >                 sgn = -sgn;
    >                 x = -x;
    >         }
    >         long double p = floorl(log10l(x));
    >         p--;
    >         p = digits-p;
    >         long double pow10 = powl(10.0, p);
    >         return sgn*floorl(x*pow10+0.5)/pow10;}
    >
    > #include <stdio.h>
    > int main(void)
    > {
    >         double d = 1.7888889988996678;
    >         long double ld = 1.7888889988996678998877L;
    >
    >         for (int i = 0; i<=DBL_DIG;i++) {
    >                 printf("i=%d: %.15g\n",i,roundto(d,i));
    >         }
    >         printf("\n      1.7888889988996678\n");
    >         for (int i = 0; i<=LDBL_DIG;i++) {
    >                 printf("i=%d: %.18Lg\n",i,roundtol(ld,i));
    >         }
    >         printf("\n      1.7888889988996678998877L\n");
    >         return 0;
    >
    > }
    >
    > --------------------------------------------------------------------
    > I would propose it to add it to the FAQ.


    The snippets solution, tweaked a little bit:

    #include <math.h>
    /* round number n to d decimal points */
    long double roundl(const long double n, const unsigned d)
    {
    long double p = powl(10., d);
    return floorl(n * p + .5) / p;
    }

    /* round number n to d decimal points */
    double roundd(const double n, const unsigned d)
    {
    return (double) roundl((long double) n, d);
    }

    /* round number n to d decimal points */
    double roundf(const float n, const unsigned d)
    {
    return (float) roundl((long double) n, d);
    }
    #ifdef UNIT_TEST
    #include <stdio.h>
    #include <stdlib.h>
    #include <float.h>
    int main(void)
    {
    long double pi = 3.1415926535897932384626433832795;
    long double npi = -pi;
    unsigned digits;
    for (digits = 0; digits <= LDBL_DIG; digits++) {
    printf("Rounding by printf gives: %20.*f\n",
    digits, pi);
    printf("Rounding approximation by function gives: %20.*f\n",
    LDBL_DIG, roundl(pi, digits));
    printf("Rounding approximation by function gives: %20.*f\n",
    DBL_DIG, roundd(pi, digits));
    printf("Rounding approximation by function gives: %20.*f\n\n",
    FLT_DIG, roundf(pi, digits));
    }
    for (digits = 0; digits <= LDBL_DIG; digits++) {
    printf("Rounding by printf gives: %20.*f\n",
    digits, npi);
    printf("Rounding approximation by function gives: %20.*f\n",
    LDBL_DIG, roundl(npi, digits));
    printf("Rounding approximation by function gives: %20.*f\n",
    DBL_DIG, roundd(npi, digits));
    printf("Rounding approximation by function gives: %20.*f\n\n",
    FLT_DIG, roundf(npi, digits));
    }
    return 0;
    }
    #endif
    /*
    Rounding by printf gives: 3
    Rounding approximation by function gives: 3.000000000000000
    Rounding approximation by function gives: 3.000000000000000
    Rounding approximation by function gives: 3.000000

    Rounding by printf gives: 3.1
    Rounding approximation by function gives: 3.100000000000000
    Rounding approximation by function gives: 3.100000000000000
    Rounding approximation by function gives: 3.100000

    Rounding by printf gives: 3.14
    Rounding approximation by function gives: 3.140000000000000
    Rounding approximation by function gives: 3.140000000000000
    Rounding approximation by function gives: 3.140000

    Rounding by printf gives: 3.142
    Rounding approximation by function gives: 3.142000000000000
    Rounding approximation by function gives: 3.142000000000000
    Rounding approximation by function gives: 3.142000

    Rounding by printf gives: 3.1416
    Rounding approximation by function gives: 3.141600000000000
    Rounding approximation by function gives: 3.141600000000000
    Rounding approximation by function gives: 3.141600

    Rounding by printf gives: 3.14159
    Rounding approximation by function gives: 3.141590000000000
    Rounding approximation by function gives: 3.141590000000000
    Rounding approximation by function gives: 3.141590

    Rounding by printf gives: 3.141593
    Rounding approximation by function gives: 3.141593000000000
    Rounding approximation by function gives: 3.141593000000000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.1415927
    Rounding approximation by function gives: 3.141592700000000
    Rounding approximation by function gives: 3.141592700000000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.14159265
    Rounding approximation by function gives: 3.141592650000000
    Rounding approximation by function gives: 3.141592650000000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.141592654
    Rounding approximation by function gives: 3.141592654000000
    Rounding approximation by function gives: 3.141592654000000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.1415926536
    Rounding approximation by function gives: 3.141592653600000
    Rounding approximation by function gives: 3.141592653600000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.14159265359
    Rounding approximation by function gives: 3.141592653590000
    Rounding approximation by function gives: 3.141592653590000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.141592653590
    Rounding approximation by function gives: 3.141592653590000
    Rounding approximation by function gives: 3.141592653590000
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.1415926535898
    Rounding approximation by function gives: 3.141592653589800
    Rounding approximation by function gives: 3.141592653589800
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.14159265358979
    Rounding approximation by function gives: 3.141592653589790
    Rounding approximation by function gives: 3.141592653589790
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: 3.141592653589793
    Rounding approximation by function gives: 3.141592653589793
    Rounding approximation by function gives: 3.141592653589793
    Rounding approximation by function gives: 3.141593

    Rounding by printf gives: -3
    Rounding approximation by function gives: -3.000000000000000
    Rounding approximation by function gives: -3.000000000000000
    Rounding approximation by function gives: -3.000000

    Rounding by printf gives: -3.1
    Rounding approximation by function gives: -3.100000000000000
    Rounding approximation by function gives: -3.100000000000000
    Rounding approximation by function gives: -3.100000

    Rounding by printf gives: -3.14
    Rounding approximation by function gives: -3.140000000000000
    Rounding approximation by function gives: -3.140000000000000
    Rounding approximation by function gives: -3.140000

    Rounding by printf gives: -3.142
    Rounding approximation by function gives: -3.142000000000000
    Rounding approximation by function gives: -3.142000000000000
    Rounding approximation by function gives: -3.142000

    Rounding by printf gives: -3.1416
    Rounding approximation by function gives: -3.141600000000000
    Rounding approximation by function gives: -3.141600000000000
    Rounding approximation by function gives: -3.141600

    Rounding by printf gives: -3.14159
    Rounding approximation by function gives: -3.141590000000000
    Rounding approximation by function gives: -3.141590000000000
    Rounding approximation by function gives: -3.141590

    Rounding by printf gives: -3.141593
    Rounding approximation by function gives: -3.141593000000000
    Rounding approximation by function gives: -3.141593000000000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.1415927
    Rounding approximation by function gives: -3.141592700000000
    Rounding approximation by function gives: -3.141592700000000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.14159265
    Rounding approximation by function gives: -3.141592650000000
    Rounding approximation by function gives: -3.141592650000000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.141592654
    Rounding approximation by function gives: -3.141592654000000
    Rounding approximation by function gives: -3.141592654000000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.1415926536
    Rounding approximation by function gives: -3.141592653600000
    Rounding approximation by function gives: -3.141592653600000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.14159265359
    Rounding approximation by function gives: -3.141592653590000
    Rounding approximation by function gives: -3.141592653590000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.141592653590
    Rounding approximation by function gives: -3.141592653590000
    Rounding approximation by function gives: -3.141592653590000
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.1415926535898
    Rounding approximation by function gives: -3.141592653589800
    Rounding approximation by function gives: -3.141592653589800
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.14159265358979
    Rounding approximation by function gives: -3.141592653589790
    Rounding approximation by function gives: -3.141592653589790
    Rounding approximation by function gives: -3.141593

    Rounding by printf gives: -3.141592653589793
    Rounding approximation by function gives: -3.141592653589793
    Rounding approximation by function gives: -3.141592653589793
    Rounding approximation by function gives: -3.141593
    */
     
    user923005, Feb 25, 2008
    #12
  13. jacob navia

    CBFalconer Guest

    jacob navia wrote:
    >
    > "How can I round a number to x decimal places" ?
    >
    > This question keeps appearing. I would propose the following
    >

    .... snip 75 or so lines ...

    Why all this gyration? I found the following in the c standard:

    7.12.9.6 The round functions
    Synopsis
    [#1]
    #include <math.h>
    double round(double x);
    float roundf(float x);
    long double roundl(long double x);

    Description

    [#2] The round functions round their argument to the nearest
    integer value in floating-point format, rounding halfway
    cases away from zero, regardless of the current rounding
    direction.

    Returns

    [#3] The round functions return the rounded integer value.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Feb 25, 2008
    #13
  14. jacob navia

    Ben Pfaff Guest

    CBFalconer <> writes:

    > jacob navia wrote:
    >>
    >> "How can I round a number to x decimal places" ?
    >>
    >> This question keeps appearing. I would propose the following
    >>

    > ... snip 75 or so lines ...
    >
    > Why all this gyration? I found the following in the c standard:
    >
    > 7.12.9.6 The round functions


    Those functions are new in C99.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Feb 26, 2008
    #14
  15. jacob navia

    user923005 Guest

    On Feb 25, 4:29 pm, Ben Pfaff <> wrote:
    > CBFalconer <> writes:
    > > jacob navia wrote:

    >
    > >> "How can I round a number to x decimal places" ?

    >
    > >> This question keeps appearing. I would propose the following

    >
    > > ... snip 75 or so lines ...

    >
    > > Why all this gyration?  I found the following in the c standard:

    >
    > >   7.12.9.6  The round functions

    >
    > Those functions are new in C99.


    And they don't round to x decimal places, unless x happens to be
    zero. (Admittedly, you could manually scale it.)
     
    user923005, Feb 26, 2008
    #15
  16. Ben Pfaff <> writes:
    > CBFalconer <> writes:
    >> jacob navia wrote:
    >>> "How can I round a number to x decimal places" ?
    >>>
    >>> This question keeps appearing. I would propose the following
    >>>

    >> ... snip 75 or so lines ...
    >>
    >> Why all this gyration? I found the following in the c standard:
    >>
    >> 7.12.9.6 The round functions

    >
    > Those functions are new in C99.


    So are floorl and log10l, which jacob's code uses; it also mixes
    declarations and statements within a block. An implementation that
    can handle jacob's code should provide the round functions.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 26, 2008
    #16
  17. jacob navia

    user923005 Guest

    On Feb 25, 10:15 pm, Keith Thompson <> wrote:
    > Ben Pfaff <> writes:
    > > CBFalconer <> writes:
    > >> jacob navia wrote:
    > >>> "How can I round a number to x decimal places" ?

    >
    > >>> This question keeps appearing. I would propose the following

    >
    > >> ... snip 75 or so lines ...

    >
    > >> Why all this gyration?  I found the following in the c standard:

    >
    > >>   7.12.9.6  The round functions

    >
    > > Those functions are new in C99.

    >
    > So are floorl and log10l, which jacob's code uses; it also mixes
    > declarations and statements within a block.  An implementation that
    > can handle jacob's code should provide the round functions.


    You will still have to multiply and divide by powers of 10 and use
    floor() to achieve the same thing because the C99 round() functions
    round to nearest integer. They do not round to nearest k decimal
    places.
     
    user923005, Feb 26, 2008
    #17
  18. jacob navia

    CBFalconer Guest

    user923005 wrote:
    >

    .... snip float rounding discussion ...
    >
    > You will still have to multiply and divide by powers of 10 and use
    > floor() to achieve the same thing because the C99 round() functions
    > round to nearest integer. They do not round to nearest k decimal
    > places.


    Are you claiming that such multiplication and division by 10 is too
    complex for the average reader of c.l.c? :)

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Feb 26, 2008
    #18
  19. jacob navia

    user923005 Guest

    On Feb 26, 2:24 pm, CBFalconer <> wrote:
    > user923005 wrote:
    >
    > ... snip float rounding discussion ...
    >
    >
    >
    > > You will still have to multiply and divide by powers of 10 and use
    > > floor() to achieve the same thing because the C99 round() functions
    > > round to nearest integer.  They do not round to nearest k decimal
    > > places.

    >
    > Are you claiming that such multiplication and division by 10 is too
    > complex for the average reader of c.l.c?  :)


    No, but I am claiming that using the C99 functions to round to N
    digits will take twice as much work as a function that does it
    directly, since the multiplication and division by a power of ten and
    the floor function are all that is necessary in either case. And so
    while you can round to N digits using the C99 rounding functions, it
    really does not make a lot of sense to do it that way.
     
    user923005, Feb 27, 2008
    #19
  20. jacob navia

    CBFalconer Guest

    user923005 wrote:
    > CBFalconer <> wrote:
    >> user923005 wrote:
    >>
    >> ... snip float rounding discussion ...
    >>
    >>> You will still have to multiply and divide by powers of 10 and
    >>> use floor() to achieve the same thing because the C99 round()
    >>> functions round to nearest integer. They do not round to
    >>> nearest k decimal places.

    >>
    >> Are you claiming that such multiplication and division by 10 is
    >> too complex for the average reader of c.l.c? :)

    >
    > No, but I am claiming that using the C99 functions to round to N
    > digits will take twice as much work as a function that does it
    > directly, since the multiplication and division by a power of
    > ten and the floor function are all that is necessary in either
    > case. And so while you can round to N digits using the C99
    > rounding functions, it really does not make a lot of sense to do
    > it that way.


    Let me also point out that such rounding is rarely needed. Most of
    the time maintaining the original alleged precision and rounding
    only the output, via printf, is needed.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Feb 27, 2008
    #20
    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. Sooha Park Lee

    Rounding a floating point number declared in "double"

    Sooha Park Lee, Jul 16, 2003, in forum: C Programming
    Replies:
    2
    Views:
    485
    Mark McIntyre
    Jul 16, 2003
  2. Sooha Park Lee

    Rounding a floating point number declared in "double"

    Sooha Park Lee, Jul 16, 2003, in forum: C Programming
    Replies:
    2
    Views:
    326
    martinh
    Jul 17, 2003
  3. hg

    floating point rounding

    hg, Mar 9, 2007, in forum: Python
    Replies:
    4
    Views:
    324
  4. Floating point rounding error

    , Jun 16, 2007, in forum: C Programming
    Replies:
    15
    Views:
    1,914
    Jean-Marc Bourguet
    Jul 2, 2007
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,341
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page