Гиперболический тангенс в R выбрасывает NAN в Windows, но не в Mac?

При оценке гиперболического тангенса в Windows используется базовая функция R tanh для больших (действительных, с мнимой частью) значений функция возвращает "NaN":

tanh(356 + 0i)
> NaN + 0i

Однако в Mac это же значение возвращает 1 (совпадающее с "реальным" математическим значением должно быть близко к 1):

tanh(356 + 0i)
> 1 + 0i

Вопрос 1: Кто-нибудь знает, почему это происходит?

Дополнительная информация

Кажется, это не проблема с плавающей запятой, потому что кажется, что Mac tanh возвращает 1 для сколь угодно больших значений:

tanh(999999677873648767519238192348124812341234182374817239847812738481234871823+0i)
> 1 + 0i

Проблема, кажется, связана с мнимой частью как:

tanh(356)
> 1

в Windows и Mac. Похоже, что проблема связана с системой (или процессором?)- как мы уже пытались:

  • Mac с процессором El Capitan v 10.11.6 : Intel Core i5 с частотой 2,7 ГГц
  • Mac с процессором Sierra v 10.12.3 : 3,2 ГГц Intel Core i5
  • Процессор Windows 10 Home v 1607 : процессор Intel Core m3-SY30 @ 0,90 ГГц 1,51 ГГц
  • Процессор Windows 7 Home Premium с пакетом обновления 1 : процессор Intel Core i5-2410M @2,30 ГГц, 2,30 ГГц.

Эти машины Windows выбрасывают NaN Mac 1 + 0i, Во всех случаях мы используем версию 3.3.3 R "новейшую" (64-битную).

1 ответ

Решение

@ Бен Болкер прямо на месте. Windows использует несколько старые библиотеки C, и здесь это часть mathlib из glibc.

Более конкретно, согласно странице загрузки CRAN для R-devel для Windows https://cran.r-project.org/bin/windows/base/rdevel.html, серия R 3.3.z использует gcc 4.6.3 (Март 2012) toolchain, в то время как "R-devel", предстоящая (еще не выпущенная!) Серия R 3.4.z использует набор инструментов gcc 4.9.3 (июнь 2015).

** Однако * Я только что проверил (установил двоичный файл R-devel из CRAN на нашу виртуальную машину с Windows-сервером) и вижу, что проблема все еще существует: во вчерашней версии R-devel, tanh(500+0i) все еще возвращается NaN+0i,

Теперь я думаю, что лучшим решением было бы использовать внутреннюю замену R (в R src/main/complex.c): У нас есть

#ifndef HAVE_CTANH
#define ctanh R_ctanh
static double complex ctanh(double complex z)
{
    return -I * ctan(z * I); /* A&S 4.5.9 */
}
#endif

и мы должны использовать его, как я вижу, на самом деле, также на Windows,

R> -1i * tan((500+0i)*1i)

дает

[1] 1+0i

как следует для tanh(500+0i) --- но не на винде.

Другие вопросы по тегам