Thread: Optimizing a simple program

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    42

    Question Optimizing a simple program

    Code:
    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
    int main(void)
    {
        float totalPaid=0.0, r=0.22, B=5000.0, P=0.0, firstMonth = 0.0, nthMonth = 0.0, n=1.0;
        printf("\nEnter your monthly payment: $");
        scanf("%f", &P);
        printf("\nAnnual Interest Rate (r) = %-5.2f%%\nAmount Borrowed (B) = $%-6.2f\nPayment Amount (P) = $%-6.2f\n", r*100, B, P);
        firstMonth = (r/12)*(B);
        totalPaid = totalPaid + firstMonth;
        printf("\n%-2.0f %-5.2f %-6.2f \n", n, firstMonth, B);
        nthMonth=firstMonth; 
        while(1){
            n=n+1;
            B = (B-(P-nthMonth));
            if (n>2) {
                totalPaid = totalPaid + nthMonth;
                if (B < 0) { break; } }
            else if(n<=2) {
                if (B < 0) { break; } }
            nthMonth = (r/12)*(B);
            printf("%-2.0f %-5.2f %-6.2f \n", n, nthMonth, B); }
        printf("\nTotal interest paid: $%-6.2f\n", totalPaid);
            exit(0);        
    }
    I already got the code to do exactly what it's needed to do, the only thing that is bothering me is my professor said that this should be a 10-15 line program and mine is double that. Are there any glaringly obvious ways that I can simplify this (while keeping the output the exact same)? I got it down to the point where I don't see anything more that I can optimize.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Paul Omans
    my professor said that this should be a 10-15 line program and mine is double that.
    Don't worry too much about the number of lines. It should be just a guide. For example, you can combine two of your printf calls by a little re-ordering, but as-is they are fine.

    That said, I would write your while loop like this:
    Code:
    while (1) {
        ++n;
        B -= P - nthMonth;
        if (n > 2) {
            totalPaid += nthMonth;
            if (B < 0) {
                break;
            }
        }
        else if(n <= 2) {
            if (B < 0) {
                break;
            }
        }
        nthMonth = (r / 12) * B;
        printf("%-2.0f %-5.2f %-6.2f \n", n, nthMonth, B);
    }
    Notice that I place the closing braces on their own lines, got rid of the really superfluous parentheses, and made use of the assignment operator forms where applicable.

    Next, this part:
    Code:
        if (n > 2) {
            totalPaid += nthMonth;
            if (B < 0) {
                break;
            }
        }
        else if(n <= 2) {
            if (B < 0) {
                break;
            }
        }
    can be simplified to:
    Code:
        if (n > 2) {
            totalPaid += nthMonth;
        }
        if (B < 0) {
            break;
        }
    Besides this, I notice that you don't use anything from <math.h>, so you should remove that header inclusion. Also, there is no need for the call to exit as the program will exit right after that line. If you do want to be explicit, return 0; instead. Of course, once you get rid of the exit call, you can also get rid of the inclusion of <stdlib.h>.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Maz's Avatar
    Join Date
    Nov 2005
    Location
    Finland
    Posts
    194
    And using for instead while would combine 3 lines in a natural way.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Can you use the I = P r t formula instead? The only variable missing from your current program are the terms, or the length of the loan. More useful than the monthly payment, here, would be the terms. You can derive the monthly payments from yearly interest.

  5. #5
    Registered User ApolCor's Avatar
    Join Date
    Apr 2013
    Location
    Philippines
    Posts
    2
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    int main(void)
    {
      float totalPaid=0.0, r=0.22, B=5000.0, P=0.0, nthMonth = 0.0, n=0.0;
      printf("\nEnter your monthly payment: $");
      scanf("%f", &P);
      printf("\nAnnual Interest Rate (r) = %-5.2f%%\nAmount Borrowed (B) = $%-6.2f\nPayment Amount (P) = $%-6.2f\n\n", r*100, B, P);
      while (B>0)
      {
        n++;
        nthMonth = r/12 * B;
        totalPaid = totalPaid + nthMonth;
        printf("%-2.0f %-5.2f %-6.2f \n", n, nthMonth, B);
        B = B - P + nthMonth;
      }
      printf("\nTotal interest paid: $%-6.2f\n", totalPaid);
      exit(0);       
    }

  6. #6
    Registered User
    Join Date
    Apr 2011
    Location
    dust
    Posts
    70
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    int main(void)
    {
      float totalPaid=0.0, r=(0.22/12), B=5000.0, P=0.0;
      printf("\nEnter your monthly payment: $");
      scanf("%f", &P);
      printf("\nAnnual Interest Rate (r) = %-5.2f%%\nAmount Borrowed (B) = $%-6.2f\nPayment Amount (P) = $%-6.2f\n\n", r*12*100, B, P);
      for (float n=1.0, nthMonth=0.0;B>0;n++)
      {
        nthMonth = r/12 * B;
        totalPaid += nthMonth;
        printf("%-2.0f %-5.2f %-6.2f \n", n, nthMonth, B);
        B -= (P + nthMonth);
      }
      printf("\nTotal interest paid: $%-6.2f\n", totalPaid);
      exit(0);      
    }
    What about the above one?

  7. #7
    Registered User
    Join Date
    May 2012
    Posts
    505
    The logic isn't very neat.

    You don't need to handle the first month specially, as I see. Your condition is while the balance is greater than zero, so it's better to have that explicitly in the loop control statement. Only use break when you really need it.

    Then the loop is just B = (B - payment) * (1 + interest), a print, and maybe a loop counter for visual display.
    C allows you to tag on an increment to another statement like this:

    Code:
    printf("Month %d balance %f\n", i++, B);
    So you only need two lines in the loop.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  8. #8
    Registered User
    Join Date
    Oct 2012
    Posts
    42
    Wow, thanks for all the replies! I'll mess around with my code and post a revised version here later today.

  9. #9
    Registered User
    Join Date
    Oct 2012
    Posts
    42
    I based it mostly off of ApolCor's suggestion, although I switched some things around. I threw in a catch in case the user enters a monthly payment that happens to be less than the first month's interest payment (which creates an infinite loop inside of the while). I'm pretty happy with it at this point.
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    int main(void)
    {
      float totalPaid=0.0, r=0.22, B=5000.0, P=0.0, nthMonth = 0.0, n=1.0;
      printf("\nEnter your monthly payment: $");
      scanf("%f", &P);
      printf("\nAnnual Interest Rate (r) = %-5.2f%%\nAmount Borrowed (B) = $%-6.2f\nPayment Amount (P) = $%-6.2f\n\n", r*100, B, P);
      while (B>0)
      {
        nthMonth = r/12 * B;
        totalPaid = totalPaid + nthMonth;
        if (nthMonth > P)
         {
             printf("Monthly payment cannot be less than the owed monthy interest: $%-6.2f\n", nthMonth);
            exit(0);
         }
        printf("%-2.0f %-5.2f %-6.2f \n", n++, nthMonth, B);
         B = B - P + nthMonth;
      }
      printf("\nTotal interest paid: $%-6.2f over a course of %-6.2fmonths.\n", totalPaid, n);
      exit(0);      
    }

  10. #10
    Registered User
    Join Date
    May 2012
    Posts
    505
    I'd change that catch to "you have got yourself into an irrecoverable debt spiral. You are now Greece." Then run for a four year period just to show what happens.

    But you only need to do the test once. The balance is either increasing or it is going down.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by ArunS View Post
    Code:
        B -= (P + nthMonth);
    What about the above one?
    You actually introduced a bug with that line (and unneeded brackets).

    Code:
    B = B - P + nthMonth;
    could be written as:
    Code:
    B -= P - nthMonth;
    
    // or
    
    B += nthMonth - P;
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Oct 2012
    Posts
    42
    Quote Originally Posted by Malcolm McLean View Post
    I'd change that catch to "you have got yourself into an irrecoverable debt spiral. You are now Greece." Then run for a four year period just to show what happens.

    But you only need to do the test once. The balance is either increasing or it is going down.
    that's the kind of humor that would score me extra credit with my professor...but yes, I suppose it would make more sense to move the if statement above the while loop so it's not having to go past it every pass. But since nthMonth isn't given the correct value until inside the while loop, would it work to write the for loop like this:
    Code:
        if (r/12 * B > P)
    
         {
             printf("Monthly payment cannot be less than the owed monthy interest: $%-6.2f\n", nthMonth);
    
            exit(0);
         }
    Would that follow proper order of operations, or would I have to partition the if statement with more parentheses? I'm on my phone right now, otherwise I would check myself.


    Quote Originally Posted by iMalc View Post
    You actually introduced a bug with that line (and unneeded brackets).

    Code:
    B = B - P + nthMonth;
    could be written as:
    Code:
    B -= P - nthMonth;
    
    // or
    
    B += nthMonth - P;
    I'm interested, what bug would that be? I understand how it is faster to use the -= but I don't understand why
    Code:
    B -= (P + nthMonth);
    introduces a bug.

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Paul Omans View Post
    I'm interested, what bug would that be? I understand how it is faster to use the -= but I don't understand why
    Code:
    B -= (P + nthMonth);
    introduces a bug.
    Basic math:
    Code:
    B -= (P + nthMonth);
    is equivalent to
    Code:
    B = B - (P + nthMonth);
    which after removing the parentheses becomes
    Code:
    B = B - P - nthMonth;
    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Optimizing question(s)...
    By yaya in forum C++ Programming
    Replies: 3
    Last Post: 05-05-2009, 03:05 AM
  2. optimizing
    By h_howee in forum C++ Programming
    Replies: 4
    Last Post: 01-06-2008, 02:44 AM
  3. Optimizing my code
    By Lina in forum C Programming
    Replies: 30
    Last Post: 10-22-2006, 01:31 PM
  4. Optimizing my program
    By jodders in forum C++ Programming
    Replies: 7
    Last Post: 03-05-2005, 09:12 AM
  5. Need help optimizing loops....
    By ninjacookies in forum C Programming
    Replies: 4
    Last Post: 02-24-2005, 03:54 PM