问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/29084695/c-comparing-floats-with-if-statements