




Я не знаю C#, но математика говорит, что tan не может быть инвертирован, только за небольшой промежуток времени.
например tan (pi) = 0 и tan (0) = 0. При запросе atan (0) это может быть 0 или пи (или каждое кратное пи), поэтому результат находится в диапазоне от -pi / 2 .. pi / 2.
Даже если вы начинаете с x в инвертируемом диапазоне, i не должен работать из-за ошибок округления с плавающей запятой (у него нет неограниченной точности).
math.tan(math.atan(x)) == x
действительно выполняется для каждого x (за исключением численных ошибок).abs(number1 - number2) < epsilon // ==
abs(number1 - number2) >= epsilon // !=
, где эпсилон - небольшая положительная константа.Просто обратите внимание: в C# есть константа Double.Epsilon, которая представляет значение epsilon для типа данных double.
AFAIK (но поправьте меня, если я ошибаюсь) в C# Math.Abs (n1 - n2) <Double.Epsilon совпадает с n1 == n2, поскольку по определению все, что имеет меньшее абсолютное значение, чем Double.Epsilon, равно нулю. Math.Abs (n1 - n2) <= Double.Epsilon было бы лучше ИМХО
Обратите внимание, что константа Double.Epsilon представляет собой наименьшее положительное значение Double больше нуля. Он не работает ни в каком другом домене.
Питер Ричи / Томас Ли: Это значение не определяется как наименьшее положительное число x, такое, что x + 1.0 не равно 1.0, поэтому Double.Epsilon нельзя использовать для «почти равенства». В структуре не существует константы, значение которой является наименьшим положительным числом x, такое, что x + 1.0 не равно 1.0.
Да, выбор epsilon зависит от конкретного приложения. Фреймворк не может иметь какой-то эпсилон, который работает везде.
В общем, когда вы имеете дело с числами с плавающей запятой, вы имеете дело с приближениями. Есть числа, которые невозможно представить точно, а операции tan и arctan сами по себе являются приблизительными.
Если вы хотите сравнить числа с плавающей запятой, вам нужно спросить, почти равны ли они или, что эквивалентно, если разница меньше некоторого небольшого значения, и тщательно подумайте, что вы делаете.
Вот несколько часто задаваемых вопросов (для C++, но идея та же), которые немного рассказывают о некоторых странностях чисел с плавающей запятой:
Обновлено: глядя на другие ответы, я понимаю, что основная проблема, вероятно, в том, что tan не обратим, но проблема аппроксимации также стоит учитывать всякий раз, когда вы проверяете числа с плавающей запятой на равенство.
Глядя на документацию .net для Математика. Атан, atan выдает значение от -π / 2 до ≤ π / 2, которое не включает 10. Я думаю, что это обычный диапазон для arctan.
Было бы полезно, если бы вы опубликовали то, что пытаетесь достичь. У меня есть воспоминания об обнаружении триггерных функций, которые решали проблему, например, в каком квадранте входы были для меня, когда я пытался играть с углами.
tan-1 (tan (x)) == x для всех x в (-PI / 2, PI / 2).
График может помочь объяснить, почему вы не получаете ожидаемого результата.

(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 просто возвращается из интервала, не решает математический фон - просто возьмите свой карманный калькулятор и (который ведет себя так же) и вычислите исходный пример
двойной d = Math.Atan (1) * (180 / Math.PI); так что d будет 45 градусов
здесь Tan-1 возвращается в степень к d
Поскольку функция касательной является периодической, нам необходимо нормализовать входной угол. Математика. Атан возвращает угол, θ, измеренный в радианах, такой как -π / 2 ≤ θ ≤ π / 2, поэтому имеет смысл нормализовать его до этого диапазона (поскольку в любом случае в этом диапазоне явно ничего не будет):
double normalizedAngle = (angle + Math.PI / 2) % Math.PI - Math.PI / 2;
Двойники следует сравнивать с некоторой погрешностью. Но на самом деле для этого случая Double.Epsilon слишком мало и «Если вы создаете собственный алгоритм, который определяет, можно ли считать два числа с плавающей запятой равными, вы должны использовать значение, которое больше, чем константа Эпсилон, чтобы установить приемлемый абсолютный запас разница для двух значений считается равной. (Обычно эта разница во много раз больше, чем Эпсилон.) «Например, Math.Atan(Math.Tan(-0.49999632679501449)) + 0.49999632679501449 будет больше, чем Double.Epsilon для 1.1235582092889474E+307 раз.
Math.Tan (10) возвращает тангенс угла 10 радианы, а не 10 градусы, как я подозреваю, вы думали.