0

So, I just finished typing my "greedy" code for the fifth time and thought that this time it actually works, but when I run the check it fails at only one value 4.2. I'm going to post my code and hope that any of you guys might give me a tip:

    float f;
    printf("How much change is owed?\n");
    do
    {
        f = GetFloat();
        if(f < 0)
        {
            printf("Retry:\n");
        }
    }
    while(f <= 0);

    int i = f * 100;

[EDIT: Unrelated code removed to comply with Honor Code policy.]
6

This is a very common problem and the whole point of greedy.c, so let me try and give the definitive answer.

Float values with a decimal part (to the right of the decimal, in case you weren't certain) rarely store with exact precision. They have to be converted from base 10 to base 2. Since there is a limit on the number of digits that can be used, it is simply not possible to do an exact conversion except for decimals that represent a fraction where the denominator is an exact power of 2 (1/2, 3/4, etc.). (See class lectures and materials, and google, for more details.) Instead, the numbers are stored as closely as possible to the exact value, but there will usually be some inaccuracy in precision.

Next, there are differences in how a float is stored and how it is displayed. It will be stored as accurately as possible, using the available bits (depends on architecture, i.e., 32 or 64 bit), but may not be displayed the same. For instance, if you `printf("myfloat = %f \n", myfloat)", it will probably display 8 significant digits or less, and it will round off the actual value accordingly. If, however, it is printed with maximum precision, the results are different.

Consider this: Say that 4.2 were loaded into myfloat. It will be stored as 4.19999980926513671875 but if printed as %f, it would round off to the default precision and be displayed as 4.200000. Multiply by 100, it would be 419.999969. Now, print those same numbers with %3.16f and they look a lot different: t = 4.1999998092651367 or 100t = 419.99996948242187500000

Now, look at what happens when a number is cast or converted from a float or an int. The float is not rounded at the decimal point, it is truncated. That means that the following code:

float fl = 4.2;
fl = fl * 100;
int i = fl;

will store 4.19999980926513671875 in fl. Next multiply it by 100 and 419.99996948242187500000 (approximately 420) is stored in fl. Finally, the value in fl is converted to an int and is stored in i as 419, not 420.

So, when any of these concepts are overlooked, imprecision creeps into a program. It can be trivial or significant in impact. It is up to the programmer to remember this and to consider these concepts when designing and writing code.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance.

If you read this later and found it useful, an upvote would be appreciated. ;-)

3
  • Yes, now I understand, but how can this be solved. I'm aware of the round(f) function that comes with the math library but am unaware of how to implement it. – PetarNPetrov Jul 12 '16 at 18:50
  • Just figured out how to use it. Clicking that check mark. – PetarNPetrov Jul 12 '16 at 19:07
  • I have the exact same problem , how did you fix it ?!! – Rayane djh Jan 16 '18 at 14:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .