Rounding floats/doubles

Discussion in 'C Programming' started by itportal, Jan 16, 2006.

  1. itportal

    itportal Guest

    Hello,

    This will probably be a simple question. How can I round float/doubles
    to a specific digit after the comma/dot?

    For example we have float i = 1.234567. I want to round it to 1.234.
    Whan function should I use?
     
    itportal, Jan 16, 2006
    #1
    1. Advertising

  2. itportal

    itportal Guest

    printf("%.3f ",i);

    rounds the number to 1.235

    How to round it to 1.234.
     
    itportal, Jan 16, 2006
    #2
    1. Advertising

  3. itportal wrote:
    > printf("%.3f ",i);
    >
    > rounds the number to 1.235
    >
    > How to round it to 1.234.
    >


    One way is to sprintf() with "%f" specifier to a string buffer, and then
    truncate resultant string to taste...

    Cheers

    Vladimir


    --
    My e-mail address is real, and I read it.
     
    Vladimir S. Oka, Jan 16, 2006
    #3
  4. <> wrote:
    >For example we have float i = 1.234567. I want
    >to round it to 1.234.


    and

    >printf("%.3f ",i);
    >rounds the number to 1.235


    "1.235" is what most of us would call
    the correct "rounded" value of "1.234567"

    To "round it down", you could use truncf():

    #include <math.h>
    ...
    #define TWO_DIGITS 100.0
    #define TREE_DIGITS 1000.0
    #define FOUR_DIGITS 10000.0
    ...
    float i, i_truncated;
    i = 1.234567;
    i_truncated = truncf(i * THREE_DIGITS) / THREE_DIGITS;
    ...

    Use trunc(), if you are dealing with double variables.

    I followed your example using 'i', even though it strongly
    suggests an integer data type. (Or it is only for people
    like me, who used FORTRAN long before using C ?)

    Roberto Waltman

    [ Please reply to the group, ]
    [ return address is invalid. ]
     
    Roberto Waltman, Jan 16, 2006
    #4
  5. itportal

    Eric Sosman Guest

    itportal wrote:

    > Hello,
    >
    > This will probably be a simple question. How can I round float/doubles
    > to a specific digit after the comma/dot?
    >
    > For example we have float i = 1.234567. I want to round it to 1.234.
    > Whan function should I use?


    I can't think of one -- after all, it's a fairly
    unusual "rounding" rule that produces the more distant
    of the two candidate values. However, you could use

    #include <math.h>
    ...
    float j = (float)(floor(i * 1000.0) / 1000.0);

    I don't guarantee this will do what you want with negative
    numbers (you didn't mention what you want). Also, the
    similar version for `double' will probably misbehave with
    starting values larger than DBL_MAX/1000. Finally, note
    that eight significant digits are more than you have any
    right to expect from a `float' ...

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jan 16, 2006
    #5
  6. itportal wrote:
    > Hello,
    >
    > This will probably be a simple question. How can I round float/doubles
    > to a specific digit after the comma/dot?
    >
    > For example we have float i = 1.234567. I want to round it to 1.234.
    > Whan function should I use?
    >


    Oh, BTW, when I learned maths the rule was:

    a.bcdef

    if d<5 round to a.bc
    else if d>5 round to a.b(c+1) and recurse for b
    else if d==5 then
    if c is even round to a.bc
    else ronud to a.b(c+1) and recurse for b

    Cheers

    Vladimir


    --
    My e-mail address is real, and I read it.
     
    Vladimir S. Oka, Jan 16, 2006
    #6
  7. >For example we have float i = 1.234567.

    You *DO NOT* have a float of that value on a machine with binary
    floating point.

    If it's not an exact integer and the decimal representation doesn't
    end in 5, there's no exact representation in binary floating point.

    >I want to round it to 1.234.


    You *DO NOT* have a float of that value on a machine with binary
    floating point.

    >Whan function should I use?
    >


    Multiply by 1000, floor() it, then divide by 1000. Dividing by 1000
    re-introduces rounding error.


    Gordon L. Burditt
     
    Gordon Burditt, Jan 16, 2006
    #7
  8. "itportal" <> writes:
    > This will probably be a simple question. How can I round float/doubles
    > to a specific digit after the comma/dot?
    >
    > For example we have float i = 1.234567. I want to round it to 1.234.
    > Whan function should I use?


    Do want the rounded value to be a floating-point number, or do you
    just want a string to be displayed somewhere?

    If you want a numeric result, keep in mind that neither 1.234567 nor
    1.234 can be represented exactly in binary floating-point. You can
    get a close approximation to 1.234, but it could be either slightly
    larger or slightly smaller than 1.234; if it's smaller, trying to
    truncate it again could give you 1.233.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jan 16, 2006
    #8
  9. The function below uses an integer cast to remove the fractional part
    of the value after being pre-scaled. This is an alternative to using
    the floor() function previously mentioned.

    double truncate_digits(double d, int significant_digits)
    {
    unsigned long int prescaler;

    /* Construct the prescaler value for this number of digits */
    for (prescaler = 1; significant_digits > 0; significant_digits--)
    {
    prescaler *= 10;
    }

    return ((long int)(d * prescaler) / (double)prescaler);
    }

    Will this perform the same on all C compilers?

    Lucien Kennedy-Lamb
     
    Lucien Kennedy-Lamb, Jan 17, 2006
    #9
  10. >The function below uses an integer cast to remove the fractional part
    >of the value after being pre-scaled. This is an alternative to using
    >the floor() function previously mentioned.
    >
    >double truncate_digits(double d, int significant_digits)
    >{
    > unsigned long int prescaler;
    >
    > /* Construct the prescaler value for this number of digits */
    > for (prescaler = 1; significant_digits > 0; significant_digits--)
    > {
    > prescaler *= 10;
    > }
    >
    > return ((long int)(d * prescaler) / (double)prescaler);
    >}
    >
    >Will this perform the same on all C compilers?


    No. Division by a power of 10 will introduce rounding error on
    machines using binary floating point (that is: most of them) and
    how much rounding error (and which direction) depends on the precision
    of the floating point. This assumes that prescaler > 0 and
    the exact result with infinite-precision math isn't an integer, which
    covers just about all of the interesting uses of the function.

    Oh, yes, even worse things happen if the calculation of prescaler
    or d*prescaler overflows.

    Gordon L. Burditt
     
    Gordon Burditt, Jan 17, 2006
    #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. {AGUT2} {H}-IWIK
    Replies:
    4
    Views:
    2,867
    Marcelo Pinto
    Sep 12, 2003
  2. dan
    Replies:
    1
    Views:
    2,326
    Jack Klein
    Nov 26, 2003
  3. J.K. Becker
    Replies:
    43
    Views:
    1,014
  4. SpreadTooThin
    Replies:
    7
    Views:
    413
    Diez B. Roggisch
    Sep 16, 2006
  5. Andrew Reilly

    Re: Floats, doubles C and MSVC

    Andrew Reilly, Oct 14, 2004, in forum: C Programming
    Replies:
    2
    Views:
    686
    Tim Prince
    Oct 14, 2004
Loading...

Share This Page