NA получены целочисленным переполнением + R в Linux - PullRequest
4 голосов
/ 18 мая 2011

Я выполняю сценарий R в системе на основе UNIX, сценарий содержит умножение больших чисел, поэтому результаты, когда NA с целочисленным переполнением, но когда я запускаю тот же сценарий в Windows, эта проблема не появляется.

но я должен держать скрипт работающим всю ночь на рабочем столе (который является Unix).

есть ли решение этой проблемы?

спасибо

for(ol in seq(1,nrow(yi),by=25))
    {
    for(oh in seq(1,nrow(yi),by=25))
 {

        A=(N*(ol^2)) + ((N*(N+1)*(2*N+1))/6) -(2*ol*((N*N+1)/2)) + (2*N*ol*(N-oh+1)) + ((N-oh+1)*N^2) + (2*N*(oh-N-1)*(oh+N))


}
}

    with :
N=16569 = nrow(yi)

, но первый раунд не рассчитывается на Unix.

Ответы [ 3 ]

5 голосов
/ 19 мая 2011

Как уже указывалось в других ответах, в ваших результатах есть что-то немного невоспроизводимое / странное. Тем не менее, если вам действительно необходимо выполнять точные вычисления для больших целых чисел, вам, вероятно, нужен интерфейс между 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?

3 голосов
/ 18 мая 2011

Учитывая ваши комментарии, я полагаю, что вы серьезно неправильно понимаете "правильность" чисел в R. Вы говорите, что результат, который вы получаете в Windows, примерно такой, как -30598395869593930593. Теперь, как на 32-битной, так и на 64-битной системе точность даже невозможна при использовании двойного числа, не говоря уже о целом числе:

> x <- -30598395869593930593
> format(x,scientific=F)
[1] "-30598395869593931776"
> all.equal(x,as.numeric(format(x,scientific=F)))
[1] TRUE
> as.integer(x)
[1] NA

У вас есть 16 цифр, которым вы можете доверять, все остальное - бред. Опять же, точность 16 цифр уже довольно сильна. Большинство измерительных инструментов даже близко не подходят к этому.

3 голосов
/ 18 мая 2011

Можете ли вы привести ваши целые числа к числам с плавающей точкой, чтобы использовать математические вычисления с плавающей точкой для вычислений?

Например:

> x=as.integer(1000000)
> x*x
[1] NA
Warning message:
In x * x : NAs produced by integer overflow
> x=as.numeric(1000000)
> x*x
[1] 1e+12

Кроме того, не совсем понятно, почему предупреждение появляется в одной среде, а не в другой. Сначала я подумал, что 32-битные и 64-битные сборки R могут использовать 32-битные и 64-битные целые числа соответственно, но не похоже на . Обе ли ваши среды настроены одинаково с точки зрения отображения предупреждений?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...