0

I recently detected the hard way that in the comparison in Visual Studio C#

double a = 0.4;
float b = 0.4f;
if (a < b) break;

a turns out to be smaller than b, so the comparison is true and the program branches out. This came to me as a surprise.

I have an idea why this is so, namely because the conversion of the decimal values to zeroes and ones is different for float and double types.

I would expect from a compiler that when equality comes into play, it will double check whether the literal representation of the decimal values happen to be identical and then bring the correct result. Or is this exactly what the compiler cannot do for some reason? Would it be possible at least to issue a warning at run time?

Of course, one solution to the problem is

if (a < (double)b) break;

and in this case the comparison is evaluated correctly. Can I tell the compiler to do that for me?

alrts
  • 338
  • 5
  • 12
  • are you **really** expecting a program that's tasked to do a _mathematical_ comparison on _numbers_ to, instead, compare the _string representations_? also: a warning would be superfluous, because the way [floating point numbers work](https://floating-point-gui.de/) should be _basic knowledge_ for every programmer. (hint: those aren't decimals. `Decimal` is a numeric type for arbitrary decimal precision. **never** expect floating point numbers to be _precise_) – Franz Gleichmann Jan 11 '22 at 08:45
  • 1
    The compiler is not the one doing the comparison, the CPU is doing the comparison and it doesn't have access to the literal values, 0.4, it only has the actual values stored in the variables, and at runtime those values are different. The reason is, as you say, how floating point values are represented using 1's and 0's. And warnings occur at compile time, not runtime. We might *wish* for the systems to be able to do this as we expect them to, but in reality the best you can do is learn that there *is* an issue, and then how to cope with it. – Lasse V. Karlsen Jan 11 '22 at 08:45
  • You can force the compiler to do the comparison by making both variables `const`, but the compiler is made to reproduce the behavior at runtime in those cases so it will still execute `break`. – Lasse V. Karlsen Jan 11 '22 at 08:48
  • _"The compiler is not the one doing the comparison"_ The compiler always does some kind of comparison, it needs to compare types, if they are compatible for example. So that doesn't speak against a compiler that could throw a warning if someone compares in this way. However, it's not available as far as i know, i guess because the added value doesn't justify the costs. – Tim Schmelter Jan 11 '22 at 08:49
  • 1
    @TimSchmelter I agree, I was speaking to the fact that in this case, for that code, the compiler merely compiles the code, the actual comparison of the two floating point values is done at runtime. And sure, warnings could easily be done, ReSharper and Rider for instance does at least warn on using equality checks. It would be a welcome change if more IDEs or compilers came with that kind of feature. – Lasse V. Karlsen Jan 11 '22 at 08:50

0 Answers0