Skip to content

Commit

Permalink
interp: fix GE/LE operators to better handle double-precision comparison
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
snowgoer540 committed Jun 17, 2023
1 parent f15826f commit 014777a
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 13 deletions.
9 changes: 4 additions & 5 deletions docs/src/gcode/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down
12 changes: 6 additions & 6 deletions src/emc/rs274ngc/interp_execute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/emc/rs274ngc/interp_internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 014777a

Please sign in to comment.