Proper rounding with

Rounding Numbers

Rounding numbers is rudimentary math, often times we do it in our head without even realizing we’ve done it.

This can lead to some interesting results when we’re writing code and haven’t taken the effect of rounding (re: precision) into account. Rounding a number is more than just lopping off the decimals and using the resulting whole number (This in effect, is what we do when we cast a double to an int).

C and C++ (via math.h and cmath headers, respectively) afford us a number of facilities for rounding numbers.

To demonstrate the different methods of converting real numbers to whole numbers with varying levels of precision we will use the following two values:

const double PI = 3.14159;
const double notPI = 3.773;

The only reasoning behind choosing these two values is that when using the rules for rounding they produce different whole numbers. PI rounds to three while notPI rounds to four.

“Rounding” via cast

I put Rounding in quotes here because this method isn’t rounding at all, its more akin to castration: we’re giving the decimals the chop. While it will give us the desired result of turning a real number into a whole number, depending on our required level of precision it is liable to return the WRONG whole number.

to demonstrate the issue we will be using the following function:

void cast2int(double n) 
{ 
   int res = (int)n; 
   cout<<"\"Rounding\" via cast: "<<res<<"\n"; 
}

When fed our two sample values, we get the following result:

cast2int(PI); 
"Rounded" by cast to int(): 3 

cast2int(notPI); 
"Rounded" by cast to int(): 3

Clearly, this is not doing what we intented, which is rounding the number to the nearest whole number. its just converting it to its natural whole number.

Of course, we can do better.

Rounding with round()

Rounding to the nearest whole number is achieved with the appropriately named round(). It’s worth noting that the default type returned by round() is double, and while you can return without cast to an int type, proper type conversion dictates the use of a cast.

void using_round(double n)
{
    double res = round(n);
    cout<<"Rounded via round(): "<<res<<"\n";
} 
using_round(PI); 
Rounded via round(): 3 

using_round(notPI); 
Rounded via round(): 4

As you can see the numbers are now rounded properly as we expected.

But there are times when we want to forgo the rules of natural rounding and force a number that would normaly round up to round down, and force a number that would normally round down to round up…

enter floor() and ceil()

Rounding with floor() and ceil()

The oddly named floor() and ceil() have a humorous origin. floor() forces a number to round down to the nearest number (towards the floor…) while ceil() forces a number to round up to the nearest whole number (towards the ceiling…)

Who said programmers are without a sense of humor? Oy…

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *