GMP库中是否有任何对数函数?
答案 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^N
比B^{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;
}
当然,可以将上述方法修改为使用对数属性(例如,更改基本公式)以任何底数返回日志。