R: Странное поведение тригонометрической функции - PullRequest
4 голосов
/ 27 апреля 2011

Когда пользователь Matlab перешел на R, я столкнулся с проблемой применения тригонометрических функций к градусам. В Matlab есть тригонометрические функции для радиан и градусов (например, cos и cosd соответственно). Кажется, что R включает в себя только функции для радиан, поэтому я должен создать свои собственные (см. Ниже)

cosd<-function(degrees) {
  radians<-cos(degrees*pi/180)
  return(radians)
}

К сожалению, эта функция не всегда работает должным образом. Некоторые результаты показаны ниже.

> cosd(90)
[1] 6.123234e-17
> cosd(180)
[1] -1
> cosd(270)
[1] -1.836970e-16
> cosd(360)
[1] 1

Я бы хотел понять, что вызывает это и как это исправить. Спасибо!

Ответы [ 5 ]

8 голосов
/ 27 апреля 2011

Это арифметика с плавающей точкой:

> all.equal(cosd(90), 0)
[1] TRUE
> all.equal(cosd(270), 0)
[1] TRUE

Если это то, что вы имели в виду под "не работает должным образом"?

Это также FAQ: http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f

5 голосов
/ 27 апреля 2011

Похоже, это работает нормально для меня. Значение pi, вероятно, недостаточно точное, поэтому вы получаете очень точную оценку. Если вы подумаете об этом, 6.123234e-17 и -1.836970e-16 очень и очень близки к 0, что и должен быть ответ.

Ваша проблема заключается в том, что, хотя на бумаге 90 * pi / 180 = pi / 2, в компьютерах мы используем числа с плавающей запятой. Я не уверен, что R / Matlab использует, но я бы определенно предположил, 32-разрядное или 64-разрядное число с плавающей запятой. И вы можете разместить столько информации только в этом ограниченном количестве битов, поэтому вы не можете хранить все возможные десятичные числа.

Вы можете изменить свою функцию так, чтобы при заданных 90 или 270 возвращать 0.

1 голос
/ 27 апреля 2011

Вам также может быть интересна функция zapsmall для другого способа отображения чисел, близких к 0, как 0.

1 голос
/ 27 апреля 2011

По той же причине, что

1-(1/3)-(1/3)-(1/3)

не равно 0. Это имеет отношение к числам с плавающей запятой. Я уверен, что будет больше уточнений.

1 голос
/ 27 апреля 2011

Это ошибка представления с плавающей запятой. См. Главу 1 из http://lib.stat.cmu.edu/s/Spoetry/Tutor/R_inferno.pdf

...