Rounding in C

  • #1
Hey everyone,

I'm writing a simple program to calculate the monthly payment amount for a loan given a principal, down payment, finance term, and interest rate. The monthly payment needs to be reported to the user rounded to two decimal places after they have entered all the required information. The assignment instructions specify that the monthly payment should be rounded to two decimal places, not truncated, floored, ceiled (?), etc.

To accomplish this, I have used the conversion specification in the printf statement to specify that the monthly payment should be printed to two decimal places:

"printf("The monthly payment amount is: %.2lf", downPayment);"

Does this method round properly, or does it just truncate? Will it produce the same results as multiplying the monthly payment by 100, using the round function from math.h to round the result, and then dividing by 100?

Thanks!
 

Answers and Replies

  • #2
34,901
6,645
What you show doesn't do any rounding. It's just truncating the result after the 2nd decimal place. So no, it doesn't produce the same results as actual rounding.
 
  • #3
rcgldr
Homework Helper
8,749
553
Depending on the compiler, printf output will generally round floating point numbers, but I don't think there's any rule in C / C++ that requires rounding. Microsoft compilers will round with printf.
 
  • #4
D H
Staff Emeritus
Science Advisor
Insights Author
15,393
686
Depending on the compiler, printf output will generally round floating point numbers, but I don't think there's any rule in C / C++ that requires rounding. Microsoft compilers will round with printf.
The standards are fairly tight with respect to rounding.

However, there is an issue here. If your computer is using the IEEE floating point standard (almost every computer nowadays), a floating point number doesn't represent just one number. It instead represents a range of numbers. Every number in that range will have the same IEEE representation. Consider the two numbers 19810222/219 + 21474836/247 and 37785/1000. These two numbers have the same representation in the IEEE double precision format. The first number is "exact"; it's IEEE representation is exactly equal to the 19810222/219 + 21474836/247. The latter number, 37785/1000 (or 37.785), is not an exact number.

Consider the following C code:
Code:
#include <stdio.h>
int main () {
   double x1, x2;
   long int two_pow19 = 1L << 19;
   long int two_pow47 = 1L << 47;

   x1 =  37785.0 / 1000.0;
   printf ("37.785 rounded = %.2f\n", x1);

   x2 = 19810222.0/two_pow19 + 21474836.0/two_pow47;
   printf ("19810222/2^19 + 21474836/t2^47 rounded = %.2f\n", x2);

   printf ("x1-x2 = %.15g\n", x1-x2);

   printf ("x1*2^47 = %.2f\n", x1*two_pow47);

   return 0;
}

Even if you are of the opinion that 37.785 should be rounded to 37.79 (opinions do vary, and so do different versions of the C library), most computers will print 37.785 as 37.78. That's because the exact number in the range of numbers that have the same representation is 19810222/219 + 21474836/247, or approximately 37.7849999999999966. Assuming you are using the default rounding mode, that number should be rounded down to 37.78. So it is -- even if you meant 37.785 and even if you want those corner cases to be rounded up.

Now consider the following Excel formulae in two cells:
Code:
=ROUND(37785/1000,2)
=ROUND(19810222/2^19+21474836/2^47,2)

Excel will display 37.79 as the value of both cells. Excel looks to see whether the range of numbers represented by some IEEE representation contains the corner case, in this case 37.785. That corner case rounds up per Excel's rounding rules, so 37.785 is rounded up to 37.79, but so is 37.7849999999999966.
 
  • #5
1,065
54
yeah, I thought that was always the case...%W.df rounds to d decimal places...that's what I have always assume in tcl, C, fortran, python, java...
 
  • #6
If you want to round to 2 decimal places, you can add .005 then truncate it. You should be able to generalize it to what ever precision you want.
 
  • #7
22
0
e.g:- rounding of 10.457 to the nearest 2 decimal places

(integer(10.457*100+0.5))/100 = 1046/100 = 10.46

for 3 decimal places *1000 and then /1000
 
Last edited:
  • #8
D H
Staff Emeritus
Science Advisor
Insights Author
15,393
686
Do that with my example of 37.785.

Addendum
Or, for that matter, if your computer is as goofy as mine (and it almost certainly is), try 0.145, 0.285, 0.565, and 0.575. The next problem child doesn't occur until after 1. In the 1s, you have 1.005, 1.015, 1.025, 1.035, 1.125, 1.135, 1.145, 1.155, 1.255, 1.265, and 1.275. And so on.

Rounding isn't quit as simple as multiplying by 10n, adding 1/2, casting to an integer, and dividing by 10n. At least not if you want to do it right.
 
Last edited:

Related Threads on Rounding in C

Replies
1
Views
1K
Replies
12
Views
2K
Replies
2
Views
651
  • Last Post
Replies
7
Views
2K
Replies
4
Views
4K
  • Last Post
Replies
7
Views
73K
  • Last Post
Replies
3
Views
8K
Replies
10
Views
2K
  • Last Post
Replies
3
Views
2K
Top