有没有GMP对数函数?

时间:2012-07-11 12:14:18

标签: gmp logarithm

GMP库中是否有任何对数函数?

4 个答案:

答案 0 :(得分:5)

我知道你没有问过如何实现它,但是......

您可以使用对数属性实现粗略的:http://gnumbers.blogspot.com.au/2011/10/logarithm-of-large-number-it-is-not.html

GMP库的内部:https://gmplib.org/manual/Integer-Internals.html

(编辑:基本上你只使用GMP表示的最重要的“数字”,因为表示的基础巨大 B^NB^{N-1}大得多)

这是我对Rationals的实现。

    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;
    }

(很晚以后编辑) 回到5年后,我认为log(a) = N log(B) + log(a_N)的核心概念即使在本机浮点实现中也很明显,here是ia64的glibc 我在遇到this question

后再次使用它

答案 1 :(得分:3)

GMP中没有这样的功能。 仅限MPFR。

答案 2 :(得分:1)

这是: https://github.com/linas/anant

提供gnu mp实数和复数对数,exp,正弦,余弦,gamma,arctan,sqrt,polylogarithm Riemann和Hurwitz zeta,汇合超几何,拓扑学家正弦等等。

答案 3 :(得分:1)

下面的方法使用mpz_get_d_2exp,并且是从gmp R package获得的。可以在文件biginteger_log中的函数bigintegerR.cc下找到该文件(首先必须下载源文件(即tar文件))。

// Adapted for general use from the original biginteger_log
// xi = di * 2 ^ ex  ==> log(xi) = log(di) + ex * log(2)

double biginteger_log_modified(mpz_t x) {
    signed long int ex;
    const double di = mpz_get_d_2exp(&ex, x);
    return log(di) + log(2) * (double) ex;
}

当然,可以将上述方法修改为使用对数属性(例如,更改基本公式)以任何底数返回日志。