This is a common problem discussed before and very well explained HERE
However, all the answers I've found all explain different ways to handle equality, but I don't think any of them are particularly good or readable in code and most importantly cannot be used for other operators such as <, >, <=, >= or ! (not).
My preferred method is using rounding, but only for comparisons as below:
> options(digits = 20)
> x <- cbind(c(1:10)/100*9,c(1:10)/10,c(1:10)/100)
> x
[,1] [,2] [,3]
[1,] 0.089999999999999997 0.10000000000000001 0.010000000000000000
[2,] 0.179999999999999993 0.20000000000000001 0.020000000000000000
[3,] 0.270000000000000018 0.29999999999999999 0.029999999999999999
[4,] 0.359999999999999987 0.40000000000000002 0.040000000000000001
[5,] 0.450000000000000011 0.50000000000000000 0.050000000000000003
[6,] 0.540000000000000036 0.59999999999999998 0.059999999999999998
[7,] 0.630000000000000115 0.69999999999999996 0.070000000000000007
[8,] 0.719999999999999973 0.80000000000000004 0.080000000000000002
[9,] 0.809999999999999942 0.90000000000000002 0.089999999999999997
[10,] 0.900000000000000022 1.00000000000000000 0.100000000000000006
> x[,1]==x[,2]-x[,3]
[1] FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE TRUE
> round(x[,1],15)==round(x[,2]-x[,3],15)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> round(x[,1],15)<=round(x[,2]-x[,3],15)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Rounding close the precision limit gives good results and will work with other operators and to me seems easier to read than other functions but I figure will still cause it's own error at times.
Is there a best practice method to deal with this error that is compact and easily readable, and can be used with multiple operators?
Or even better, is it possible to have a set of alternate operators such as ~==
or ~<=
that will automatically round to precision limits such that I don't need to constantly think about them?
Edit To better explain why I asked this question is that this is more than just handling equality. Which has already been answered.
However from my example in row 3 0.270000000000000018 > .27
and 0.29999999999999999 > .3
and 0.029999999999999999 < .03
. but the sum is 0.30000000000000004
not 0.29999999999999999
so These are the cases where < and > will break as well, as values can arbitrarily become < or >.
In this case I would add or subtract a small value .27 + .02 < .3 +.000001
but that always changes on a case by case or even a use by use basis.
I am working with data where I am doing comparisons and I am constantly seeing errors specifically with < and > and I have to constantly make code adjustments to deal with it. I want something so that I don't need to add so much extra code to deal with this.