Argarak - 6 months ago 22

C Question

I am currently writing a greedy algorithm, but I have stumbled upon a problem when comparing floats.

I would use code like this:

`float f = 0;`

if (f == 0) {

// code

}

I have tested this on a seperate program and it worked fine, but not on the program I am working on.

Here is an extract from my own program.

`float chf2 = fmod(chf, 0.1);`

float ch3 = chf - chf2;

if (chf2 == 0) {

/* Divide user's number by 0.1 */

float ch3 = chf / 0.1;

/* Round the number */

int ch4 = round(ch3);

/* Print the amount of coins and end */

printf("%d\n", ch4 + coin2);

return 0;

}

Oddly, this seems to work with a previous if statement that checks when a fmod of 0.25 from the user's input.

Is there a better way of checking if a float is equal to another float?

Answer

Your code works correctly. Your expectations might need a little bit of adjusting, however.

The `fmod`

function always returns an exact result---when you write `c = fmod(a, b)`

, `c`

is a number such that `c + k*b`

(evaluated in infinite precision) exactly equals `a`

for some integer `k`

. So your code is actually sound---`if (c == 0)`

will trigger exactly when `a`

is exactly a multiple of `b`

.

You took `b`

to be the `double`

`0.1`

, which is actually the fraction `3602879701896397/36028797018963968`

, not the fraction `1/10`

. So if I compute `fmod(1, 0.1)`

, I should expect to get the fraction `(36028797018963968 % 3602879701896397) / 36028797018963968`

, which is `3602879701896395 36028797018963968`

. That's very slightly smaller than the `double`

called `0.1`

.

This also explains why your code meets your expectations when you use `0.25`

instead of `0.1`

; `0.25`

gives you 1/4 exactly.

You might read this floating-point guide to learn about the representation of floating-point numbers.