Гиперболический тангенс в 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)
--- но не на винде.