Rounding floats/doubles

I

itportal

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

Vladimir S. Oka

itportal said:
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
 
R

Roberto Waltman

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. ]
 
E

Eric Sosman

itportal said:
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' ...
 
V

Vladimir S. Oka

itportal said:
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
 
G

Gordon Burditt

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
 
K

Keith Thompson

itportal said:
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.
 
L

Lucien Kennedy-Lamb

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
 
G

Gordon Burditt

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top