Как уже указывалось в других ответах, в ваших результатах есть что-то немного невоспроизводимое / странное. Тем не менее, если вам действительно необходимо выполнять точные вычисления для больших целых чисел, вам, вероятно, нужен интерфейс между R и какой-либо другой системой.
Некоторые из ваших вариантов:
- пакет
gmp
(см. эту страницу и прокрутите вниз до R
- интерфейс к калькулятору
bc
в googlecode
- на вики-странице R имеется высокоточная арифметическая страница, которая сравнивает интерфейсы с Yacas, bc и MPFR / GMP
в пакете elliptical
имеется ограниченный интерфейс к пакету PARI / GP, но, вероятно, (намного) он менее полезен, чем предыдущие три варианта
В большинстве систем Unix или Cygwin уже должна быть установлена bc. GMP и Yacas легко установить на современные системы Linux ...
Вот расширенный пример с функцией, которая может выбирать числовые, целочисленные или bigz
вычисления.
f1 <- function(ol=1L,oh=1L,N=16569L,type=c("num","int","bigz")) {
type <- match.arg(type)
## convert all values to appropriate type
if (type=="int") {
ol <- as.integer(ol)
oh <- as.integer(oh)
N <- as.integer(N)
one <- 1L
two <- 2L
six <- 6L
cc <- as.integer
} else if (type=="bigz") {
one <- as.bigz(1)
two <- as.bigz(2)
six <- as.bigz(6)
N <- as.bigz(N)
ol <- as.bigz(ol)
oh <- as.bigz(oh)
cc <- as.bigz
} else {
one <- 1
two <- 2
six <- 6
N <- as.numeric(N)
oh <- as.numeric(oh)
ol <- as.numeric(ol)
cc <- as.numeric
}
## if using bigz mode, the ratio needs to be converted back to bigz;
## defining cc() as above seemed to be the most transparent way to do it
N*ol^two + cc(N*(N+one)*(two*N+one)/six) -
ol*(N*N+one) + two*N*ol*(N-oh+one) +
(N-oh+one)*N^two + two*N*(oh-N-one)*(oh+N)
}
Я удалил много ненужных скобок, которые фактически усложнили понимание того, что происходит. Действительно, для случая (1,1) конечный результат не превышает .Machine$integer.max
, но некоторые промежуточные шаги ... (для случая (1,1) это фактически сводится к $$ - 1 / 6 * (N + 2) * (4 * N ^ 2-5 * N + 3) $$ ...)
f1() ## -3.032615e+12
f1() > .Machine$integer.max ## FALSE
N <- 16569L
N*(N+1)*(2*N+1) > .Machine$integer.max ## TRUE
N*(N+1L)*(2L*N+1L) ## integer overflow (NA)
f1(type="int") ## integer overflow
f1(type="bigz") ## "-3032615078557"
print(f1(),digits=20) ## -3032615078557: no actual loss of precision in this case
PS: у вас есть (N*N+1)
член в вашем уравнении. Должно ли это быть N*(N+1)
, или вы действительно имели в виду N^2+1
?