You could re-invent the wheel, as many other answers suggest. Alternately, you could use someone else's wheel -- I'd suggest Newlib's, which is BSD-licensed and intended for use on embedded systems. It properly handles negative numbers, NaNs, infinities, and cases which are not representable as integers (due to being too large), as well as doing so in an efficient manner that uses exponents and masking rather than generally-costlier floating-point operations. In addition, it's regularly tested, so you know it doesn't have glaring corner-case bugs in it.

The Newlib source can be a bit awkward to navigate, so here are the bits you want:

Float version: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/sf_round.c;hb=master

Double version: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/s_round.c;hb=master

Word-extraction macros defined here: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/fdlibm.h;hb=master

If you need other files from there, the parent directory is this one: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=tree;f=newlib/libm/common;hb=master

For the record, here's the code for the float version. As you can see, there's a bit of complexity required to deal with all the possible cases correctly.

float roundf(x)
{
  int signbit;
  __uint32_t w;
  /* Most significant word, least significant word. */
  int exponent_less_127;

  GET_FLOAT_WORD(w, x);

  /* Extract sign bit. */
  signbit = w & 0x80000000;

  /* Extract exponent field. */
  exponent_less_127 = (int)((w & 0x7f800000) >> 23) - 127;

  if (exponent_less_127 < 23)
    {
      if (exponent_less_127 < 0)
        {
          w &= 0x80000000;
          if (exponent_less_127 == -1)
            /* Result is +1.0 or -1.0. */
            w |= ((__uint32_t)127 << 23);
        }
      else
        {
          unsigned int exponent_mask = 0x007fffff >> exponent_less_127;
          if ((w & exponent_mask) == 0)
            /* x has an integral value. */
            return x;

          w += 0x00400000 >> exponent_less_127;
          w &= ~exponent_mask;
        }
    }
  else
    {
      if (exponent_less_127 == 128)
        /* x is NaN or infinite. */
        return x + x;
      else
        return x;
    }
  SET_FLOAT_WORD(x, w);
  return x;
}
Answer from Brooks Moses on Stack Overflow
Top answer
1 of 10
23

You could re-invent the wheel, as many other answers suggest. Alternately, you could use someone else's wheel -- I'd suggest Newlib's, which is BSD-licensed and intended for use on embedded systems. It properly handles negative numbers, NaNs, infinities, and cases which are not representable as integers (due to being too large), as well as doing so in an efficient manner that uses exponents and masking rather than generally-costlier floating-point operations. In addition, it's regularly tested, so you know it doesn't have glaring corner-case bugs in it.

The Newlib source can be a bit awkward to navigate, so here are the bits you want:

Float version: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/sf_round.c;hb=master

Double version: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/s_round.c;hb=master

Word-extraction macros defined here: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libm/common/fdlibm.h;hb=master

If you need other files from there, the parent directory is this one: https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=tree;f=newlib/libm/common;hb=master

For the record, here's the code for the float version. As you can see, there's a bit of complexity required to deal with all the possible cases correctly.

float roundf(x)
{
  int signbit;
  __uint32_t w;
  /* Most significant word, least significant word. */
  int exponent_less_127;

  GET_FLOAT_WORD(w, x);

  /* Extract sign bit. */
  signbit = w & 0x80000000;

  /* Extract exponent field. */
  exponent_less_127 = (int)((w & 0x7f800000) >> 23) - 127;

  if (exponent_less_127 < 23)
    {
      if (exponent_less_127 < 0)
        {
          w &= 0x80000000;
          if (exponent_less_127 == -1)
            /* Result is +1.0 or -1.0. */
            w |= ((__uint32_t)127 << 23);
        }
      else
        {
          unsigned int exponent_mask = 0x007fffff >> exponent_less_127;
          if ((w & exponent_mask) == 0)
            /* x has an integral value. */
            return x;

          w += 0x00400000 >> exponent_less_127;
          w &= ~exponent_mask;
        }
    }
  else
    {
      if (exponent_less_127 == 128)
        /* x is NaN or infinite. */
        return x + x;
      else
        return x;
    }
  SET_FLOAT_WORD(x, w);
  return x;
}
2 of 10
22
int round(double x)
{
    if (x < 0.0)
        return (int)(x - 0.5);
    else
        return (int)(x + 0.5);
}
🌐
Reddit
reddit.com › r/c_programming › rounding in c
r/C_Programming on Reddit: Rounding in C
May 8, 2024 -

I have a question when it comes to rounding in C. Does it round up or down at .5? If it does round up, then does that mean that the smallest value of k in the code below can only be 1?

 int main()
{
    int k = 13;
    int i;
    for (i = 0; i < 8; i++) {
        printf("%d", (k%2));
        k >>= 1;
    }
    printf("%n");
}

Discussions

rounding - How to round floating point numbers to the nearest integer in C? - Stack Overflow
The nearbyint functions round their argument to an integer value in floating-point format, using the current rounding direction and without raising the ‘‘inexact’’ floating point exception. More on stackoverflow.com
🌐 stackoverflow.com
Rounding ints without round()
round is a standard C function. You're allowed to use it. More on reddit.com
🌐 r/cs50
3
2
October 4, 2023
microcontroller - Round off Float value in C without in-built functions - Stack Overflow
I am writing a code for PIC microcontroller in C language. I have a float value of more than 4 decimal places. I want to round it to 1 decimal place. But the issue is, I can't use the round,floor,... More on stackoverflow.com
🌐 stackoverflow.com
Rounding in C
Have you considered simply trying the code out? More on reddit.com
🌐 r/C_Programming
37
0
May 8, 2024
🌐
W3Schools
w3schools.com › c › ref_math_round.php
C Math round() Function
C Examples C Real-Life Examples C Exercises C Quiz C Code Challenges C Compiler C Syllabus C Study Plan C Interview Q&A C Certificate ... printf("%f", round(0.60)); printf("%f", round(0.40)); printf("%f", round(5)); printf("%f", round(5.1)); printf("%f", round(-5.1)); printf("%f", round(-5.9)); Try it Yourself » · The round() function rounds a number to the nearest integer.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › round-function-in-c
round() Function in C - GeeksforGeeks
July 5, 2024 - C round() is a built-in library function that rounds a floating-point number to the nearest integer. If the fractional part of the number is 0.5 or greater, the argument is rounded away from zero. If the fractional part is less than 0.5, the argument is rounded towards zero.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 98999-rounding-c.html
Rounding in C
February 12, 2008 - What you could do is just print the number into a string, then search along for the '.' and look at the number after the '.' Then make the dot a Null (zero) and read the string back into an integerthen increase that number if necessary. Might not be to everyones liking as the best way to do ...
Find elsewhere
🌐
Scaler
scaler.com › home › topics › c round() function
C round() Function - Scaler Topics
March 27, 2024 - The round() function in C returns the nearest integer value (rounded off value) of the number provided as an argument which can be of type float, integer, or double number provided as an argument. If the decimal value of the number provided is less than or equal to 0.5, then the value returned will be the integer smaller than the number provided in the argument, and if the decimal value of the number provided is greater than 0.5, then the value returned will be the integer greater than the number provided in the argument.
Top answer
1 of 11
17

To round a float in C, there are 3 <math.h> functions to meet the need. Recommend rintf().

float nearbyintf(float x);

The nearbyint functions round their argument to an integer value in floating-point format, using the current rounding direction and without raising the ‘‘inexact’’ floating point exception. C11dr §7.12.9.3 2

or

float rintf(float x);

The rint functions differ from the nearbyint functions (7.12.9.3) only in that the rint functions may raise the ‘‘inexact’’ floating-point exception if the result differs in value from the argument. C11dr §7.12.9.4 2

or

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.6 2


Example

#include <fenv.h>
#include <math.h>
#include <stdio.h>

void rtest(const char *fname, double (*f)(double x), double x) {
  printf("Clear inexact flag       :%s\n", feclearexcept(FE_INEXACT) ? "Fail" : "Success");
  printf("Set round to nearest mode:%s\n", fesetround(FE_TONEAREST)  ? "Fail" : "Success");

  double y = (*f)(x);
  printf("%s(%f) -->  %f\n", fname,x,y);

  printf("Inexact flag             :%s\n", fetestexcept(FE_INEXACT) ? "Inexact" : "Exact");
  puts("");
}

int main(void) {
  double x = 8.5;
  rtest("nearbyint", nearbyint, x);
  rtest("rint", rint, x);
  rtest("round", round, x);
  return 0;
}

Output

Clear inexact flag       :Success
Set round to nearest mode:Success
nearbyint(8.500000) -->  8.000000
Inexact flag             :Exact

Clear inexact flag       :Success
Set round to nearest mode:Success
rint(8.500000) -->  8.000000
Inexact flag             :Inexact

Clear inexact flag       :Success
Set round to nearest mode:Success
round(8.500000) -->  9.000000
Inexact flag             :Exact

What is weak about OP's code?

(int)(num < 0 ? (num - 0.5) : (num + 0.5))
  1. Should num have a value not near the int range, the cast (int) results in undefined behavior.

  2. When num +/- 0.5 results in an inexact answer. This is unlikely here as 0.5 is a double causing the addition to occur at a higher precision than float. When num and 0.5 have the same precision, adding 0.5 to a number may result in numerical rounded answer. (This is not the whole number rounding of OP's post.) Example: the number just less than 0.5 should round to 0 per OP's goal, yet num + 0.5 results in an exact answer between 1.0 and the smallest double just less than 1.0. Since the exact answer is not representable, that sum rounds, typically to 1.0 leading to an incorrect answer. A similar situation occurs with large numbers.


OP's dilemma about "The above line always prints the value as 4 even when float num =4.9." is not explainable as stated. Additional code/information is needed. I suspect OP may have used int num = 4.9;.


// avoid all library calls
// Relies on UINTMAX_MAX >= FLT_MAX_CONTINUOUS_INTEGER - 1
float my_roundf(float x) {
  // Test for large values of x 
  // All of the x values are whole numbers and need no rounding
  #define FLT_MAX_CONTINUOUS_INTEGER  (FLT_RADIX/FLT_EPSILON)
  if (x >= FLT_MAX_CONTINUOUS_INTEGER) return x;
  if (x <= -FLT_MAX_CONTINUOUS_INTEGER) return x;

  // Positive numbers
  // Important: _no_ precision lost in the subtraction
  // This is the key improvement over OP's method
  if (x > 0) {
    float floor_x = (float)(uintmax_t) x;
    if (x - floor_x >= 0.5) floor_x += 1.0f;
    return floor_x;
  }

  if (x < 0) return -my_roundf(-x);
  return x; //  x is 0.0, -0.0 or NaN
}

Tested little - will do so later when I have time.

2 of 11
16

4.9 + 0.5 is 5.4, which cannot possibly round to 4 unless your compiler is seriously broken.

I just confirmed that the Googled code gives the correct answer for 4.9.

marcelo@macbookpro-1:~$ cat round.c 
#include <stdio.h>

int main() {
    float num = 4.9;
    int n = (int)(num < 0 ? (num - 0.5) : (num + 0.5));
    printf("%d\n", n);
}
marcelo@macbookpro-1:~$ make round && ./round
cc     round.c   -o round
5
marcelo@macbookpro-1:~$
🌐
O'Reilly
oreilly.com › library › view › c-in-a › 0596006977 › re199.html
round C99 - C in a Nutshell [Book]
December 16, 2005 - The Results of Arithmetic Type ... types4.1.5.4. Conversions to real floating-point types4.1.5.5. Conversions to complex floating-point types4.2. Conversion of Nonarithmetic Types4.2.1. Array and Function Designators4.2.2....
Authors   Peter PrinzTony Crawford
Published   2005
Pages   618
🌐
Quora
quora.com › How-do-I-round-off-in-C
How to round off in C - Quora
Answer (1 of 4): Then the number must be bigger than 7.000000 if ceil is returning 8, maybe just by a little bit. You can use the following decimal truncating technique to discard the least significant decimals (in your case 6 places): [code]double a = 7.0000001 double b = floor(1E6 * a)/1E6; ...
🌐
GeeksforGeeks
geeksforgeeks.org › c language › write-a-c-function-to-round-floating-point-numbers
Write a one line C function to round floating point numbers - GeeksforGeeks
June 2, 2017 - /* Program for rounding floating point numbers */ # include<stdio.h> int roundNo(float num) { return num < 0 ? num - 0.5 : num + 0.5; } int main() { printf("%d", roundNo(-1.777)); getchar(); return 0; } Output: -2 Time complexity: O(1) Space complexity: O(1) Now try rounding for a given precision. i.e., if given precision is 2 then function should return 1.63 for 1.63322 and -1.63 for 1.6332. ... Help us improve. Share your suggestions to enhance the article.
🌐
Reddit
reddit.com › r/cs50 › rounding ints without round()
r/cs50 on Reddit: Rounding ints without round()
October 4, 2023 -

Hey! First of all I know a bit about programming I started CS50x to extend my knowledge at lower level CS. When I approach labs and psets I always try to only use knowledge that was passed through the lecture by David.

When I started week 4 - filter (more) pset I had huge problem rounding RGB values of pixels, I had it off by 1 in a lot of cases and I knew it is rounding problem. I found round() function in math.h library but not sure if it was ever mentioned and if I'm using it I'm not cheating because in a lot of cases I could find a lot of helpful libraries but I always try to use default ones provided in .c files.

🌐
Fresh2Refresh
fresh2refresh.com › home › c programming tutorial › c – arithmetic functions › c – round() function
C round() function | C Arithmetic functions | Fresh2Refresh
September 23, 2020 - double round (double a); float roundf (float a); long double roundl (long double a); ... “math.h” and “stdlib.h” header files support all the arithmetic functions in C language. All the arithmetic functions used in C language are given below. Click on each function name below for detail ...
🌐
NAO IT Systems LLC.
digibeatrix.com › home › standard library functions › how to round numbers in c: practical methods, examples, and best practices
How to Round Numbers in C: Practical Methods, Examples, and Best Practices - C Programming for System Development
July 29, 2018 - In this code, 2.3 is added to 0.5 to become 2.8, which is then cast to an int, resulting in 2. By adding 0.5, you can perform rounding properly. This technique is useful as an alternative to the round() function.
Top answer
1 of 2
2

The usual solution on microcontrollers is to not do this. Decimal places are for humans, and that sort of luxury doesn't belong on embedded hardware. Heck, even binary floating point is a bit of a luxury.

The only place where you might see decimal math is in I/O operations. For those cases, it's easiest to internally work with an integer. So the range 0.0 - 6553.5 is internally represented as 0-65535. On output, you just print value/10 . value%10.

2 of 2
2

The standard way to do this is to scale, add 0.5, truncate, and un-scale:

float x;

...

x *= 10;
x = (int)(x + 0.5);
x /= 10;

Or, in one line:

x = (int)(x * 10 + 0.5) / 10.;

By adding 0.5 before truncating to int, you arrange that numbers with a fractional part greater than 0.5 round up.

But there are two other points to consider:

  1. This simple, basic rounding recipe will not handle negative numbers correctly.

  2. Floating-point numbers on most computers can't represent decimal fractions exactly. So you haven't really rounded x to "one place past the decimal". If you print x out later, you'll often find that it seems to contain a number like, say, 3.199999 instead of 3.2. There's nothing you can do about this; the usual solution is to use a printf format like %.1f when it comes time to print the number out. And once you're using a printf format like %.1f, it'll do all the rounding for you, so you don't have to.

So the question is, what are you actually doing with your floating-point numbers that they have to be rounded to "one place past the decimal"? Are you printing them out as a string, or doing something else with them? And if you're printing them out, are you using printf or something else?

🌐
OpenGenus
iq.opengenus.org › rounding-and-truncating-numbers-in-c
Rounding and Truncating numbers using math.h in C
April 5, 2025 - In this article, we have explored how we can round and truncate numbers in C using the math.h library. math.h is a header file in the list of standard C libraries which enables the coder to perform some basic mathematical operations and transformations. The header file contains many functions among ...
🌐
22web
randy.22web.org › classes › cop2000.c › rounding.html
How to Round a Number in a C Program
March 1, 2005 - This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support
🌐
Cppreference
en.cppreference.com › w › c › numeric › math › round
round, roundf, roundl, lround, lroundf, lroundl, llround, llroundf, llroundl - cppreference.com
May 23, 2024 - 4,8,12) Type-generic macros: If arg has type long double, roundl, lroundl, llroundl is called. Otherwise, if arg has integer type or the type double, round, lround, llround is called. Otherwise, roundf, lroundf, llroundf is called, respectively. If no errors occur, the nearest integer value to arg, rounding halfway cases away from zero, is returned.