One property that is slightly different in Equal and SameQ that will seem significant to people who program with floating-point numbers (Real objects) is that they compare with relative tolerance. Equal uses a greater tolerance than SameQ. Two numbers test as the same if they differ only in their last seven, resp. one, bit(s).
1. + (2^6) $MachineEpsilon == 1.
1. + (2^6 + 1) $MachineEpsilon == 1.
(*
True
False
*)
1. + $MachineEpsilon === 1.
1. + 2 $MachineEpsilon === 1.
(*
True
False
*)
To test if Real numbers are actually the same, I test the difference against zero: x - y == 0.
LessEqual, GreaterEqual also test with tolerance. So that x <= y can be true but x - y <= 0 will be false. Likewise, x <=y <= z can be true, but x <= z can be false.
1. + (2^6 + 1) $MachineEpsilon <= 1. + (2^6) $MachineEpsilon <= 1.
1. + (2^6 + 1) $MachineEpsilon <= 1
(*
True
False
*)
The tolerances are system parameters, Internal`$EqualTolerance (= Log10[2.^7]) and
Internal`$SameQTolerance (= Log10[2.]), that users can change. (Just because users can change it does not mean the system won't reset it during an internal computation.) Compile[] has a runtime option "CompareWithTolerance" that controls it.
I once thought I could use MatchQ[x, y] to strictly compare Real numbers x and y. But no, MatchQ[] seems to do this: Round up x and y from a 53-bit mantissa to 52 bits and returns whether the rounded numbers are the same. This is undocumented, AFAIK, and I do not have an explanation for it.
MatchQ[1., 1. + $MachineEpsilon]
MatchQ[1. + $MachineEpsilon, 1. + 2 $MachineEpsilon]
MatchQ[1. + 2 $MachineEpsilon, 1. + 3 $MachineEpsilon]
(*
False
True
False
*)