Почему Math.Atan (Math.Tan (x))! = X?

Если 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. Почему?

Math.Tan (10) возвращает тангенс угла 10 радианы, а не 10 градусы, как я подозреваю, вы думали.

Hans Kesting 14.10.2009 13:30
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
8 817
8

Ответы 8

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

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

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

  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   // !=
    
    , где эпсилон - небольшая положительная константа.

Просто обратите внимание: в C# есть константа Double.Epsilon, которая представляет значение epsilon для типа данных double.

lacop 22.11.2008 19:54

AFAIK (но поправьте меня, если я ошибаюсь) в C# Math.Abs ​​(n1 - n2) <Double.Epsilon совпадает с n1 == n2, поскольку по определению все, что имеет меньшее абсолютное значение, чем Double.Epsilon, равно нулю. Math.Abs ​​(n1 - n2) <= Double.Epsilon было бы лучше ИМХО

Tamas Czinege 22.11.2008 20:12

Обратите внимание, что константа Double.Epsilon представляет собой наименьшее положительное значение Double больше нуля. Он не работает ни в каком другом домене.

dalle 22.11.2008 21:17

Питер Ричи / Томас Ли: Это значение не определяется как наименьшее положительное число x, такое, что x + 1.0 не равно 1.0, поэтому Double.Epsilon нельзя использовать для «почти равенства». В структуре не существует константы, значение которой является наименьшим положительным числом x, такое, что x + 1.0 не равно 1.0.

dalle 22.11.2008 21:18

Да, выбор epsilon зависит от конкретного приложения. Фреймворк не может иметь какой-то эпсилон, который работает везде.

mmx 12.01.2009 15:46

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

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

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

FAQ 29.16
FAQ 29.17
FAQ 29.18

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

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

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

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

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

alt text
(source: wolfram.com)

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

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

Если arctan был ограничен только одной из этих нитей, например -pi / 2 <x <pi / 2, тогда Arctan (tan (x)) вернет x, если вы учли ошибки с плавающей запятой.

Обновлено: Однако, согласно http://msdn.microsoft.com/en-us/library/system.math.atan.aspx, метод atan уже возвращает -pi / 2 <x <pi / 2 или NaN, если ваш ввод не определен. Таким образом, проблема должна заключаться только в округлении с плавающей запятой.

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

"проблема должна быть связана только с округлением с плавающей запятой" - неправильный вывод, потому что atan просто возвращается из интервала, не решает математический фон - просто возьмите свой карманный калькулятор и (который ведет себя так же) и вычислите исходный пример

flolo 22.11.2008 21:22

двойной d = Math.Atan (1) * (180 / Math.PI); так что d будет 45 градусов

здесь Tan-1 возвращается в степень к d

sujitha 06.10.2009 14:44
  1. Поскольку функция касательной является периодической, нам необходимо нормализовать входной угол. Математика. Атан возвращает угол, θ, измеренный в радианах, такой как -π / 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 раз.

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