Неожиданное поведение в 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
вместо.