1

I have this code in order to get a logarithm of a number given a generic base:

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

As you can see boot libs define only neperian log and there is also a tricky way to get that log because what that lib gives back to you is not log(x) but log(x+1). As you can see this problem is solved by giving as the argument arg - 1 and everything should work.

WELL It works, but only the neperian log is ok, I mean, If I run this code:

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

Everything is ok, but right when I perform a base change everything is not good, I get back wrong results... I don't know, maybe it's a math issue... I know that log(basea, x) = log(baseb, x)/log(baseb, basea)...

Where do I do wrong??

Well, may be it is a math issue concerning numerical stability and so on... to get a log in a different base, what's the best practice???????

4

2 回答 2

1

我不确定到底发生了什么,但您可能遇到了舍入问题。delta 很小的 1 + delta 的问题在于,由于 1 占主导地位并且 delta 被认为是微不足道的,因此没有构建双精度来使 delta 保持很高的精度。

boost库的目的是让你分别传入1和delta,以免在取log的时候失去delta的精度,这会给你一个接近0的数字。

一个例子是你 delta = 0.00000000123456789

如果您将其添加到 1 然后再减去 1,您将不会看到所有这些数字,因为 double 仅保留大约 15 个精度位,但 +1 以上的数字需要 17,而我打印的数字仅使用 9 个位置,因为前导零不计较。

于 2010-12-02T09:23:23.223 回答
0

不清楚 arg 的类型是什么。你可以尝试一些东西

  1. 验证 boost::math::log1p( ) 打印出预期的结果。

  2. 验证 arg - 1 真的是双精度并打印出来。相反,您是否尝试过:arg - 1.0

于 2015-10-13T18:42:35.783 回答