Стандарт для синусов очень больших чисел - PullRequest
7 голосов
/ 12 июля 2011

Я пишу (почти) IEEE 854-совместимую реализацию с плавающей запятой в TeX (которая поддерживает только 32-битные целые числа).Этот стандарт определяет только результат +, -, *, /, сравнение, остаток и sqrt: для этих операций результат должен совпадать с округлением точного результата до представимого числа(в соответствии с режимом округления).

Кажется, я помню, что IEEE указывает, что трансцендентные функции (sin, exp ...) должны давать точные результаты (в стандартном режиме округления до ближайшего), они должны вывести одно из двух представимых чисел, окружающих точный результат).Вычислить синус небольших чисел довольно просто: сдвиньте кратное 2 * пи, чтобы получить число в диапазоне [0,2 * пи], затем проделайте еще некоторую работу, чтобы уменьшить диапазон до [0, пи / 4].и используйте ряд Тейлора.

Теперь предположим, что я хочу вычислить грех (1e300).Для этого мне нужно было бы найти 1е300 по модулю 2 * пи.Для этого необходимо знать 300 (316?) Десятичных дробей числа Пи, поскольку при наличии только 16 десятичных знаков результат не будет иметь никакого значения (в частности, он не может быть точным).

Существует ли стандарт длярезультат sin(1e300) и подобных очень больших чисел должен быть?

Что делают другие реализации с плавающей запятой?

Ответы [ 2 ]

9 голосов
/ 12 июля 2011

Не существует стандарта, который требует точного округления трансцендентных функций. IEEE-754 (2008) рекомендует , но не требует, чтобы эти функции были правильно округлены.

Большинство хороших математических библиотек стремятся обеспечить действительно округленные результаты во всем диапазоне (да, даже для огромных входных данных до sin( ) и аналогичных сложных случаев). Как вы заметили, это требует, чтобы библиотека знала несколько больше цифр π, чем цифр в самом большом представимом числе. Это называется сокращением аргумента "бесконечный пи".

В тот момент, когда поднимается @spraff, хорошие математические библиотеки принимают точку зрения, согласно которой входные данные являются бесконечно точными (то есть функция должна вести себя так, как будто входные данные всегда представлены точно). Можно спорить, является ли это разумной позицией, но это рабочее предположение практически для всех хороших математических библиотек.

Все это говорит о том, что существует множество библиотек, которые выбирают простой маршрут и используют сокращение "конечное число", которое в основном рассматривает функцию, подобную sin( ), как если бы π было представимым конечным числом. Оказывается, что это на самом деле не создает никаких проблем для большинства пользователей, и, безусловно, проще в реализации.

1 голос
/ 12 июля 2011

Если вы выполняете операции с такими большими числами, конечно, вы достигнете точности:

#include <iostream>
#include <math.h>

int main () {
    long double i = 1;
    std :: cout << sin (i) << "\n" << sin (i+0.1) << "\n";
    i = pow (10, 300);
    std :: cout << sin (i) << "\n" << sin (i+0.1);
}

Вывод:

0.841471

0,891207

-0,817882

-0,81788

Если вы не можете точно представить входные данные, вы не можете точно представить выходные данные.Вычитая pi*pow(10,int(log_10(n/pi)) или что-либо еще, будет хуже для "маленького" n, но когда n становится достаточно большим, вы просто добавляете шум к шуму, и это уже не имеет значения.

...