How can I round a float value (such as 37.777779) to two decimal places (37.78) in C?
-
15You cannot properly round the number itself, because `float` (and `double`) aren't decimal floating-point - they are binary floating-point - so rounding to decimal positions is meaningless. You can round the output, however. – Pavel Minaev Aug 27 '09 at 21:49
-
75It's not meaningless; it's inexact. There's quite a difference. – Brooks Moses Aug 28 '09 at 03:08
-
2What kind of rounding you're expecting? Half-up or Rounding to nearest even? – Truthseeker Rangwan Aug 03 '14 at 13:21
17 Answers
If you just want to round the number for output purposes, then the "%.2f"
format string is indeed the correct answer. However, if you actually want to round the floating point value for further computation, something like the following works:
#include <math.h>
float val = 37.777779;
float rounded_down = floorf(val * 100) / 100; /* Result: 37.77 */
float nearest = roundf(val * 100) / 100; /* Result: 37.78 */
float rounded_up = ceilf(val * 100) / 100; /* Result: 37.78 */
Notice that there are three different rounding rules you might want to choose: round down (ie, truncate after two decimal places), rounded to nearest, and round up. Usually, you want round to nearest.
As several others have pointed out, due to the quirks of floating point representation, these rounded values may not be exactly the "obvious" decimal values, but they will be very very close.
For much (much!) more information on rounding, and especially on tie-breaking rules for rounding to nearest, see the Wikipedia article on Rounding.

- 16,074
- 4
- 30
- 37
-
5
-
1@slater When you say 'arbitrary precision', are you asking about rounding to, eg, three instead of two decimal places, or using libraries that implement unbounded precision decimal values? If the former, make what I hope are obvious adjustments to the constant 100; otherwise, do the exact same calculations shown above, just with whatever multi precision library you're using. – Dale Hagglund May 15 '14 at 07:09
-
2@DaleHagglung The former, thank you. Is the adjustment to replace 100 with pow(10, (int)desiredPrecision)? – May 15 '14 at 15:09
-
3Yep. To round after k decimal places, use a scale factor of 10^k. This should be really easy to see if you write out some decimal values by hand and play around with multiples of 10. Suppose you're working with the value 1.23456789, and want to round it to 3 decimal places. The operation available to you is *round to integer*. So, how do you move the first three decimal places so that they're left of the decimal point? I hope it's clear that you multiply by 10^3. Now you can round that value to an integer. Next, you put the three low order digits back by dividing by 10^3. – Dale Hagglund May 16 '14 at 03:19
-
1Can I make this work with `doubles` too somehow? Doesn't seem to do the job I want :( (using `floor` and `ceil`). – Ms. Nobody Jun 20 '14 at 12:40
-
It ought to work fine, even if all you do is change 'float' to 'double'. Can you describe what problems your having? – Dale Hagglund Jun 21 '14 at 22:56
-
You're quite right that it fails for negative numbers. I wasn't aware of 'roundf', though, so thanks. – Dale Hagglund Aug 03 '14 at 20:42
-
would there any any advantage of doing `roundf(val*100)/100` vs `round(val / 1e-2) * 1e-2` ? – Apeiron Jan 28 '15 at 23:11
-
@Apeiron: I think they'll be exactly the same after the compiler converts the integer constant 100 to a floating point value. However I'd argue the former is simpler to read. – Dale Hagglund Jan 29 '15 at 04:19
-
1Here's your generic macro that will work for arbitrary decimal places: `#define ROUND_TO_DECIMAL_PLACES(x, decimal_places) (roundf(x * 1e##decimal_places) / 1e##decimal_places)` – smileyborg Mar 16 '16 at 03:30
-
-
1
-
1This can return wrong results if the number you're trying to round is very close to the threshold where the result changes, because the multiplication by 100 can change whether it should round up or down. For instance, the number 0.01499999999999999944488848768742172978818416595458984375 can be exactly represented as a double, and the mathematically correct result if you round it to 2 dp using to-nearest rounding is 0.01, but if you round it in the way shown here, you'll get 0.02, because 0.01499999999999999944488848768742172978818416595458984375 * 100 gives *exactly* 1.5 which rounds upwards. – Mark Amery Aug 25 '19 at 11:53
-
@MarkAmery Thanks for the very interesting example. In hindsight, given all the vagaries of floating point arithmetic I shouldn't be surprised. Do you happen to know if accurate rounding is provided in IEEE floating point? – Dale Hagglund Aug 26 '19 at 07:35
-
@DaleHagglund It's provided by `snprintf`, and so in my answer I suggest that the only easy way to solve this problem correctly is to [convert to a string with `snprintf` and then parse the string](https://stackoverflow.com/a/57647113/1709587). – Mark Amery Aug 26 '19 at 08:47
-
@MarkAmery Very nice. Now, if you'll permit me a moment of silence for this answer which has been, one might say, a steady earner for a long time. – Dale Hagglund Aug 27 '19 at 03:32
-
Using %.2f in printf. It only print 2 decimal points.
Example:
printf("%.2f", 37.777779);
Output:
37.77

- 500
- 3
- 18

- 10,100
- 8
- 32
- 30
-
-
3@albert This also has the advantage of no loss of `float` range as `val * 100` could overflow. – chux - Reinstate Monica Aug 03 '14 at 15:52
-
1[Here](https://stackoverflow.com/q/24120888), it was discussed `%.2f` is implementation-dependent. – tueda Aug 24 '22 at 16:13
Assuming you're talking about round the value for printing, then Andrew Coleson and AraK's answer are correct:
printf("%.2f", 37.777779);
But note that if you're aiming to round the number to exactly 37.78 for internal use (eg to compare against another value), then this isn't a good idea, due to the way floating point numbers work: you usually don't want to do equality comparisons for floating point, instead use a target value +/- a sigma value. Or encode the number as a string with a known precision, and compare that.
See the link in Greg Hewgill's answer to a related question, which also covers why you shouldn't use floating point for financial calculations.

- 1
- 1

- 53,924
- 26
- 111
- 144
-
1Upvoted for addressing what may be the question behind the question (or the question that should have been behind the question!). That's a rather important point. – Brooks Moses Aug 28 '09 at 03:13
-
Actually 37.78 can be presented exactly by floating point. Float has 11 to 12 digit for precission. That should be enough to address 3778 377.8 or all kind of 4 decimal digit. – Anonymous White Oct 28 '12 at 09:56
-
-
1dynamic precision: `printf("%.*f", (int)precision, (double)number);` – Minhas Kamal Feb 26 '20 at 05:10
-
@AnonymousWhite That is not correct, the closest value to 37.78 using 32-bit floating point is 37.779998779296875. It can not be represented exactly. – orlp Sep 22 '22 at 10:49
-
"you shouldn't use floating point for financial calculations." is out-of-date with C23 as decimal floating point is great for financial code. – chux - Reinstate Monica Aug 22 '23 at 17:08
How about this:
float value = 37.777779;
float rounded = ((int)(value * 100 + .5) / 100.0);

- 1,398
- 2
- 17
- 28
-
6-1: a) this won't work for negative numbers (ok, the example is positive but still). b) you don't mention that it's impossible to store the exact decimal value in the float – John Carter Aug 28 '09 at 08:28
-
36
-
-
1
-
1
-
2_rounding rules_ in the context of @Daniil comment are __round to nearest__ – Shmil The Cat May 15 '17 at 15:43
printf("%.2f", 37.777779);
If you want to write to C-string:
char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);

- 45,516
- 10
- 73
- 79

- 94,250
- 39
- 176
- 234
-
@Sinan: Why the edit? @AraK: No, *you* should take care of the size :). Use snprintf(). – aib Aug 28 '09 at 14:17
-
1@aib: I would guess because /**/ are C style comments and the question is tagged for C – Michael Haren Aug 28 '09 at 14:20
-
5C89 only allowed /**/-style, C99 introduced support for //-style. Use a lame/old compiler (or force C89 mode) and you'll be unable to use //-style. Having said that, it's 2009, let's consider them both C and C++ style. – Andrew Coleson Sep 04 '09 at 17:28
Always use the printf
family of functions for this. Even if you want to get the value as a float, you're best off using snprintf
to get the rounded value as a string and then parsing it back with atof
:
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
double dround(double val, int dp) {
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
char *buffer = malloc(charsNeeded);
snprintf(buffer, charsNeeded, "%.*f", dp, val);
double result = atof(buffer);
free(buffer);
return result;
}
I say this because the approach shown by the currently top-voted answer and several others here - multiplying by 100, rounding to the nearest integer, and then dividing by 100 again - is flawed in two ways:
- For some values, it will round in the wrong direction because the multiplication by 100 changes the decimal digit determining the rounding direction from a 4 to a 5 or vice versa, due to the imprecision of floating point numbers
- For some values, multiplying and then dividing by 100 doesn't round-trip, meaning that even if no rounding takes place the end result will be wrong
To illustrate the first kind of error - the rounding direction sometimes being wrong - try running this program:
int main(void) {
// This number is EXACTLY representable as a double
double x = 0.01499999999999999944488848768742172978818416595458984375;
printf("x: %.50f\n", x);
double res1 = dround(x, 2);
double res2 = round(100 * x) / 100;
printf("Rounded with snprintf: %.50f\n", res1);
printf("Rounded with round, then divided: %.50f\n", res2);
}
You'll see this output:
x: 0.01499999999999999944488848768742172978818416595459
Rounded with snprintf: 0.01000000000000000020816681711721685132943093776703
Rounded with round, then divided: 0.02000000000000000041633363423443370265886187553406
Note that the value we started with was less than 0.015, and so the mathematically correct answer when rounding it to 2 decimal places is 0.01. Of course, 0.01 is not exactly representable as a double, but we expect our result to be the double nearest to 0.01. Using snprintf
gives us that result, but using round(100 * x) / 100
gives us 0.02, which is wrong. Why? Because 100 * x
gives us exactly 1.5 as the result. Multiplying by 100 thus changes the correct direction to round in.
To illustrate the second kind of error - the result sometimes being wrong due to * 100
and / 100
not truly being inverses of each other - we can do a similar exercise with a very big number:
int main(void) {
double x = 8631192423766613.0;
printf("x: %.1f\n", x);
double res1 = dround(x, 2);
double res2 = round(100 * x) / 100;
printf("Rounded with snprintf: %.1f\n", res1);
printf("Rounded with round, then divided: %.1f\n", res2);
}
Our number now doesn't even have a fractional part; it's an integer value, just stored with type double
. So the result after rounding it should be the same number we started with, right?
If you run the program above, you'll see:
x: 8631192423766613.0
Rounded with snprintf: 8631192423766613.0
Rounded with round, then divided: 8631192423766612.0
Oops. Our snprintf
method returns the right result again, but the multiply-then-round-then-divide approach fails. That's because the mathematically correct value of 8631192423766613.0 * 100
, 863119242376661300.0
, is not exactly representable as a double; the closest value is 863119242376661248.0
. When you divide that back by 100, you get 8631192423766612.0
- a different number to the one you started with.
Hopefully that's a sufficient demonstration that using roundf
for rounding to a number of decimal places is broken, and that you should use snprintf
instead. If that feels like a horrible hack to you, perhaps you'll be reassured by the knowledge that it's basically what CPython does.

- 143,130
- 81
- 406
- 459
-
4+1 for a concrete example of what goes wrong with my answer and those similar to it, thanks to the weirdness of IEEE floating point, and providing a straightforward alternative. I was peripherally aware, quite a long time back, of lot of effort put into print and friends to me them safe for round-tripping floating point values. I would guess that the work done then might be showing up here. – Dale Hagglund Aug 27 '19 at 03:26
-
Ahem... Sorry for the word salad near the end there, which it's now too late to edit. What I meant to say was "... a lot of effort put into printf and friends to make them safe ..." – Dale Hagglund Sep 01 '19 at 00:14
-
1Unfortunately, the result from `snprintf` could be implementation-dependent; `dround(0.125, 2)` may give `0.12` or `0.13`. https://godbolt.org/z/xz4K1P13z – tueda Aug 24 '22 at 13:03
-
@tueda damn, that kinda sucks! So if you want rounding that's both correct for non-ties and consistent across platforms for ties, there's just no convenient way in the C standard library to get that, and you have to roll your own? – Mark Amery Aug 24 '22 at 14:43
-
1I guess that's why people wrote own `dtoa`, for example `_Py_dg_dtoa` in CPython. – tueda Aug 24 '22 at 15:57
Also, if you're using C++, you can just create a function like this:
string prd(const double x, const int decDigits) {
stringstream ss;
ss << fixed;
ss.precision(decDigits); // set # places after decimal
ss << x;
return ss.str();
}
You can then output any double myDouble
with n
places after the decimal point with code such as this:
std::cout << prd(myDouble,n);

- 8,971
- 16
- 71
- 98
There isn't a way to round a float
to another float
because the rounded float
may not be representable (a limitation of floating-point numbers). For instance, say you round 37.777779 to 37.78, but the nearest representable number is 37.781.
However, you can "round" a float
by using a format string function.

- 22,195
- 6
- 45
- 72
-
3This is no different from saying "there's no way to divide two floats and get a float, because the divided result may not be representable," which may be precisely true but is irrelevant. Floats are always inexact, even for something as basic as addition; the assumption is always that what you actually get is "the float that most closely approximates the exact rounded answer". – Brooks Moses Aug 28 '09 at 03:11
-
What I meant is that you cannot round a `float` to n decimal places and then expect the result always have n decimal places. You will still get a `float`, just not the one you expected. – Andrew Keeton Aug 28 '09 at 03:28
-
Your first statement might sound true initially, but many languages do allow you to round one float into another. Consider Python's `round()` function for example: https://www.pythontutorial.net/advanced-python/python-rounding/ It's genuinely surprisingly that something as basic as this was omitted from C++. – Raleigh L. Feb 11 '22 at 21:52
In C++ (or in C with C-style casts), you could create the function:
/* Function to control # of decimal places to be output for x */
double showDecimals(const double& x, const int& numDecimals) {
int y=x;
double z=x-y;
double m=pow(10,numDecimals);
double q=z*m;
double r=round(q);
return static_cast<double>(y)+(1.0/m)*r;
}
Then std::cout << showDecimals(37.777779,2);
would produce: 37.78.
Obviously you don't really need to create all 5 variables in that function, but I leave them there so you can see the logic. There are probably simpler solutions, but this works well for me--especially since it allows me to adjust the number of digits after the decimal place as I need.

- 8,971
- 16
- 71
- 98
You can still use:
float ceilf(float x); // don't forget #include <math.h> and link with -lm.
example:
float valueToRound = 37.777779;
float roundedValue = ceilf(valueToRound * 100) / 100;

- 1,490
- 4
- 19
- 33
-
This truncates at decimal point (i.e. will produce 37), and he needs to round to two places _after_ the decimal point. – Pavel Minaev Aug 27 '09 at 23:23
-
Rounding to two places after the decimal point is a trivial variation, though (but still should be mentioned in the answer; ZeroCool, want to add an edit?): float roundedValue = ceilf(valueToRound * 100.0) / 100.0; – Brooks Moses Aug 28 '09 at 03:07
-
How come this solution isn't more popular? This works exactly how it should with minimal code. Is there some caveat with it? – Andy Dec 03 '13 at 05:35
Use float roundf(float x)
.
"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." C11dr §7.12.9.5
#include <math.h>
// When |x| is less than FLT_MAX/100
float y = roundf(x * 100.0f) / 100.0f;
Depending on your float
implementation, numbers that may appear to be half-way are not. Floating-point is typically base-2 oriented. Further, precisely rounding to the nearest 0.01
on all "half-way" cases is most challenging.
void r100(const char *s) {
float x, y;
sscanf(s, "%f", &x);
y = round(x*100.0)/100.0;
printf("%6s %.12e %.12e\n", s, x, y);
}
int main(void) {
r100("1.115");
r100("1.125");
r100("1.135");
return 0;
}
1.115 1.115000009537e+00 1.120000004768e+00
1.125 1.125000000000e+00 1.129999995232e+00
1.135 1.134999990463e+00 1.139999985695e+00
Although "1.115" is "half-way" between 1.11 and 1.12, when converted to float
, the value is 1.115000009537...
and is no longer "half-way", but closer to 1.12 and rounds to the closest float
of 1.120000004768...
"1.125" is "half-way" between 1.12 and 1.13, when converted to float
, the value is exactly 1.125
and is "half-way". It rounds toward 1.13 due to ties to even rule and rounds to the closest float
of 1.129999995232...
Although "1.135" is "half-way" between 1.13 and 1.14, when converted to float
, the value is 1.134999990463...
and is no longer "half-way", but closer to 1.13 and rounds to the closest float
of 1.129999995232...
If code used
y = roundf(x*100.0f)/100.0f;
Although "1.135" is "half-way" between 1.13 and 1.14, when converted to float
, the value is 1.134999990463...
and is no longer "half-way", but closer to 1.13 but incorrectly rounds to float
of 1.139999985695...
due to the more limited precision of float
vs. double
. This incorrect value may be viewed as correct, depending on coding goals.

- 143,097
- 13
- 135
- 256
Code definition :
#define roundz(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))
Results :
a = 8.000000
sqrt(a) = r = 2.828427
roundz(r,2) = 2.830000
roundz(r,3) = 2.828000
roundz(r,5) = 2.828430

- 49
- 1
double f_round(double dval, int n)
{
char l_fmtp[32], l_buf[64];
char *p_str;
sprintf (l_fmtp, "%%.%df", n);
if (dval>=0)
sprintf (l_buf, l_fmtp, dval);
else
sprintf (l_buf, l_fmtp, dval);
return ((double)strtod(l_buf, &p_str));
}
Here n
is the number of decimals
example:
double d = 100.23456;
printf("%f", f_round(d, 4));// result: 100.2346
printf("%f", f_round(d, 2));// result: 100.23

- 14,324
- 7
- 55
- 77

- 47
- 3
-
-1 for four reasons: 1) the lack of explanation, 2) the vulnerability to buffer overflow - this will overflow, and therefore quite possibly crash, if `dval` is huge 3) the weird `if` / `else` block where you do exactly the same thing in each branch, and 4) the overcomplicated use of `sprintf` to build the format specifier for a second `sprintf` call; it's simpler to just use `.*` and pass the double value and number of decimal places as arguments to the same `sprintf` call. – Mark Amery Aug 25 '19 at 15:55
I made this macro for rounding float numbers. Add it in your header / being of file
#define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))
Here is an example:
float x = ROUNDF(3.141592, 100)
x equals 3.14 :)

- 17,769
- 16
- 66
- 164

- 1,079
- 13
- 26
-
1This truncates, but the question requests rounding. Additionally, it is subject to rounding errors in floating-point operations. – Eric Postpischil Dec 01 '18 at 21:07
Let me first attempt to justify my reason for adding yet another answer to this question. In an ideal world, rounding is not really a big deal. However, in real systems, you may need to contend with several issues that can result in rounding that may not be what you expect. For example, you may be performing financial calculations where final results are rounded and displayed to users as 2 decimal places; these same values are stored with fixed precision in a database that may include more than 2 decimal places (for various reasons; there is no optimal number of places to keep...depends on specific situations each system must support, e.g. tiny items whose prices are fractions of a penny per unit); and, floating point computations performed on values where the results are plus/minus epsilon. I have been confronting these issues and evolving my own strategy over the years. I won't claim that I have faced every scenario or have the best answer, but below is an example of my approach so far that overcomes these issues:
Suppose 6 decimal places is regarded as sufficient precision for calculations on floats/doubles (an arbitrary decision for the specific application), using the following rounding function/method:
double Round(double x, int p)
{
if (x != 0.0) {
return ((floor((fabs(x)*pow(double(10.0),p))+0.5))/pow(double(10.0),p))*(x/fabs(x));
} else {
return 0.0;
}
}
Rounding to 2 decimal places for presentation of a result can be performed as:
double val;
// ...perform calculations on val
String(Round(Round(Round(val,8),6),2));
For val = 6.825
, result is 6.83
as expected.
For val = 6.824999
, result is 6.82
. Here the assumption is that the calculation resulted in exactly 6.824999
and the 7th decimal place is zero.
For val = 6.8249999
, result is 6.83
. The 7th decimal place being 9
in this case causes the Round(val,6)
function to give the expected result. For this case, there could be any number of trailing 9
s.
For val = 6.824999499999
, result is 6.83
. Rounding to the 8th decimal place as a first step, i.e. Round(val,8)
, takes care of the one nasty case whereby a calculated floating point result calculates to 6.8249995
, but is internally represented as 6.824999499999...
.
Finally, the example from the question...val = 37.777779
results in 37.78
.
This approach could be further generalized as:
double val;
// ...perform calculations on val
String(Round(Round(Round(val,N+2),N),2));
where N is precision to be maintained for all intermediate calculations on floats/doubles. This works on negative values as well. I do not know if this approach is mathematically correct for all possibilities.

- 650
- 1
- 12
- 18
...or you can do it the old-fashioned way without any libraries:
float a = 37.777779;
int b = a; // b = 37
float c = a - b; // c = 0.777779
c *= 100; // c = 77.777863
int d = c; // d = 77;
a = b + d / (float)100; // a = 37.770000;
That of course if you want to remove the extra information from the number.

- 125
- 10
-
Fails when `a` well outside `int` range. Fails when `c *= 100` incurs rounding in select cases. – chux - Reinstate Monica Aug 22 '23 at 17:06
this function takes the number and precision and returns the rounded off number
float roundoff(float num,int precision)
{
int temp=(int )(num*pow(10,precision));
int num1=num*pow(10,precision+1);
temp*=10;
temp+=5;
if(num1>=temp)
num1+=10;
num1/=10;
num1*=10;
num=num1/pow(10,precision+1);
return num;
}
it converts the floating point number into int by left shifting the point and checking for the greater than five condition.

- 625
- 12
- 20