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;
}