Is there a function to round a float in C or do I need to write my own?
float conver = 45.592346543;
I would
To print a rounded value, @Matt J well answers the question.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
As most floating point (FP) is binary based, exact rounding to one decimal place is not possible when the mathematically correct answer is x.1, x.2, ...
.
To convert the FP number to the nearest 0.1
is another matter.
Overflow: Approaches that first scale by 10 (or 100, 1000, etc) may overflow for large x
.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Double rounding: Adding 0.5f and then using floorf(x*10.0f + 0.5f)/10.0
returns the wrong result when the intermediate sum x*10.0f + 0.5f
rounds up to a new integer.
// Fails to round 838860.4375 correctly, comes up with 838860.5
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
if (x < 0.0) {
return ceilf(x*10.0f + 0.5f)/10.0f;
}
return floorf(x*10.0f + 0.5f)/10.0f;
}
Casting to int
has the obvious problem when float x
is much greater than INT_MAX
.
Using roundf()
and family, available in <math.h>
is the best approach.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
To avoid using double
, simply test if the number needs rounding.
float round_tenthB(float x) {
const float limit = 1.0/FLT_EPSILON;
if (fabsf(x) < limit) {
return roundf(x*10.0f)/10.0f;
}
return x;
}
As Rob mentioned, you probably just want to print the float to 1 decimal place. In this case, you can do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
If you want to actually round the stored value, that's a little more complicated. For one, your one-decimal-place representation will rarely have an exact analog in floating-point. If you just want to get as close as possible, something like this might do the trick:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
conver = conver*10.0f;
conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
conver = conver/10.0f;
//If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
//conver = roundf(conver*10.0f)/10.0f;
printf("conver is now %f\n",conver);
return 0;
}
I doubt this second example is what you're looking for, but I included it for completeness. If you do require representing your numbers in this way internally, and not just on output, consider using a fixed-point representation instead.
#include <math.h>
double round(double x);
float roundf(float x);
Don't forget to link with -lm. See also ceil(), floor() and trunc().
Just to generalize Rob's answer a little, if you're not doing it on output, you can still use the same interface with sprintf()
.
I think there is another way to do it, though. You can try ceil()
and floor()
to round up and down. A nice trick is to add 0.5, so anything over 0.5 rounds up but anything under it rounds down. ceil()
and floor()
only work on double
s though.
EDIT: Also, for floats, you can use truncf()
to truncate floats. The same +0.5 trick should work to do accurate rounding.
you can use #define round(a) (int) (a+0.5) as macro so whenever you write round(1.6) it returns 2 and whenever you write round(1.3) it return 1.
Sure, you can use roundf(). If you want to round to one decimal, then you could do something like: roundf(10 * x) / 10