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

Marc Schwartz marc_schwartz at me.com
Thu Sep 8 22:41:26 CEST 2011

```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.
>>>>>
>>>>> 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) )
>>>
>>> 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

```