Существуют ли какие-либо определения функций, таких как sqrt()
, sin()
, cos()
, tan()
, log()
, exp()
(они из math.h/cmath)?
Я просто хотел знать, как они работают.
Существуют ли какие-либо определения функций, таких как sqrt()
, sin()
, cos()
, tan()
, log()
, exp()
(они из math.h/cmath)?
Я просто хотел знать, как они работают.
Это интересный вопрос, но чтение источников эффективных библиотек не приведет вас к очень далеко, если вы не знаете, какой метод использовался.
Вот несколько указателей, которые помогут вам понять классические методы. Моя информация никоим образом не точна. Следующие методы являются только классическими, в конкретных реализациях могут использоваться другие методы.
sincos
.atan2
вычисляется с помощью вызова sincos
и немного логики. Эти функции являются строительными блоками для сложной арифметики.Каждая реализация может отличаться, но вы можете проверить одну реализацию из файла glibc (библиотеки GNU C).
edit: Google Code Search был отключен, поэтому старая ссылка, в которой я была, не попадает.
Источники для библиотеки glibc-math находятся здесь:
Посмотрите, как glibc
реализует различные математические функции, полные магии, аппроксимации и сборки.
Определенно посмотрите на источники fdlibm. Они хороши, потому что библиотека fdlibm является автономной, каждая функция хорошо документирована с подробными объяснениями вовлеченной математики, и код очень понятен для чтения.
Много посмотрев на математический код, я бы посоветовал не смотреть на glibc - код часто довольно трудно поддаться, и многое зависит от магии glibc. math lib в FreeBSD гораздо легче читать, если иногда иногда медленнее (но не сильно).
Для сложных функций основной трудностью являются граничные случаи - правильная обработка nan/inf/0 уже сложна для реальных функций, но это кошмар для сложных функций. Стандарт C99 определяет много угловых случаев, некоторые функции имеют легко 10-20 угловых случаев. Вы можете ознакомиться с приложением G обновленного стандартного документа C99, чтобы получить представление. Существует также сложный с длинным двойником, потому что его формат не стандартизирован - по моему опыту, вы должны ожидать довольно много ошибок с длинным двойным. Надеемся, что новая версия IEEE754 с расширенной точностью улучшит ситуацию.
Большинство современных аппаратных средств включают в себя модули с плавающей точкой, которые очень эффективно реализуют эти функции.
Те почти всегда реализуются как системные вызовы. Если вы хотите посмотреть источники, вам нужен доступ к источникам ОС, а это значит, что вам нужно искать ОС с открытым исходным кодом, например Linux или BSD.