it-roy-ru.com

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

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

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

33
Patryk Czachurski

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

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

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

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

Правка: поиск кода Google был переведен в автономный режим, поэтому старая ссылка, которую я имел, никуда не ведет.

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

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

21
wkl

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

7
ismail

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

5
Daniel Trebbien

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

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

4
David Cournapeau

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

0
David Heffernan