Pages

Wednesday, 27 November 2013

Creative rounding in C/C++


If you are coding in C/C++ for rounding you are probably using  round(),  which is part of the C99, but did you think about another solutions, for example if the compiler doesn't support C99, or you just want to do something "cool"?

At the beginning I would like to give you a piece of code:

 int roundedResult, sum = 5, div = 3; 
 roundedResult = (float) sum / (float) div + 0.5;
 cout<<roundedResult;
output: 2
(5/3 = 1.666..)

 int roundedResult, sum = 5, div = 4; 
 roundedResult = (float) sum / (float) div + 0.5;  
 cout<<roundedResult;
output: 1
(5/4 = 1.25) 

You could notice that + 0.5 at the end and probably think that it may be somehow connected with rounding... If yes, then you are right! In first example when we add 0.5 to the result (1.66..) we got ~2.16. As roundedResult is integer type it just cuts the rest after dot.
In second example result after adding 0.5 is 1.75 and again when we cut 0.75 we got correctly rounded number.

Here is a ready function for rounding this way
 int roundNumber(float number)
 { 
   int rounded = (int)(number + 0.5); 
// in C++ recommended to use static_cast instead of (int) 
   return rounded; 
 } 
but you could notice that the problem appears when we want to round minus number. -2.6 will become -2, what is incorrect. Fortunately there is a simple solution:
 int roundNumber(float number)
 { 
  int rounded = (int)(number > 0) ? (number + 0.5) : (number - 0.5);
// in C++ recommended to use static_cast instead of(int)
   return rounded; 
 } 
Thanks to this for minus numbers we subtract 0.5 instead of adding, after that from -2.6  we will get -3,1, which is being cut to 3 - correct!

Tip for C++ coders: For small functions use:
inline int roundNumber(float number)
thanks to inline keyword compiler will put function code into place where you called it, instead of putting on stack etc. It makes program faster, but be careful! If you use inline for big functions it will drastically increase output file size, so use it wisely.


No comments:

Post a Comment