2

Right now I'm using C and I came across a problem while doing a certain task. The task is to be able to input a number and the value of coins used will be displayed after. My problem is, say there is 0.10 cents worth of change, my code will skip past the dime loop (which checks if a value of 0.10 is less than the value of the change, then subtracts) and continue on to the nickel.. which will then skip the nickel after the change value goes to 0.05 and goes to pennies, which will then stop at 0.01 and end the coin count making the count one penny short and also longer than needed.

int main(void) {
  float c;

  int k = 0;

  printf("How much change?: \n");
  c = GetFloat();

  //checks for quarters
  for (float q = 0.25; q <= c; k = k + 1) {

    c = c - 0.25;
    printf("q \n");
  }
  //checks for dimes
  for (float d = 0.10; d <= c; k = k + 1) {

    c = c - 0.10;
    printf("d \n");
  }
  //checks for nickels
  for (float n = 0.05; n <= c; k = k + 1) {
    c = c - 0.05;
    printf("n \n");

  }
  //checks for pennies
  for (float p = 0.01; p <= c; k = k + 1) {
    c = c - 0.01;
    printf("p \n");
  }

  printf("%d  & %.02f \n", k, c);
}

I have a clue thinking that the error could be in the condition part of the for loops but I have no clue :/

Shaggy
  • 596
  • 1
  • 6
  • 15
Dre V
  • 33
  • 3
  • 1
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – too honest for this site Sep 24 '16 at 17:17
  • If people whould just read the info page **before** asking ... – too honest for this site Sep 24 '16 at 17:18
  • Is it like this in all C based languages? (C++, c#, java) – shinzou Sep 24 '16 at 17:21
  • @kuhaku It's like this in any language and any computer that uses floating point. – tofro Sep 24 '16 at 17:55
  • @kuhaku consider a `float` having 32 bits, which can represent 2**32 different values. As there is an infinite number of values between, say, 0 and 1 they cannot *all* be represented. Some can be represented exactly, but most are an approximation. Floating point types buy you *range* at the expense of *accuracy*. Even if the notation could cope with recurring numbers (similar to one third in decimal being 0.33333...) an irrational number cannot be stored, by definition. – Weather Vane Sep 24 '16 at 18:06
  • @kuhaku: None of those languages are **C-based**! C++ started as a C extension, but both languages have changed the last 27 years. They are different languages! The other two never were based on C. It is the same as if you called German and French "english-baed languages", just because they use the same letters. – too honest for this site Sep 24 '16 at 18:09
  • @WeatherVane: You more describe a fractional/fixed point type. `float` actually adds an additional "dimension" with the exponent. – too honest for this site Sep 24 '16 at 18:10
  • @kuhaku: How do you intend to represent **all** possible real values with a limited number of digits? – too honest for this site Sep 24 '16 at 18:11
  • @Olaf the exponent adds range, I meant the mantissa. And BTW English is a German-French (and other) based language, not the other way round! – Weather Vane Sep 24 '16 at 18:12
  • @WeatherVane: Not really. German has an indo-german origin, French a roman. English has celtic ancestry, etc. A language-historian can detail this much better. (That was not my point anyway). – too honest for this site Sep 24 '16 at 18:14
  • @Olaf getting off-topic here but much of English came from the Saxons and the Normans as well as the Celts, the Vikings and the Romans. Have a [read here](https://en.wikipedia.org/wiki/English_language). – Weather Vane Sep 24 '16 at 18:17
  • OK they aren't C based but C influenced or C family. @Olaf – shinzou Sep 24 '16 at 18:37
  • @kuhaku With the same rectification you can say BASIC influenced C. Or B influenced Python. Inheritance of PLs is completely pointless for the problem. Handling and representation of floats in **digital** computers is deeply rooted in the hardware itself, not a specific programming language. The assertion is true also for Assembler language. – too honest for this site Sep 24 '16 at 19:42

1 Answers1

6

Your problems are all due to floating point imprecision: binary floating point cannot be precisely converted to and from decimal notation.

It happens that 0.25 can be represented exactly in floating point: as can many of its multiples. But 0.1 cannot. So your incrementing by these amounts will give you unexpected behaviour.

Your best bet in this case is to use integral types throughout and work in cents.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483