Почему Math.Atan (Math.Tan (x))! = X? - PullRequest
3 голосов
/ 22 ноября 2008

Если tan (x) = y и atan (y) = x, почему Math.Atan (Math.Tan (x))! = X?

Я пытаюсь вычислить x как-то так:

tan(2/x +3) = 5 

так

atan(tan(2/x + 3) = atan(5)

и так далее ... но я пробовал это:

double d = Math.Atan(Math.Tan(10));

и d! = 10. Почему?

Ответы [ 8 ]

36 голосов
/ 22 ноября 2008
  1. Функция тангенса периодична с периодом pi и обратима только , если вы ограничиваете ее подмножеством области, над которой она инъективна. Обычно выбор такого набора - открытый интервал] -pi / 2, pi / 2 [, поэтому функция arctan всегда будет возвращать точку в этом интервале. В вашем случае 10 = 3 * pi + 0,57522 ... Таким образом, арктан тангенса 10 вернет 0,57522 ...
  2. Обратите внимание, что функция arctan, определенная, как указано выше, является инъективной и определенной для всех действительных чисел, следовательно, обратная сторона вашей задачи
    math.tan(math.atan(x)) == x 
    действительно справедливо для каждого x (кроме числовых ошибок).
  3. Чтобы справиться с числовыми ошибками, вы никогда не должны сравнивать результаты вычислений с плавающей запятой, используя == или! =. Вместо этого используйте
    abs(number1 - number2) <  epsilon   // ==
    abs(number1 - number2) >= epsilon   // !=
    
    , где эпсилон - маленькая положительная константа.
8 голосов
/ 22 ноября 2008

График может помочь объяснить, почему вы не получаете ожидаемый результат.

alt text
(источник: wolfram.com )

http://mathworld.wolfram.com/Tangent.html

Здесь показан график Tan, но если вы представляете, что считываете значение x для данного y (например, y = 0), то в зависимости от того, какую «цепочку» Tan вы прочитали, вы получите другой ответ ( -пи, 0, пи ...). В том-то и дело, что у Arctan (x) более одного решения.

Если арктан был ограничен только одной из этих нитей, например -pi / 2

РЕДАКТИРОВАТЬ: Однако, согласно http://msdn.microsoft.com/en-us/library/system.math.atan.aspx, метод atan уже возвращает -pi / 2

РЕДАКТИРОВАТЬ (Ф.Р.): добавлен рисунок

7 голосов
/ 22 ноября 2008

Я не знаю C #, но математика говорит, что tan не обратим, только в небольшом интервале.

например. tan (pi) = 0 и tan (0) = 0. При запросе atan (0) это может быть 0 или pi (или каждое кратное число pi), поэтому результат находится в диапазоне от -pi / 2 .. pi /2.

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

3 голосов
/ 22 ноября 2008

tan -1 (tan (x)) == x для всех x in (-PI / 2, PI / 2).

1 голос
/ 21 декабря 2009
  1. Поскольку функция тангенса периодическая, нам нужно нормализовать входной угол. Math.Atan возвращает угол, θ , измеренный в радианах, такой, что -π / 2 ≤ θ ≤ π / 2 , поэтому имеет смысл нормализовать к этому диапазону (поскольку в любом случае он явно не будет ничего в этом диапазоне):

    double normalizedAngle = (angle + Math.PI / 2) % Math.PI - Math.PI / 2;
    
  2. Двойники должны сравниваться с некоторой погрешностью. Но на самом деле для этого случая Double.Epsilon слишком мало и «Если вы создаете пользовательский алгоритм, который определяет, можно ли считать два числа с плавающей точкой равными, вы должны использовать значение, которое больше Эпсилон константа для установления приемлемого абсолютного запаса разницы для двух значений, считающихся равными. (Как правило, этот запас разницы во много раз больше, чем Эпсилон .) "Например, Math.Atan(Math.Tan(-0.49999632679501449)) + 0.49999632679501449 будет больше Double.Epsilon для 1.1235582092889474E+307 раз.

0 голосов
/ 06 октября 2009

double d = Math.Atan (1) * (180 / Math.PI); поэтому d будет 45 градусов

0 голосов
/ 22 ноября 2008

Может быть полезно, если вы опубликовали то, что пытаетесь достичь. У меня есть воспоминания об обнаружении тригонометрических функций, которые обрабатывали проблему, например, в каком квадранте были входы для меня, когда я пытался играть с углами.

0 голосов
/ 22 ноября 2008

В общем, когда вы имеете дело с числами с плавающей точкой, вы имеете дело с аппроксимациями. Есть числа, которые не могут быть представлены точно, и операции tan и arctan сами по себе являются только приблизительными.

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

Вот некоторые часто задаваемые вопросы (для c ++, но идея та же самая), которые немного говорят о некоторых странностях чисел с плавающей запятой:

FAQ 29.16
FAQ 29.17
FAQ 29.18

Редактировать: Глядя на другие ответы, я понимаю, что главная проблема, вероятно, заключается в том, что загар не является обратимым, но вопрос аппроксимации тоже стоит рассмотреть, когда вы проверяете числа с плавающей запятой на равенство.

Глядя на документацию .net для Math.Atan , atan выдает значение от -π / 2 до ≤ π / 2, которое не включает 10. Я думаю, что это обычный диапазон для арктангенс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...