From 014777a816991682748e500dc1e5de7e844c7d3e Mon Sep 17 00:00:00 2001 From: Greg Carl <26096779+snowgoer540@users.noreply.github.com> Date: Sat, 17 Jun 2023 11:49:28 -0400 Subject: [PATCH] interp: fix GE/LE operators to better handle double-precision comparison This commit does four things: 1. Changes the LE/GE operators to better handle double-precision floating-point comparisons. When comparing two values as equal (or not equal) the EQ and NE operators considered the floating-point precision "issue" by comparing the difference between the two values to TOLERANCE_EQUAL, GE and LE did not. 2. Tidy the difference by using fabs() 3. Modify the TOLERANCE_EQUAL threshold to 1e-6. Previously this was set to .0001 which is very close to a reasonable difference between two gcode coordinate values. 4. Update the documentation to reflect these change. --- docs/src/gcode/overview.adoc | 9 ++++----- src/emc/rs274ngc/interp_execute.cc | 12 ++++++------ src/emc/rs274ngc/interp_internal.hh | 4 ++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/src/gcode/overview.adoc b/docs/src/gcode/overview.adoc index 6d8a1e7ac8f..de07e876dc9 100644 --- a/docs/src/gcode/overview.adoc +++ b/docs/src/gcode/overview.adoc @@ -704,11 +704,10 @@ false, and any non-zero number is equivalent to logical true. == Equality and floating-point values -The RS274/NGC language only supports floating-point values of finite -precision. Therefore, testing for equality or inequality of two -floating-point values is inherently problematic. The interpreter -solves this problem by considering values equal if their absolute -difference is less than 0.0001 (this value is defined as +Testing for equality or inequality of two +double-precision floating-point values is inherently problematic. +The interpreter solves this problem by considering values equal if +their absolute difference is less than 1e-6 (this value is defined as 'TOLERANCE_EQUAL' in src/emc/rs274ngc/interp_internal.hh). [[gcode:functions]] diff --git a/src/emc/rs274ngc/interp_execute.cc b/src/emc/rs274ngc/interp_execute.cc index 7897ba7ae48..4e0367f8467 100644 --- a/src/emc/rs274ngc/interp_execute.cc +++ b/src/emc/rs274ngc/interp_execute.cc @@ -158,20 +158,20 @@ int Interp::execute_binary2(double *left, //!< pointer to the left operan *left = (*left < *right) ? 1.0 : 0.0; break; case EQ: - diff = *left - *right; - diff = (diff < 0) ? -diff : diff; + diff = fabs(*left - *right); *left = (diff < TOLERANCE_EQUAL) ? 1.0 : 0.0; break; case NE: - diff = *left - *right; - diff = (diff < 0) ? -diff : diff; + diff = fabs(*left - *right); *left = (diff >= TOLERANCE_EQUAL) ? 1.0 : 0.0; break; case LE: - *left = (*left <= *right) ? 1.0 : 0.0; + diff = fabs(*left - *right); + *left = ((diff < TOLERANCE_EQUAL) || (*left <= *right)) ? 1.0 : 0.0; break; case GE: - *left = (*left >= *right) ? 1.0 : 0.0; + diff = fabs(*left - *right); + *left = ((diff < TOLERANCE_EQUAL) || (*left >= *right)) ? 1.0 : 0.0; break; case GT: *left = (*left > *right) ? 1.0 : 0.0; diff --git a/src/emc/rs274ngc/interp_internal.hh b/src/emc/rs274ngc/interp_internal.hh index 15092fa75ba..99547e3db0e 100644 --- a/src/emc/rs274ngc/interp_internal.hh +++ b/src/emc/rs274ngc/interp_internal.hh @@ -87,8 +87,8 @@ Tighter tolerance down to a minimum of 1 micron +- also accepted. #define SPIRAL_RELATIVE_TOLERANCE 0.001 /* angle threshold for concavity for cutter compensation, in radians */ -#define TOLERANCE_CONCAVE_CORNER 0.05 -#define TOLERANCE_EQUAL 0.0001 /* two numbers compare EQ if the +#define TOLERANCE_CONCAVE_CORNER 0.05 +#define TOLERANCE_EQUAL 1e-6 /* two numbers compare EQ if the difference is less than this */ static inline bool equal(double a, double b)