Rounding and Truncating problem in C

Discussion in 'C' started by moogle1979, Feb 2, 2010.

  1. moogle1979

    moogle1979 New Member

    Joined:
    Feb 2, 2010
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    I tested it using the purchase price if 23.455, when doing it Iuse 0.005 to help with the rounding issue however it is not rounding right when I truncate it

    For example

    The Delmar store has a tax rate of 7.25% which should show a tax of 1.7004875. Rounding that it would be 1.70, even to account for the rounding in C with 0.005 it should still truncate to 1.70 however it is showing 1.71. What am I doing wrong?


    Here is the program I have at the moment

    Code:
    #include <stdio.h>
    #include <windows.h>
    
    
    int main (void) //Main program function
    {
        
        char    *stores[3] = {"Del Mar", "Encinitas", "La Jolla"};
        float    taxPercent[3]={7.25, 7.5, 7.75}; // Tax variable for all three stores
        float    price; //float variable for the price
        
        do {
            printf("\t\tKudler Fine Foods Tax Calculator\n\n");  // prints header 
            printf("Please enter the amount of your purchase: ");
            scanf("%f", &price);
            if (0.0 > price) {
                              printf("\n\nPurchase amount must be positive");
                              sleep(2000);
                              system("cls");
                              }
             } while(price < 0.0);
             
        float newPrice = price + 0.005;     
            
        float taxTotal[3] = {price * (taxPercent[0]/100), price * (taxPercent[1]/100), price * (taxPercent[2]/100)}; //calculates the total for each store
        float totalPrice[3] = {price + taxTotal[0], price + taxTotal[1], price + taxTotal[2]};
        printf("\n\n\t%s store\n", stores[0]); //prints tax information for Del Mar
        printf("\n\tPurchase price: %.2f", newPrice);
        printf("\n\tSales tax: %.2f", taxTotal[0] + 0.005); 
        printf("\n\tTotal Purchase Price: %.2f", totalPrice[0] + 0.005);
        
           printf("\n\n\t%s store\n", stores[1]); //prints tax information for Del Mar
        printf("\n\tPurchase price: %.2f", newPrice);
        printf("\n\tSales tax: %.2f", taxTotal[1] + 0.005); 
        printf("\n\tTotal Price: %.2f", totalPrice[1] + 0.005);
        
           printf("\n\n\t%s store\n", stores[2]); //prints tax information for Del Mar
        printf("\n\tPurchase price: %.2f", newPrice);
        printf("\n\tSales tax: %.2f", taxTotal[2] + 0.005); 
        printf("\n\tTotal Purchase Price: %.2f", totalPrice[2] + 0.005);
            
        getch(); // waits for user to press a key
    
        return 0; // return of int main()
    
    } // end main
    
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Computers can't store floating point numbers precisely; they convert them to binary and there are some losses. You know about these losses in decimal, for example what's 3/10 as a number? 0.3333... you cannot represent it in a finite number of digits.

    So it is with computers. When you try to store 1.70, the computer converts it into binary which only approximates the true value. So the maths on floating point numbers doesn't work properly. 1.70+0.01 != 1.71.

    There are two ways of getting round this. The most accurate way is to switch to integers, and instead of storing 1.70, store 170 with a note somewhere that this is the true value multiplied by 100. Then the maths will be exact.

    Or when comparing, you can subtract, take the absolute value and compare the difference with a suitably small number. So if you're comparing 1.70+0.01 with 1.71, what you might do is subtract 1.70 from 1.71 and see if the difference is less than, say, 0.00005.
     
  3. moogle1979

    moogle1979 New Member

    Joined:
    Feb 2, 2010
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    Some one mentioned doing it basically this way

    Code:
    int sale = ((taxPercent[0]/100) * price)  * 100;
    int decimal = sale % 100;
    int wholeSale = sale/100
    
    printf("Purchase Price: %d.%d", wholeSale, decimal);
    
    Since I have three stores is there a way to do this in arrays?
    When I do this is comes out right with the first store. The second store however, with the number I use (23.455) of a tax rate of 7.5 shows a tax of 1.759125; shows in on there as 1.75 when it should show 1.76. Did I do it right and it should show the 1.75 or is there a way to do it to get it to be 1.76?

    I hope this all makes sense and thanks in advance for any help you can provide.
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Looks like you need to round off. 1.759xxx -> 1.76. You can round to a whole number by adding half then casting to an int (so 1.4->1.9->1, 1.7->2.3->2, so this rounds to the nearest integer), so to round to the nearest 1/100th you can do something similar.
     
  5. moogle1979

    moogle1979 New Member

    Joined:
    Feb 2, 2010
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    Well it is allot of coding but I think I have done it. Tell me what you think

    Code:
    /********************************************************************
    *   Tax Calculator for CSS 561                                      *  
    *   Author: Gregory Hegykozi                                        *
    *   Due Date: February 7, 2010                                      *
    *   Facilitator: Michael Flanagan                                   *
    *********************************************************************        
    *        Libraries Included                                         *
    *             math.h                                                *   
    *             stdio.h                                               *
    *             windows.h                                             *
    *********************************************************************
    *          Variables used                                           *
    *stores: an array storing the names of the stores                   *
    *taxPercent: used as an array to store the tax price for each store *             
    *price: float variable for price                                    *        
    *taxTotal: used as an array to calculate tax totals                 *
    *totalPrice: float variable to determine total purchase             *
    *********************************************************************
    *                 Company                                           *
    *               Kudler Fine Foods                                   *
    *********************************************************************
    *            Stores Included                                        *
    *               Delmar                                              *
    *               Encinitas                                           *
    *               La Jolla                                            *
    *********************************************************************
    *                     Main Version                                  *
    * Version: Create a tax calcutator that gives prices for            *
    * the 3 Kudler Fine Foods Store showing the tax for 125.00 dollars  *
    *********************************************************************
    *                     Additions                                     *
    * First Addition: Add in the ability for the user to choose their   *
    * own purchase price while checking that the user does not put      *
    * in a negative number while showing
    ********************************************************************/
    
    #include <math.h>
    #include <stdio.h>
    #include <windows.h>
    
    
    int main (void) //Main program function
    {
        
        char    *stores[3] = {"Del Mar", "Encinitas", "La Jolla"}; //store variables
    	float	taxPercent[3]={7.25, 7.5, 7.75}; // Tax variable for all three stores
    	float	price; //float variable for the price
    	
    	do {  // starts a do while loop
            printf("\t\tKudler Fine Foods Tax Calculator\n\n");  // prints header 
            printf("Please enter the amount of your purchase: "); //asks for purchase amount
            scanf("%f", &price);  // scans user input
            
            // verifies user input was positive
            if (0.0 > price) { 
                              printf("\n\nPurchase amount must be positive");
                              sleep(2000);
                              system("cls");
                              }
             } while(price < 0.0);
      
        // creates usable variables for price, tax, and total purchase  
        short saleTax[3] = {(((taxPercent[0]/100) * price) + 0.005) * 100, (((taxPercent[1]/100) * price) + 0.005) * 100, (((taxPercent[2]/100) * price) + 0.005) * 100};
        short decimal[3] = {saleTax[0] % 100, saleTax[1] % 100, saleTax[2] % 100};
        short wholeTax[3] = {saleTax[0]/100, saleTax[1]/100, saleTax[2]/100};
        float roundPrice = {price + 0.005}; 
        float taxTotal[3] = {floor((price*(taxPercent[0]/100))*1000)/1000, floor((price*(taxPercent[1]/100))*1000)/1000, floor((price*(taxPercent[2]/100))*1000)/1000};
        float totalPrice[3] = {roundPrice + taxTotal[0],roundPrice + taxTotal[1],roundPrice + taxTotal[2]}; 
    	
    	//prints purchase information for Del Mar
    	printf("\n\n\t%s store\n", stores[0]); 
    	printf("\n\tPurchase price: %.2f", roundPrice);
    	printf("\n\tSales tax: %d.%d", wholeTax[0], decimal[0]); 
    	printf("\n\tTotal Purchase Price: %.2f", totalPrice[0]);
    	//end purchase information for Del Mar
        
    	//prints purchase information for Encinitas
    	printf("\n\n\t%s store\n", stores[1]); 
    	printf("\n\tPurchase price: %.2f", roundPrice);
    	printf("\n\tSales tax: %d.%d", wholeTax[1], decimal[1]); 
        printf("\n\tTotal Price: %.2f", totalPrice[1]);
        //end purchase information for Encinitas
        
        //prints purchase information for La Jolla
       	printf("\n\n\t%s store\n", stores[2]); 
        printf("\n\tPurchase price: %.2f", roundPrice);
        printf("\n\tSales tax: %d.%d", wholeTax[2], decimal[2]);
        printf("\n\tTotal Purchase Price: %.2f", totalPrice[2]);
        //end purchase information for La Jolla
        
        	
        getch(); // waits for user to press a key
    
    	return 0; // return of int main()
    
    } // end main
    
     
  6. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    "allot" isn't a word, or if it is, it doesn't mean "a lot". Let's see what happens if we use the "a xyyy"="axxyyy" principle some more...

    Your code isn't formatted well. This makes it difficult to follow - a reviewer would need to reformat it to be able to make any sense of it. This isn't "allot" of code, by the way, it's only "affew" lines. The lack of good formatting will make this program "allot" harder than it needs to be. Here are the first few lines formatted correctly:

    Code:
    int main (void) //Main program function
    {
    	char    *stores[3] = {"Del Mar", "Encinitas", "La Jolla"}; //store variables
    	float	taxPercent[3]={7.25, 7.5, 7.75}; // Tax variable for all three stores
    	float	price; //float variable for the price
    
    	do {  // starts a do while loop
    		printf("\t\tKudler Fine Foods Tax Calculator\n\n");  // prints header 
    		printf("Please enter the amount of your purchase: "); //asks for purchase amount
    		scanf("%f", &price);  // scans user input
    
    		// verifies user input was positive
    		if (0.0 > price) 
    		{ 
    			printf("\n\nPurchase amount must be positive");
    			sleep(2000);
    			system("cls");
    		}
    	} while(price < 0.0);
    
    ... and you can do the rest.
    
    
    Comments are there to explain what the code is doing and relate it to the higher level design so that it can be understood what the code is for. They are NOT for stating the obvious. This comment is "awwaste" of space because it doesn't do anything more than state the obvious: "do{" always starts "addo" loop because that's the syntax of a do loop!
    Code:
    	do {  // starts a do while loop
    
    Other pointless comments:
    Code:
    int main (void) //Main program function.  Well duh.  Obviously it's the main function.
    
    char    *stores[3] = {"Del Mar", "Encinitas", "La Jolla"}; //store variables
    Well duh.  Obviously you're storing variables.  What is the significance of them?
    
    float	taxPercent[3]={7.25, 7.5, 7.75}; // Tax variable for all three stores
    See, you can do comments correctly!
    
    printf("\t\tKudler Fine Foods Tax Calculator\n\n");  // prints header 
    printf("Please enter the amount of your purchase: "); //asks for purchase amount
    scanf("%f", &price);  // scans user input
    All pointless comments.  It's just as obvious what the code is doing without them.
    
    // verifies user input was positive
    if (0.0 > price) 
    Well duh.  Obviously this is checking if price is negative.
    
    } while(price < 0.0);
    Why isn't there a "// ends a do while loop" comment here?  (NOOO, I'm not implying there should be one!)
    
    Don't write your if statements the wrong way round. If you're checking if price is less than zero, check that price is less than zero, not if zero is bigger than price.
    Code:
    if (0.0 > price)
    
    But if you're going to insist on doing it, then be consistent:
    } while(price < 0.0);
    
    Watch out for duplicate code; this is "aggreat" way to introduce bugs - if you need to change it, then you need to remember to change it everywhere, and you get "abbug" that can be difficult to track down when you don't (because you think you've fixed that issue, so you waste time looking everywhere else).

    Code review stops there because that's as far as I reformatted the code, except for one final point. Try to write self-documenting code, then that way the need for comments is reduced. For example
    Code:
    return 0; // return of int main()
    
    Most compilers will define EXIT_SUCCESS as zero; use that instead:
    Code:
        return EXIT_SUCCESS;
    
    Very clear and no need for any kind of comment there.
     
  7. moogle1979

    moogle1979 New Member

    Joined:
    Feb 2, 2010
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    These are stuff are teacher is telling us not to do. For instance our teacher is telling us to always use:

    Code:
    return 0;
    
    and our teacher told us to make it well documented with as few comments as possible and not to document every line.
    as far as the following
    Code:
    if (0.0 > price)
    
    But if you're going to insist on doing it, then be consistent:
    } while(price < 0.0);
    
    I asked the teacher if the following would work

    Code:
    
    if (price > 0.0)
    
    } while (price < 0.0)
    
    as I always like to put the variable first in arguments, however the teacher sent me a message back say it should be the way it is now as it looks better.

    I appreciate your comments and sorry about the allot instead of a lot. I am not the best at grammar.
     
  8. moogle1979

    moogle1979 New Member

    Joined:
    Feb 2, 2010
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    I just talked to the teacher and when confronted he said, he never mentioned it because everyone is assumed to have windows which automatically returns 0

    This has happened before the teacher posted the following program used from an example

    Code:
    #include <stdio.h>
    #include <time.h>
    #include <system.h>
    
    /********************************************
    FUNCTION PROTOTYPES
    ********************************************/
    int sportsQuestion(void);
    int geographyQuestion(void);
    void pause(int);
    /*******************************************/
    /********************************************
    GLOBAL VARIABLE
    ********************************************/
    int giResponse = 0;
    /*******************************************/
    main()
    {
       do {
          clrscr();
          printf("\n\tTHE TRIVIA GAME\n\n");
          printf("1\tSports\n");
          printf("2\tGeography\n");
          printf("3\tQuit\n");
          printf("\n\nEnter your selection: ");
          scanf("%d", &giResponse);
          switch(giResponse) {
          case 1:
             if (sportsQuestion() == 4)
                printf("\nCorrect!\n");
             else
                printf("\nIncorrect\n");
             pause(2);
             break;
          case 2:
             if (geographyQuestion() == 2)
                printf("\nCorrect!\n");
             else
                printf("\nIncorrect\n");
             pause(2);
             break;
          } //end switch
       } while ( giResponse != 3 );
    } //end main function
      /**********************************************************
      FUNCTION DEFINITION
    **********************************************************/
    int sportsQuestion(void)
    {
       int iAnswer = 0;
       clrscr();
       printf("\tSports Question\n");
       printf("\nWhat University did NFL star Deon Sanders attend? ");
       printf("\n\n1\tUniversity of Miami\n");
       printf("2\tCalifornia State University\n");
       printf("3\tIndiana University\n");
       printf("4\tFlorida State University\n");
       printf("\nEnter your selection: ");
       scanf("%d", &iAnswer);
       return iAnswer;
    } //end sportsQuestion function
      /**********************************************************
      FUNCTION DEFINITION
    **********************************************************/
    int geographyQuestion(void)
    {
       int iAnswer = 0;
       clrscr();
       printf("\tGeography Question\n");
       printf("\nWhat is the state capital of Florida? ");
       printf("\n\n1\tPensacola\n");
       printf("2\tTallahassee\n");
       printf("3\tJacksonville\n");
       printf("4\tMiami\n");
       printf("\nEnter your selection: ");
       scanf("%d", &iAnswer);
       return iAnswer;
    } //end geographyQuestion function
      /***********************************************************
      FUNCTION DEFINITION
    ************************************************************/
    void pause(int inNum)
    {
       int iCurrentTime = 0;
       int iElapsedTime = 0;
       iCurrentTime = time(NULL);
       do {
          iElapsedTime = time(NULL);
       } while ( (iElapsedTime - iCurrentTime) < inNum );
    } // end pause function
    
    The problem with this is the compiler they recommend accept non-ANSI functions like clrscr, however since Miracle C does not run on my Operating System I had to use Dev C++ "which I am glad I did" because I found out clrscr does not run on Dev C++ because it is a Borland Expression from conio.h which is not standard ANSI. I posed this to him and he had no solution except to force the compiler to use it with voids. I looked it up and found out the standard ANSI for something like that is

    Code:
    system("cls");
    
    I do so much research because I do not put much stock in what the teacher says. Some they say is good but they like teaching non-portable ways and do not even mention portable options.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice