-1

I want it to ask user for a float input to assign to money such as a dollar. The smallest unit would be a cent or 0.01 so I want it to reprompt the user for input every time he enters a negative value or zero. The while condition seems fine. What is wrong with it?

#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{ 
    float amount = 0;
    do
    {
    printf("How much change to be returned?\n");
    amount = GetFloat();
    }
    while(amount < 0.01);
}

Sample run:

jharvard@appliance (~/Dropbox/pset1): ./greedy
How much change to be returned?
0.01
How much change to be returned?

As you can see when I enter 1 cent it repeats the loop. If I enter 0.02 it works but I want to know why it's doing this.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Éanan Halferty
  • 41
  • 1
  • 2
  • 6
  • Please show all code needed to understand this. Especially the Function GetFloat();. – Nidhoegger Aug 03 '15 at 16:10
  • 1
    You're comparing `float` with `double`. Use `while(amount < 0.01f)`. – EOF Aug 03 '15 at 16:11
  • It's most probably a floating point error. Your input is converted to a float (single precision) and compared to a double precision. The single precision representation might be smaller than the double due to rounding errors. – H4kor Aug 03 '15 at 16:11
  • 2
    Don't use floats to represent money values, and don't check equality of floats. Note that 0.01 cannot be represented exactly as a float (or double) on a computer so the line (amount < 0.01) won't work the way you think it does.. – FredK Aug 03 '15 at 16:11
  • @EOF thank you. So if I just write 0.01 in a condition it is a double , if I want a float I have to write 0.01f? – Éanan Halferty Aug 03 '15 at 16:13
  • @ÉananHalferty Print what value `amount` has with decimals upto 10 or 12 places .You will be surprised. – ameyCU Aug 03 '15 at 16:16

3 Answers3

1

Floats definition doesn't make them a good type for comparisons.

This is probably duplicate of similar topic

while loop does not terminate - float arithmetic

Community
  • 1
  • 1
Origence
  • 155
  • 3
  • 10
1

Previous answers are correct - float values cannot be represented exactly in a binary format. So you should always compare float number with some value of error:

Change the line

while(amount < 0.01)

To

while(amount - 0.01 < EPS)

Where the EPS constant is defined as (put any number that is small enough to be insignificant)

const float EPS = 1e-5;
Kirhog
  • 11
  • 2
0

0.01 Cannot be represented exactly in a float variable, therefore I conclude that in your case the input of 0.01 is converted to a float value bigger than the 0.01 constant and consequently the loop is not terminating for input of 0.01.

To fix this you can switch to a full blown currency or fixed point datatype or more simply change the program to work with cents instead of dollars, thereby avoiding fractional values and especially those of them that cannot be represented exactly. Another often used technique from Kirhog's answer is to use an Epsilon in you comparisons, e.g.:

double EPSILON = 0.005;
...
while(amount < 0.01+EPSILON);
Peter G.
  • 14,786
  • 7
  • 57
  • 75