Неожиданное поведение в asin()

Я сталкиваюсь с странным поведением с asin() функция в R. У меня есть выражение, которое иногда оценивается в -1, что я передаю asin(), Иногда asin() отвечает ожидаемым значением asin(-1) = 1.57.... в других случаях он отвечает NaNs produced,

Приведенный ниже код дает пример (из более крупной функции, которая вычисляет дни выращивания насекомых):

 # works
 tempMax <- 22.6
 tempMin <- 10.0
 threshold <- 10

 meanT     <- (tempMax + tempMin) / 2

 amplitude <- (tempMax - tempMin) /2

 thetaSub <- ( (threshold - meanT)/amplitude )

 thetaOut  <- asin( thetaSub)

 # fails
tempMax <- 22.7
tempMin <- 10.0
threshold <- 10

meanT     <- (tempMax + tempMin) / 2

amplitude <- (tempMax - tempMin) /2

thetaSub <- ( (threshold - meanT)/amplitude )

thetaOut  <- asin( thetaSub)

Обратите внимание, что в обоих примерах thetaSub оценивает до -1, но asin только "работает" в первом примере.

При тестировании функции кажется, что я получаю NaNs, когда tempMin == threshold и целочисленное значение tempMax является четным, а десятичная часть равна 0,7 (например, 22,7, 24,7, 26,7).

Я подозреваю, что это не причина, а просто другие случаи, которые вызывают ту же ошибку. Я предполагаю, что это как-то связано с тем, как значение thetaSub интерпретируется asin, но я не могу понять, почему это работает иногда, а не другие.

редактировать.

@James определил мою проблему как проблему с плавающей запятой. Как заставить асин "игнорировать" десятичные знаки?

1 ответ

Решение

Это проблема с плавающей запятой. Способ работы чисел с плавающей запятой состоит в том, что все числа должны быть сопоставлены с ближайшим, которое может быть выражено как конечная сумма степеней двух, и это может привести к небольшим неточностям в ожидаемом результате и может зависеть от того, как числа рассчитывается.

print(thetaSub,digits=22)
[1] -1.000000000000000222045

Вы должны изменить свой код для использования asin(max(-1,min(1,thetaSub))) защитить от этой проблемы. Если вы делаете вычисления в векторизованном виде, используйте pmax а также pmin вместо.

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