Подтвердить что ты не робот

Определения sqrt, sin, cos, pow и т.д. В cmath

Существуют ли какие-либо определения функций, таких как sqrt(), sin(), cos(), tan(), log(), exp() (они из math.h/cmath)?

Я просто хотел знать, как они работают.

4b9b3361

Ответ 1

Это интересный вопрос, но чтение источников эффективных библиотек не приведет вас к очень далеко, если вы не знаете, какой метод использовался.

Вот несколько указателей, которые помогут вам понять классические методы. Моя информация никоим образом не точна. Следующие методы являются только классическими, в конкретных реализациях могут использоваться другие методы.

  • Часто используются таблицы поиска
  • Тригонометрические функции часто реализуются с помощью алгоритма CORDIC (либо на процессоре, либо в библиотеке). Обратите внимание, что обычно синус и косинус вычисляются вместе, я всегда задавался вопросом, почему стандартная библиотека C не предоставляет функцию sincos.
  • Квадратные корни используют метод Ньютона с некоторыми умными трюками реализации: вы можете найти где-нибудь в Интернете выдержку из исходного кода Quake с умом bogging 1/sqrt (x).
  • Экспоненциальные и логарифмы используют exp (2 ^ nx) = exp (x) ^ (2 ^ n) и log2 (2 ^ nx) = n + log2 (x), чтобы иметь аргумент, близкий к нулю (одному для log ) и использовать приближение рациональной функции (обычно аппроксимации Паде). Обратите внимание, что этот точный трюк может дать вам матричные экспоненты и логарифмы. Согласно @Stephen Canon, современные реализации благоприятствуют расширению Тейлора над приближением рациональной функции, где деление гораздо медленнее, чем умножение.
  • Другие функции могут быть выведены из этих. Реализации могут предоставлять специализированные процедуры.
  • pow (x, y) = exp (y * log (x)), поэтому pow не следует использовать, когда y является целым числом
  • hypot (x, y) = abs (x) sqrt (1 + (y/x) ^ 2) если x > y (hypot (y, x) в противном случае), чтобы избежать переполнения. atan2 вычисляется с помощью вызова sincos и немного логики. Эти функции являются строительными блоками для сложной арифметики.
  • Для других трансцендентных функций (gamma, erf, bessel,...), пожалуйста, обратитесь к отличной книге Numericical Recipes, 3rd edition для некоторых идеи. Полезен также good'old Abramowitz и Stegun. Существует новая версия http://dlmf.nist.gov/.
  • В более сложных функциях используются методы, такие как приближение Чебышева, продолжение продолжения дробей (фактически связанное с аппроксимациями Паде) или экономия энергетических рядов (если вы, например, читаете исходный код для erf, bessel или gamma). Я сомневаюсь, что они действительно используют простые простые математические функции, но кто знает. Проконсультируйтесь с числовыми рецептами для обзора.

Ответ 2

Каждая реализация может отличаться, но вы можете проверить одну реализацию из файла glibc (библиотеки GNU C).

edit: Google Code Search был отключен, поэтому старая ссылка, в которой я была, не попадает.

Источники для библиотеки glibc-math находятся здесь:

http://sourceware.org/git/?p=glibc.git;a=tree;f=math;h=3d5233a292f12cd9e9b9c67c3a114c64564d72ab;hb=HEAD

Ответ 3

Посмотрите, как glibc реализует различные математические функции, полные магии, аппроксимации и сборки.

Ответ 4

Определенно посмотрите на источники fdlibm. Они хороши, потому что библиотека fdlibm является автономной, каждая функция хорошо документирована с подробными объяснениями вовлеченной математики, и код очень понятен для чтения.

Ответ 5

Много посмотрев на математический код, я бы посоветовал не смотреть на glibc - код часто довольно трудно поддаться, и многое зависит от магии glibc. math lib в FreeBSD гораздо легче читать, если иногда иногда медленнее (но не сильно).

Для сложных функций основной трудностью являются граничные случаи - правильная обработка nan/inf/0 уже сложна для реальных функций, но это кошмар для сложных функций. Стандарт C99 определяет много угловых случаев, некоторые функции имеют легко 10-20 угловых случаев. Вы можете ознакомиться с приложением G обновленного стандартного документа C99, чтобы получить представление. Существует также сложный с длинным двойником, потому что его формат не стандартизирован - по моему опыту, вы должны ожидать довольно много ошибок с длинным двойным. Надеемся, что новая версия IEEE754 с расширенной точностью улучшит ситуацию.

Ответ 6

Большинство современных аппаратных средств включают в себя модули с плавающей точкой, которые очень эффективно реализуют эти функции.

Ответ 7

Те почти всегда реализуются как системные вызовы. Если вы хотите посмотреть источники, вам нужен доступ к источникам ОС, а это значит, что вам нужно искать ОС с открытым исходным кодом, например Linux или BSD.