Calculating Loan Payments: Rounding Correctly?

  • Thread starter Thread starter newageanubis
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around the proper method for rounding monthly loan payment calculations in programming, specifically in the context of using the printf function in C/C++. Participants explore various approaches to rounding, the implications of floating-point representation, and the differences in behavior across different programming environments.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant questions whether the printf method for displaying the monthly payment rounds correctly or simply truncates the result.
  • Another participant asserts that the printf function does not perform rounding but truncates after the second decimal place.
  • Some participants note that behavior may vary depending on the compiler, with Microsoft compilers reportedly rounding correctly with printf.
  • A detailed example is provided illustrating how floating-point representation can affect rounding outcomes, particularly with specific values that may lead to unexpected results.
  • One participant suggests a method of rounding by adding 0.005 before truncating, proposing a generalizable approach for different decimal precisions.
  • Another participant provides a mathematical example to demonstrate their proposed rounding method, emphasizing the complexity of rounding in programming.
  • Concerns are raised about the reliability of rounding methods across different programming languages and environments, with references to Excel's rounding behavior as a contrasting example.

Areas of Agreement / Disagreement

Participants express differing views on whether the printf function rounds or truncates, and there is no consensus on the best method for rounding in programming. The discussion remains unresolved regarding the implications of floating-point representation on rounding accuracy.

Contextual Notes

Participants highlight limitations related to floating-point representation and the potential for different rounding behaviors across programming environments, which may affect the outcomes of rounding operations.

newageanubis
Messages
15
Reaction score
0
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!
 
Technology news on Phys.org
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.
 
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.
 
rcgldr said:
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.
 
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...
 
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.
 
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:
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:

Similar threads

  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 1 ·
Replies
1
Views
3K
Replies
14
Views
7K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
6K
Replies
12
Views
4K
  • · Replies 9 ·
Replies
9
Views
11K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 12 ·
Replies
12
Views
5K
  • · Replies 2 ·
Replies
2
Views
6K