2014-01-08 3 views
0

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

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

# 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 равно и десятичная часть равна .7 (например, 22.7, 24.7, 26.7).

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

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

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

+0

Второй 'thetaSub' фактически находится под' -1'. –

+0

re: ваше редактирование, я расширил свой ответ с помощью возможного решения – James

ответ

7

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

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

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

+0

Это работает! Весьма признателен! – Chris

Смежные вопросы