# Rounding floats/doubles

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

1. ### itportalGuest

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

2. ### itportalGuest

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

rounds the number to 1.235

How to round it to 1.234.

itportal, Jan 16, 2006

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 S. Oka, Jan 16, 2006
4. ### Roberto WaltmanGuest

<> 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

[ return address is invalid. ]

Roberto Waltman, Jan 16, 2006
5. ### Eric SosmanGuest

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

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 S. Oka, Jan 16, 2006
7. ### Gordon BurdittGuest

>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
8. ### Keith ThompsonGuest

"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
9. ### Lucien Kennedy-LambGuest

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
10. ### Gordon BurdittGuest

>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