[R] The elegant way to test if a number is a whole number

William Dunlap wdunlap at tibco.com
Fri Sep 9 17:10:27 CEST 2011


Which of these functions is best really depends on
why you are interested in knowing whether a number
is integral or not.  Why are people interested in this?

I can think of a few

1) I have a C routine with the prototype
       void func(int *n)
   and to call it with .C() I need to make sure
   the data is stored as a C 'int' [4-byte signed
   integer].  The appropriate test is is.integer(n).

2) I have computed something that ought to be the
   length of an output vector.  E.g.,
   > n <- 7
   > len <- 1/6 * n * (n+1) * (n+2)
   > len
   [1] 84
   > length(complex(len)) # what?!
   [1] 83
   Here I wanted the test that len==trunc(len) or len==as.integer(len)
   because the constructor complex(len) converts len to an integer using
   truncation.

3) I am computing an integral that I know should give
   an integral result for certain inputs (e.g, the gamma
   function for nonnegative integral inputs) and I want to
   do some sanity checks on the output.  Then all.equal(x, round(x))
   or abs(x-round(x))<tolerance would be the right check.

Why are people interested in this question?

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com 

> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Martin Maechler
> Sent: Friday, September 09, 2011 1:41 AM
> To: Marc Schwartz
> Cc: r-help; Alexander Engelhardt
> Subject: Re: [R] The elegant way to test if a number is a whole number
... [ many lines elided ] ...
>     >>>>> 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
... [ many more lines elided ] ...



More information about the R-help mailing list