For machine-precision numbers, Mathematica uses a tolerance for comparisons, so that 1.-$MachineEpsilon==1.
However, Floor
does not take into account this tolerance, leading to an inconsistency:
{Floor[#], # < 1., # >= 1.} &[1. - $MachineEpsilon]
(*{0, False, True}*)
(*Should be {1,False,True} or {0,True,False}*)
For the particular piece of code this affects, I am using Compile
and so can just set the RuntimeOptions
to not CompareWithTolerance
(which is what Floor
assumes). However, I thought it worth asking if it is possible to avoid this in general, or is it necessary to refactor code that assumes this consistency?
For what it's worth, it also appears to be inconsistent with the documentation which states that "Floor[x]
gives the greatest integer less than or equal to x" and the documentation gives an example of it working correctly for an arbitrary-precision number, e.g. Floor[1`100 - 10^-130]==1
Floor[1`100 - 10^-130]==1
is listed under "Possible Issues", which indicates that it doesn't necessarily work as expected; this is because you're specifying a precision of 100 digits with1`100
, whereas1.
is specified asMachinePrecision
; clearly10^-130
would require more than 130 digits of precision, and so is neglected in evaluation. $\endgroup$Less
. This doesn't particularly bother me. However, the definition of equality should be consistent throughout. The greatest integer less than or equal to1.-$MachineEpsilon
is 1 according toLess
and 0 according toFloor
. It gives a bug in code such asIf[1<=x<Length[list]+1,list[[Floor[x]]],0]
. If x is1.-$MachineEpsilon
, we getHead[list]
rather than 0 orlist[[1]]
as expected. $\endgroup$