Где я могу найти математические процедуры в источнике G CC? Как работают математические функции? - PullRequest
3 голосов
/ 10 апреля 2020

Спокойной ночи. Я бакалавр по математике и изучаю журналы () и сериалы. И я хочу посмотреть, как G CC вычисляет все эти вещи, это мне очень поможет, в математике нет ничего. Я уже прочитал это. Я безумно пытаюсь найти, как G CC вычисляет логарифмы и квадратные корни, используя самый быстрый метод. Я не загрузил источник, но не могу найти, где математические процедуры.

https://github.com/gcc-mirror/gcc

Я просто хочу увидеть это, я не очень хороший Программист, мое дело математика.

Ответы [ 3 ]

4 голосов
/ 10 апреля 2020

Математические функции являются частью стандартной библиотеки C, и G CC просто использует их. Если вы хотите посмотреть исходный код, вы можете скачать исходный код с официального glib c веб-сайта (для версии библиотеки GNU C, которая является одной из наиболее часто используемых), или используйте онлайн-браузер кодов . Вот код для log(), например.

Поскольку вы говорите, что вы не так уж много программист, я сомневаюсь, что вы найдете стандартную библиотеку GNU C понятный. Это результат десятилетий оптимизаций и корректировок совместимости, а код очень сложный. Я бы предложил взглянуть на musl C Library вместо . Исходный код намного чище и более прокомментирован. Вот функция log() , а вот все файлы, относящиеся к математическим функциям .

Наконец, ни G CC, ни библиотека C не имеют " самый быстрый способ когда-либо "вычислить такие функции. Цель библиотеки C состоит не в том, чтобы обеспечить максимально быструю реализацию каждой математической функции, а в том, чтобы обеспечить достаточно хорошую реализацию, в то же время будучи достаточно переносимым для использования на нескольких архитектурах, поэтому они все еще очень быстры, но, скорее всего, не"самый быстрый". В лучшем случае некоторые математические функции можно даже сократить до одной инструкции ЦП, если ЦП поддерживает быстрые встроенные аппаратные математические операции (например, , например, Intel x86 с fsqrt для квадрата root ).

0 голосов
/ 10 апреля 2020

Взгляните на эту реализацию журнала .

Это от fdlibm , которая имеет реализации (следующие за IEEE-754 ) из множества математических функций в C для людей.

Из реализации:

Метод

  1. Сокращение аргумента: найти k и f такой что
    x = 2^k * (1+f),
    where sqrt(2)/2 < 1+f < sqrt(2) .
Аппроксимация log (1 + f).
Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
     = 2s + 2/3 s**3 + 2/5 s**5 + .....,
         = 2s + s*R
  • Мы используем специальный алгоритм Рима для [0,0.1716], чтобы сгенерировать полином степени 14 для аппроксимации R Максимум ошибка этого полиномиального приближения ограничена 2**-58.45. Другими словами,
                 2      4      6      8      10      12      14
    R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
    (the values of Lg1 to Lg7 are listed in the program)

и

    |      2          14          |     -58.45
    | Lg1*s +...+Lg7*s    -  R(z) | <= 2 
    |                             |

Обратите внимание, что 2s = f - s*f = f - hfsq + s*hfsq, где hfsq = f*f/2. Чтобы гарантировать ошибку в журнале ниже 1ulp, мы вычисляем журнал по

    log(1+f) = f - s*(f - R)    (if f is not too large)
    log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
Наконец,
     log(x) = k*ln2 + log(1+f).  
            = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
  • Здесь ln2 разбит на два числа с плавающей точкой:
        ln2_hi + ln2_lo,

, где n*ln2_hi всегда Точно для |n| < 2000.

Реальная реализация и особые случаи объяснения вы можете проверить по этой ссылке .

0 голосов
/ 10 апреля 2020

Функции типа log являются частью математической библиотеки, которую обычно называют "libm". Реализации стандартной библиотеки C, как правило, поставляются с реализацией libm, так что то, что вы ищете, скорее всего, в glib c. Вы можете найти реализацию log в glib c здесь: https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/e_log.c.html

В исходном коде есть некоторые комментарии, которые дают вам подсказки об используемом алгоритме, но не детализируют объяснение.

Конечно, существуют разные реализации libm - например, есть openlibm и netlib fdlibm . Документация обоих объясняет используемый алгоритм. Вот как log реализован в openlibm: https://github.com/JuliaMath/openlibm/blob/master/src/e_log.c

(Интересно - похоже, что log в openlibm и fdlibm пришли из того же источника)

...