The problem here is that you are using a float
variable (gap
), but you are comparing it with a double
constant (0.00002
). The constant is double
because floating-point constants in C are double unless otherwise specified.
An underlying issue is that the number 0.00002
is not representable in either float
or double
. (It's not representable at all in binary floating point because it's binary expansion is infinitely long, like the decimal expansion of ⅓.) So when you write 0.00002
in a program, the C compiler substitutes it with a double
value which is very close to 0.00002
. Similarly, when scanf
reads the number 0.00002
into a float
variable, it substitutes a float
value which is very close to 0.00002
. Since double
numbers have more bits than floats
, the double
value is closer to 0.00002
than the float
value.
When you compare two floating point values with different precision, the compiler converts the value with less precision into exactly the same value with more precision. (The set of values representable as double
is a superset of the set of values representable as float
, so it is always possible to find a double
whose value is the same as the value of a float
.) And that's what happens when gap < 0.00002
is executed: gap
is converted to the double
of the same value, and that is compared with the double (close to) 0.00002
. Since both of these values are actually slightly less than 0.00002, and the double
is closer, the float
is less than the double
.
You can solve this problem in a couple of ways. First, you can avoid the conversion, either by making gap
a double
and changing the scanf
format to %lf
, or by comparing gap
to a float
:
while (gap < 0.00002F || gap > 0.99999F) {
But that's not really correct, for a couple of reasons. First, there is actually no guarantee that the floating point conversion done by the C compiler is the same as the conversion done by the standard library (scanf
), and the standard allows the compiler to use "either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner." (It doesn't specify in detail which value scanf
produces either, but recommends that it be the nearest representable value.) As it happens, gcc
and glibc
(the C compiler and standard library used on Linux) both produce the nearest representable value, but other implementations don't.
Anyway, according to your error message, you want the value to be between 0.00001
and 1.00000
. So your test should be precisely that:
while (gap <= 0.00001F || gap >= 1.0000F) { ...
(assuming you keep gap
as a float
.)
Any of the above solutions will work. Personally, I'd make gap
a double
in order to make the comparison more intuitive, and also change the comparison to compare against 0.00001
and 1.0000
.
By the way, the E-05
suffix means "times ten to the power of -5" (the E
stands for Exponent
). You'll see that a lot; it's a standard way of writing floating point constants.