我有这段代码,以便在给定通用底数的情况下获得数字的对数:
#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;
如您所见,引导库仅定义 neperian 日志,并且还有一种获取该日志的棘手方法,因为该库返回给您的不是 log(x) 而是 log(x+1)。正如您所看到的,这个问题通过给定参数 arg - 1 得到解决,一切都应该有效。
很好,它可以工作,但只有 neperian 日志可以,我的意思是,如果我运行这段代码:
#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
//res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;
一切都很好,但是当我执行基础更改时,一切都不好,我得到了错误的结果......我不知道,也许这是一个数学问题......我知道 log(basea, x ) = log(baseb, x)/log(baseb, basea)...
我哪里做错了??
嗯,这可能是一个关于数值稳定性等的数学问题......在不同的基础上获取日志,最佳做法是什么??????
最佳答案
我不确定到底发生了什么,但您可能遇到了舍入问题。 1 + delta 的问题是 delta 很小,因为 1 占主导地位并且 delta 被认为是微不足道的,所以 double 不是为了保持 delta 的精度而构建的。
boost库的目的是让你把1和delta分开传入,在取log的时候不会丢失delta的精度,这会给你一个接近于0的数字。
一个例子是你 delta = 0.00000000123456789
如果你将它加到 1 然后再次减去 1,你将看不到所有这些数字,因为 double 只包含大约 15 位精度,但 +1 以上的数字需要 17,而我打印的数字只使用 9 位,因为前导零不算在内。
关于c++ - Boost C++ 库中 Log 函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4333330/