5

The number of ways of choosing k objects from n, i.e. the binomial coefficient n!/(k!(n-k)!), is an integer when n and k are integers. How can I calculate this guaranteeing that the result is both correct and of integer type? The choose function returns a double even with integer arguments:

> typeof(choose(4L, 2L))  
[1] "double"  

as does manual calculation, e.g. n-choose-2 = n(n-1)/2

typeof((4L * (4L - 1L)) / 2L)
[1] "double"  

Of course I can coerce to an integer with as.integer() but I'm nervous about machine precision:

> as.integer(3.999999999999999)
[1] 3
> as.integer(3.9999999999999999)
[1] 4

round() (with the default digits=0) rounds to the nearest integer, but returns a value of double type. If I could be certain that supplying an integer stored in double format to as.integer(round(...)) is guaranteed to round to the correct integer, never being tripped up by machine precision, then as.integer(round(choose(n, k))) would be acceptable. Is this the case? Or is there an alternative to choose() that will return an integer for integer arguments?

ChrisW
  • 1,265
  • 12
  • 12
  • 1
    `typeof((4L * (4L - 1L)) %/% 2L)` will give you integer , if you choose to use `%/%` instead of `/` you will get integer – PKumar Jun 12 '18 at 12:41
  • I'm not sure that it is what @ChrisW wants... because `5 %/% 2 = 2` – Emmanuel-Lin Jun 12 '18 at 13:38
  • Indeed, I don't think that answers my question. – ChrisW Jun 12 '18 at 14:12
  • Since n!/(k!(n-k)!) will always return an integer if n and k are integers, there is no need to `round` it, just do `as.integer(choose(n, k))`. you only need rounding if your inputs are non-integers. – acylam Jun 12 '18 at 18:44

2 Answers2

0

One way is to use the VeryLargeIntegers package. The function is:

binom(n, k)

e.g. binom(1000,50) or even binom(10000000,50)

It's wise to learn how to make very large integers too cf: as.vli('1234567890123456789')

https://www.rdocumentation.org/packages/VeryLargeIntegers/versions/0.1.8/topics/06.%20Binomial%20coefficients

The package is not completely bug-free, and larger computations will take a while.

Dr Jo.

0

Do not worry about the conversion, the machine precision will not be a problem. L after the integer is definitely not a double, [R] has a weird syntax, it is definitely not a long value and cannot have a decimal point.

navarq
  • 1,075
  • 2
  • 15
  • 20