Skip to content

Instantly share code, notes, and snippets.

@hzhou
Last active February 27, 2017 00:58
Show Gist options
  • Save hzhou/1bb7bf5edb18a62a32ca001da33d9806 to your computer and use it in GitHub Desktop.
Save hzhou/1bb7bf5edb18a62a32ca001da33d9806 to your computer and use it in GitHub Desktop.
Undefined Behaviors -- a comment on HN gcc floating point "bug"

People need understand that floating point comparison at floating precision is undefined, so it is not a bug. The proper floating number representation should track its precision. Since that is more complicated and potentially performance affecting, so until then the programmer should manage the precision tracking on their own (similar to memory allocations), that is, one should do:

  if ( f_a < f_b-f_eps)
  if ( f_a > f_b+f_eps)
  if (fabs(f_a-f_b)<f_eps)

If you don't do this, then you are on your own. Sometimes it is fine, but sometimes it may give you grief, just like the dangers of other undefined behaviors.

PS: I also have a problem that people think "undefined behavior" is undefined because certain standards say so. Undefined behavior is due to lack of agreement of common sense or it defies common sense. For example, divide by zero, there is no common sense doing so, and define its behavior does not change anything. Signed integer overflow, there is no common sense agreement for that behavior either. The common sense for undefined behaviors is to avoid it. (On the other hand, there seems to be some common sense agreement on unsigned integer overflow, and people are writing code based on that behavior. But that agreement is weak, so I would avoid it if I can regardless what the standards say.)

PS2: The reason that floating point comparison is undefined behavior because, unlike fixed precision or integers, floating point number has floating precision. Floating precision does not have common sense correspondence. In any real application (where common sense is based), a finite, and above all, consistent precision, is always assumed.

And the solution, by manually specifying a f_eps, we put that comparison into a common-sense understanding that you know the result of comparisons is only meaningful above f_eps. With that common sense, having an internal calculation in higher precision is always OK -- isn't that common sense?

PS3: The question is why not turn undefined behaviors into errors? Undefined behavior does not mean there are no behaviors, and the behaviors can be used to achieve certain efficiency. When programmers write code with undefined behaviors, they are extracting their code out of common sense domain, but into a special sense domain. Special sense domain is practically fine. Everyone has their own efficient quirks, just do not expect your quirks to be understood or supported by out large where common sense rules. A language that allows for undefined behaviors allows for individual efficiency, which sometimes it is rather good.

For example, it is ok to write programs with direct floating point number comparisons as long as you understand that your program do not care when the comparison falls into the ambiguos range. Only you who understands your special application can assess that. If you are the only one who is responsible for the result of that code, then it is perfectly fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment