jhasse / poly2tri

2D constrained Delaunay triangulation library
BSD 3-Clause "New" or "Revised" License
429 stars 89 forks source link

Avoid triggering Werror=float-equal #32

Open starseeker opened 2 years ago

starseeker commented 2 years ago

Our code uses the Werror=float-equal warning, which trips on the shapes.h header. This is an attempt to work around triggering that warning.

jhasse commented 2 years ago

Thanks! See e0ba327ed83f3e32933cf6cc4f61fabc50191711, #11 and #12. Ideally I would like to fix this once and for all, as it has caused problems in my code. Not sure how though, comparing floats is so hard :/

starseeker commented 2 years ago

Hmm... yeah, I don't know of a simple answer. The two main approaches seem to be clamping to integer space (what the Bitfighter folks did, IIRC: https://github.com/acres-com-au/clip2tri) and various approaches to supporting quasi-arbitrary precision (which are relatively complex and slower, as I understand it.)

pr0g commented 1 year ago

Just spotted this and wanted to mention this fantastic article by Bruce Dawson on comparing floating point numbers - Comparing Floating Point Numbers, 2012 Edition.

The solution I've used in my own code, taken from this article (that doesn't involve using ULPs) looks like this...

// floating point comparison by Bruce Dawson
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
bool float_near(
  const float a,
  const float b,
  const float max_diff,
  const float max_rel_diff) {
  // check if the numbers are really close
  // needed when comparing numbers near zero
  const float diff = fabsf(a - b);
  if (diff <= max_diff) {
    return true;
  }
  const float largest = fmaxf(fabsf(a), fabsf(b));
  // find relative difference
  return diff <= largest * max_rel_diff;
}

And then max_diff and max_rel_diff are usually std::numeric_limits<float>::min()/FLT_MIN by default but can be tuned depending on the situation.