У меня сбой модульного теста на Math.Tan(-PI/2)
, возвращающем неправильную версию в .NET.
«Ожидаемое» значение берется из Wolfram online (с использованием прописанной константы для -Pi/2). Убедитесь сами здесь.
Как правильно заметили в комментариях, математический результат tan(-pi/2) равен бесконечности. Однако константа Math.PI
не совсем точно представляет PI, так что это входные данные, близкие к пределу.
Вот код.
double MINUS_HALF_PI = -1.570796326794896557998981734272d;
Console.WriteLine(MINUS_HALF_PI == -Math.PI/2); //just checking...
double tan = Math.Tan(MINUS_HALF_PI);
Console.WriteLine("DotNET {0:E20}", tan);
double expected = -1.633123935319534506380133589474e16;
Console.WriteLine("Wolfram {0:E20}", expected);
double off = Math.Abs(tan-expected);
Console.WriteLine(" {0:E20}", off);
Вот что печатается:
True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
5.39375188498000000000E+011
Я думал, что это проблема представления с плавающей запятой.
Как ни странно, то же самое в Java ДЕЙСТВИТЕЛЬНО возвращает то же значение, что и Wolfram, вплоть до последней цифры — см. оценку в Eclipse. (Выражения обрезаны — поверьте мне, они используют ту же константу, что и MINUS_HALF_PI
выше.)
True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
Java -1.63312393531953700000E+016
Как видите, разница в следующем:
- между Wolfram и .NET:
~5.39 * 10^11
- между Wolfram и Java:
=2.40 * 10^1
Это десять порядков!
Итак, есть идеи, почему реализации .NET и Java так сильно различаются? Я ожидаю, что они оба просто переложат фактические вычисления на процессор. Является ли это предположение нереалистичным для x86?
Обновлять
В соответствии с просьбой я попытался запустить Java с strictfp
. Без изменений:
decimal
может помочь в этом отношении. В-третьих, Java и .NET используют одно и то же стандартное представление дляdouble
s, поэтому возможность представления значения вряд ли будет проблемой. - person Cristian Diaconescu   schedule 29.11.2013strictfp
? - person chrylis -cautiouslyoptimistic-   schedule 29.11.2013Tan
равно -Infinity при -Pi/2, поэтому я думаю, что это не репрезентативное значение для проверки точности используемой функции. Конечно, ошибка составляет десять порядков, но это все еще относительная ошибка всего 0,003%. Цифра только кажется большой, но на самом деле это не так. - person user1983983   schedule 29.11.2013MINUS_HALF_PI
? Очевидно, что это не Wolfram Alpha - person Martin Smith   schedule 29.11.2013