Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Rounding in C

  1. Sep 19, 2012 #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!
     
  2. jcsd
  3. Sep 19, 2012 #2

    Mark44

    Staff: Mentor

    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.
     
  4. Sep 19, 2012 #3

    rcgldr

    User Avatar
    Homework Helper

    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.
     
  5. Sep 19, 2012 #4

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    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 (Text):

    #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 (Text):

    =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.
     
  6. Sep 19, 2012 #5
    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...
     
  7. Sep 20, 2012 #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.
     
  8. Sep 25, 2012 #7
    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: Sep 25, 2012
  9. Sep 25, 2012 #8

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    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: Sep 25, 2012
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Rounding in C
  1. To C or not to C (Replies: 31)

  2. C or C++? (Replies: 8)

Loading...