Another solution is to use a bit of arithmetic:
is.natural2 <- function(x,tol=.Machine$double.eps^0.5){ sign(x) - abs(x-round(x)) >= 1-tol }
Now, checking all the solutions, it turned out that one of Tal and one of the caracal did not give the correct result:
is.natural <- function(x) { x>0 & identical(round(x), x) } is.natural2 <- function(x,tol=.Machine$double.eps^0.5){ sign(x) - abs(x-round(x)) >= 1-tol } is.natural3 <- function(x, dig=15){ x > 0 & zapsmall(x, dig) == round(x) } is.natural4 <- function(x,tol=.Machine$double.eps^0.5){ x > 0 & isTRUE(all.equal(x,round(x), tolerance=tol, check.attributes=FALSE, check.names=FALSE)) } is.naturalnumber <- function(x, tol = .Machine$double.eps^0.5){ x > 0 & abs(x - round(x)) < tol }
Then:
> X <- (seq(0,3,by=0.5)^0.5)^2 > is.natural(X) [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE # wrong > is.natural2(X) [1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE > is.natural3(X) [1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE > is.natural4(X) [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE # wrong > is.naturalnumber(X) [1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE
Regarding time:
> X <- (seq(0,1000000,by=0.5)^0.5)^2 > system.time(is.natural2(X)) user system elapsed 0.24 0.03 0.26 > system.time(is.natural3(X)) user system elapsed 0.67 0.00 0.67 > system.time(is.naturalnumber(X)) user system elapsed 0.22 0.01 0.23
what makes marcogue a winner.
source share