[Courses] [C] Floating Point Errors: summary

Mary mary-linuxchix at puzzling.org
Thu Jul 18 11:25:31 EST 2002


I thought Suzi's post and the resulting discussion deserved its own
summary:

http://www.linuxchix.org/content/courses/c_programming/floating.html

                             Floating Point Errors

   This informal discussion sprung from Suzi's [1]post describing a
   problem with this program [code reproduced with permission]:
#include

char line[50];
float amount;           /* the amount of $ as entered by the user */
int total;          /* amount * 100, converted to an interger */
int dollars;            /* # of dollars needed to make change */
int quart;          /* # of quarters needed */
int dime;           /* # of dimes needed, etc. */
int nick;
int penn;

int main()
{
   while (1) {
     /* inputting dollar amount */
     printf("Enter the amount of money to make change for: $");
     fgets(line, sizeof(line), stdin);
     if (sscanf(line, "%f", &amount) <= 0)
       break;
     while (amount <= 0) {
       printf("Please enter an amount greater than 0: $");
       fgets(line, sizeof(line), stdin);
       if (sscanf(line, "%f", &amount) <= 0)
          break;
     }
     total = amount * 100;

     /* determining how many of each coin is needed */
     dollars = total / 100;
     total %= 100;
     quart = total / 25;
     total %= 25;
     dime = total / 10;
     total %= 10;
     nick = total / 5;
     penn = total % 5;

     /* printing the change needed.  Program should only print a type of
      * coin if it is needed to make change (i.e. it should not print
      * "0 quarters".                                                  */
     printf("To make change for $%.2f, you need:\n", amount);
     if (dollars > 1)
       printf("%d dollars\n", dollars);
     if (dollars == 1)
       printf("%d dollar\n", dollars);
     if (quart > 1)
       printf("%d quarters\n", quart);
     if (quart == 1)
       printf("%d quarter\n", quart);
     if (dime > 1)
       printf("%d dimes\n", dime);
     if (dime == 1)
       printf("%d dime\n", dime);
     if (nick == 1)
       printf("%d nickel\n", nick);
     if (penn > 1)
       printf("%d pennies\n", penn);
     if (penn == 1)
       printf("%d penny\n", penn);
   }
   return (0);
}

   It didn't behave correctly when there was change of a single peeny (1
   cent, or 0.01 dollars) involved.

   Mary made a [2]long post in response which eventually identified a
   floating point error, a quite subtle bug.

Online references

     * [3]A general introduction
     * [4]The source of this particular bug (the 0.1 bug)

Solutions

   Different solutions to Suzi's problem were suggested:
     * [5]Suzi's soluion [manually rounding to correct for floating point
       errors]
     * [6]Christopher's solution [using round or lround]
     * [7]Conor's solution [correcting manual rounds for negative
       numbers]
     * [8]Lorne's solution [cutting floating point numbers out of the
       equation altogether]

References

   1. http://mailman.linuxchix.org/pipermail/courses/2002-July/000571.html
   2. http://mailman.linuxchix.org/pipermail/courses/2002-July/000572.html
   3. http://www.ug.cs.usyd.edu.au/~cs2/soft2004/s1_2002/tutes/week10/
   4. http://www.eskimo.com/~scs/C-faq/q14.1.html
   5. http://mailman.linuxchix.org/pipermail/courses/2002-July/000575.html
   6. http://mailman.linuxchix.org/pipermail/courses/2002-July/000576.html
   7. http://mailman.linuxchix.org/pipermail/courses/2002-July/000580.html
   8. http://mailman.linuxchix.org/pipermail/courses/2002-July/000581.html



More information about the Courses mailing list