>>>>> Marc Schwartz <marc_schwa...@me.com> >>>>> on Thu, 8 Sep 2011 15:41:26 -0500 writes:
> On Sep 8, 2011, at 3:09 PM, David Winsemius wrote: >> >> On Sep 8, 2011, at 3:54 PM, Marc Schwartz wrote: >> >>> >>> On Sep 8, 2011, at 2:42 PM, David Winsemius wrote: >>> >>>> >>>> On Sep 8, 2011, at 3:35 PM, Alexander Engelhardt wrote: >>>> >>>>> Am 08.09.2011 20:48, schrieb Marc Schwartz: >>>>> There was a post from Martin Maechler some years ago and I had to >>>>> search a bit to find it. For these sorts of issues, I typically trust >>>>> his judgement. thank you, Marc! :-) >>>>> The post is here: >>>>> >>>>> https://stat.ethz.ch/pipermail/r-help/2003-April/032471.html >>>>> >>>>> His solution also handles complex numbers. >>>>> >>>>> For those too lazy to follow >>>>> He is basically creating the function is.whole: >>>>> >>>>> is.whole <- function(x) >>>>> is.numeric(x) && floor(x)==x >>>> >>>> Are you sure? I thought the test would have been all.equal(x, >>>> round(x,0) ) Yes, I was *very* sure that the is.whole() above should be exactly what it was: The purpose was really different. There, the discussion started from the fact that as.integer(1) gives FALSE in R and that some people where making a fuzz about the allegedly poor design of S and R in that regard. The purpose of the above is.whole() was solely to be a concise *alternative* to is.integer(), -- which even would work with complex numbers, as Marc mentioned... and BTW, instead of floor(), trunc(), or ceiling() or even round() would have been equally valid. I had chosen floor() because in mathematics, it is the most frequently used of those four functions. Your topic below ... about accidental rounding or not with floating point arithmetic is an entirely different issue, *and* I agree that a solution to your problem should be based on the same calculations as all.equal.numeric() .. and hence will be considerably more involved if it should "work" in all border cases. Martin Maechler, ETH Zurich >>>> My reasoning was that 1.999999999999 should be considered 2 but >>>> floor would make it 1. >>> >>> David, I am confuzzled. Why would that be equal to 2? >> >> So that sqrt(3) * sqrt(3) would be a "whole number". (It is true the >> the floor based wholeness criterion would make sqrt(2)*sqrt(2) >> >> Somehow it doesn't see "right" that only half of square roots of >> integers that have been squared should pass the wholeness test: >> >> > is.whole <- function(a, tol = 1e-7) { >> + is.eq <- function(x,y) { >> + r <- all.equal(x,y, tol=tol) >> + is.logical(r) && r >> + } >> + (is.numeric(a) && is.eq(a, floor(a))) || >> + (is.complex(a) && {ri <- c(Re(a),Im(a)); is.eq(ri, floor(ri))}) >> + } >> > is.whole( sqrt(2)^2 ) >> [1] TRUE >> > is.whole( sqrt(3)^2 ) >> [1] FALSE >> > <snip content> > OK. I suspect it may down to what assumptions one is willing to make, > including the level of tolerance used for the comparison. > is.whole() of course works for 2 because: >> print(sqrt(2) ^ 2, 20) > [1] 2.0000000000000004441 > is slightly larger than 2, so: >> floor(sqrt(2) ^ 2) > [1] 2 > works, as does: >> round(sqrt(2) ^ 2, 0) > [1] 2 > On the other hand: >> print(sqrt(3) ^ 2, 20) > [1] 2.9999999999999995559 > is slightly smaller than 3, so: >> floor(sqrt(3) ^ 2) > [1] 2 > versus: >> round(sqrt(3) ^ 2, 0) > [1] 3 > Not sure if Martin (cc'd now) might have any comments 8 plus years > later relative to this issue, as I would again defer to his judgement > here. > The other solution proposed, using modulo division, would logically > fail in both cases: >> (sqrt(3) ^ 2) %% 1 == 0 > [1] FALSE >> (sqrt(2) ^ 2) %% 1 == 0 > [1] FALSE > Regards, > Marc ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.