Есть ли функция логарифма GMP?

есть ли функция логарифма, реализованная в библиотеке GMP?

3 ответов


нет в GMP нет такой функции. Только в MPFR.


Я знаю, что вы не спрашивали, как его реализовать, но...

вы можете реализовать грубый, используя свойства логарифмов: http://gnumbers.blogspot.com.au/2011/10/logarithm-of-large-number-it-is-not.html

и внутренности библиотеки GMP:https://gmplib.org/manual/Integer-Internals.html

(Edit: в основном вы просто используете самую значительную "цифру" представления GMP с момента основания представление огромный B^N гораздо больше, чем B^{N-1})

вот моя реализация для рациональных.

    double LogE(mpq_t m_op)
    {
        // log(a/b) = log(a) - log(b)
        // And if a is represented in base B as:
        // a = a_N B^N + a_{N-1} B^{N-1} + ... + a_0
        // => log(a) \approx log(a_N B^N)
        // = log(a_N) + N log(B)
        // where B is the base; ie: ULONG_MAX

        static double logB = log(ULONG_MAX);

        // Undefined logs (should probably return NAN in second case?)
        if (mpz_get_ui(mpq_numref(m_op)) == 0 || mpz_sgn(mpq_numref(m_op)) < 0)
            return -INFINITY;               

        // Log of numerator
        double lognum = log(mpq_numref(m_op)->_mp_d[abs(mpq_numref(m_op)->_mp_size) - 1]);
        lognum += (abs(mpq_numref(m_op)->_mp_size)-1) * logB;

        // Subtract log of denominator, if it exists
        if (abs(mpq_denref(m_op)->_mp_size) > 0)
        {
            lognum -= log(mpq_denref(m_op)->_mp_d[abs(mpq_denref(m_op)->_mp_size)-1]);
            lognum -= (abs(mpq_denref(m_op)->_mp_size)-1) * logB;
        }
        return lognum;
    }

здесь: https://github.com/linas/anant

обеспечивает gnu mp реальный и сложный логарифм, exp, синус, Косинус, гамма, арктан, sqrt, полилогарифм Римана и Гурвица Дзета, слияние гипергеометрических, топологи синус и многое другое.