Почему я не загорел (PI / 2) = бесконечность в C - PullRequest
0 голосов
/ 21 января 2019

Когда я вычисляю tan (PI / 2), я получаю -22877332 в c, но tan (Pi / 2) - это бесконечность.и Google дает его как 3060023.30695 Почему я получаю разные ответы

Я пытался на компиляторе MINGW и в Google оба дают разные ответы

float32 Tan_f32 (float32 ValValue )
{
float32 Result_Val;

 Result_Val= (tanf(ValValue));
 return Result_Val;
 }

в компиляторе MINGW это дает -22877332 и в Google+3060023,30695

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Невозможно передать π / 2 в tan или tanf, потому что π иррационально, поэтому любое число с плавающей точкой, независимо от его точности, будет, по крайней мере, немного отличаться от π / 2. Следовательно, tanf(ValValue) возвращает тангенс некоторого значения, близкого к π / 2, и этот тангенс большой, но не бесконечный.

В общем формате, используемом для float, базового 32-разрядного двоичного числа с плавающей точкой IEEE-754, ближайшим представляемым числом к ​​π / 2 является 1,57079637050628662109375. Тангенс этого числа приблизительно равен -22877332.4289, а ближайшим значением, представимым в float, является -22877332, что является результатом, который вы получили. Таким образом, ваш tanf дает вам наилучший результат для введенного вами номера.

0 голосов
/ 21 января 2019

Стандарт C, или действительно общий, но ни в коем случае не повсеместный стандарт IEEE754 с плавающей запятой, не дает гарантии точности tan ( Cf sqrt).Реализация приведет к компромиссу в получении хорошего результата за разумное количество тактов.

В частности, поведение тригонометрической функции вблизи асимптоты особенно непредсказуемо;и это именно тот случай.

Признание того, что ошибка не связана с вашим значением pi (стоит проверить, хотя учтите, что, поскольку pi трансцендентен, он может 'не должно быть точно представлено в любой системе с плавающей запятой), если вы хотите, чтобы хорошо функционирующая функция tan во всем домене, вам было бы лучше использовать стороннюю математическую библиотеку.

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

double c = cos(x); tan(x) = sqrt(1 / c / c  - 1);

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

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