Blob Blame History Raw
diff -up ./include/ignition/math/Helpers.hh.387 ./include/ignition/math/Helpers.hh
--- ./include/ignition/math/Helpers.hh.387	2016-07-08 14:48:37.000000000 -0400
+++ ./include/ignition/math/Helpers.hh	2016-07-17 20:26:47.060969825 -0400
@@ -142,6 +142,15 @@
 #define IGN_SQRT2 1.41421356237309504880
 #endif
 
+/// \brief Define IGN_FP_VOLATILE for FP equality comparisons
+/// Use volatile parameters when checking floating point equality on
+/// the 387 math coprocessor to work around bugs from the 387 extra precision
+#if defined __FLT_EVAL_METHOD__  &&  __FLT_EVAL_METHOD__ == 2
+#define IGN_FP_VOLATILE volatile
+#else
+#define IGN_FP_VOLATILE
+#endif
+
 /// \brief Compute sphere volume
 /// \param[in] _radius Sphere radius
 #define IGN_SPHERE_VOLUME(_radius) (4.0*IGN_PI*std::pow(_radius, 3)/3.0)
@@ -342,7 +351,8 @@ namespace ignition
     inline bool equal(const T &_a, const T &_b,
                       const T &_epsilon = 1e-6)
     {
-      return std::abs(_a - _b) <= _epsilon;
+      IGN_FP_VOLATILE T diff = std::abs(_a - _b);
+      return diff <= _epsilon;
     }
 
     /// \brief get value at a specified precision
diff -up ./src/Box.cc.387 ./src/Box.cc
--- ./src/Box.cc.387	2016-07-17 20:54:36.196586098 -0400
+++ ./src/Box.cc	2016-07-17 21:04:45.842717999 -0400
@@ -246,7 +246,7 @@ bool Box::ClipLine(const int _d, const L
 {
   // dimLow and dimHigh are the results we're calculating for this
   // current dimension.
-  double dimLow, dimHigh;
+  IGN_FP_VOLATILE double dimLow, dimHigh;
 
   // Find the point of intersection in this dimension only as a fraction of
   // the total vector http://youtu.be/USjbg5QXk3g?t=3m12s
@@ -262,20 +262,22 @@ bool Box::ClipLine(const int _d, const L
 
   // If this dimension's high is less than the low we got then we definitely
   // missed. http://youtu.be/USjbg5QXk3g?t=7m16s
-  if (dimHigh < _low)
+  IGN_FP_VOLATILE double low = _low;
+  if (dimHigh < low)
     return false;
 
   // Likewise if the low is less than the high.
-  if (dimLow > _high)
+  IGN_FP_VOLATILE double high = _high;
+  if (dimLow > high)
     return false;
 
   // Add the clip from this dimension to the previous results
   // http://youtu.be/USjbg5QXk3g?t=5m32s
   if (std::isfinite(dimLow))
-    _low = std::max(dimLow, _low);
+    _low = std::max(dimLow, low);
 
   if (std::isfinite(dimHigh))
-    _high = std::min(dimHigh, _high);
+    _high = std::min(dimHigh, high);
 
   return true;
 }