I wrote a (potentially not particularly good!) function to test if a number is a whole number or not:
is.wholeNumber <- function(x) x == floor(x)
In general this function works fine for my purpose as I am really only considering cases where I'm testing numbers with a handful of deciminal places, so my naive understanding was that machine precision shouldn't be a factor.
When I apply this function in the case 45 x 1.4 = 63, however I get
> is.wholeNumber( 45 * 1.4)
[1] FALSE
This appears to occur because the floor function of R is not evaluating as I would expect:
> floor(45 * 1.4)
[1] 62
which should in fact be 63.
On doing some reading I came across this popular post about how to code this in R. The top voted answer there suggests the function
is.wholeNumber <- function(x) ( x %% 1 ) == 0
which again does not appear to work in my context, since I get
> (45 * 1.4 ) %% 1
[1] 1
The second most upvoted post suggests using
is.wholeNumber <- function(x) all.equal(x, as.integer(x))
and whilst once again this does not work, it does give the illuminatingly unexpected output of
> is.wholeNumber( 45 * 1.4)
[1] "Mean relative difference: 0.01587302"
I have now tried this in both a clean R studio workspace, and from R terminal (R 3.4.2 Short Summer) and duplicated this issue. I'd be interested to know:
Following function will give you correct results:
is.wholeNumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With