0

请记住,Precision 是基于总位数而不是小数位数,但我需要一种设置小数位数的方法,而我只能找到 Precision,所以我正在尝试使用它,所以我考虑了整数中的位数,以使其正常工作,但这不起作用。

我想做一些数学运算并返回一个设定的精度值,该函数采用一个非常大的数字字符串,具有非常大的小数精度,并将其作为一个字符串返回,该字符串设置为作为精度传入的小数位数:

 #include <boost/multiprecision/mpfr.hpp>

 QString multiply(const QString &mThis, const QString &mThat, const unsigned int &precison)
 {
    typedef boost::multiprecision::number<mpfr_float_backend<0> > my_mpfr_float;
    my_mpfr_float aThis(mThis.toStdString());
    my_mpfr_float aThat(mThat.toStdString());
    my_mpfr_float::default_precision(precison);
    my_mpfr_float ans = (aThis * aThat);
    return QString::fromStdString(ans.str());
 } 

我试过没有typedef,同样的问题;

MathWizard::multiply("123456789.123456789", "123456789.123456789", 20);

Precision 18位,9+9,我要30

将返回 22 位小数

15241578780673678.51562

而不是 20

15241578780673678.516

那么为什么它关闭了2?

我想在数学之后进行精度更改,但似乎你必须先设置它,而不是像 boost 在他们的示例中显示的示例,但仍然没有返回正确的值,这样做之后不会改变值.

更新:将我所做的与他们在这篇文章中所说的进行比较: 如何使用 boost::multiprecision 在运行时更改数字精度

 typedef number<gmp_float<0> >     mpf_float;
 mpfr_float a = 2;
 mpfr_float::default_precision(1000);
 std::cout << mpfr_float::default_precision() << std::endl;
 std::cout << sqrt(a) << std::endl; // print root-2

我注意到 gmp_float、mpf_float(使用 boost/multiprecision/gmp.hpp)和 mpfr_float 之间的差异,而 mpfr_float 会给我更接近的精度,例如,如果我取数字(1/137):

 mpf_float
 0.007299270072992700729927007299270072992700729927007299270073
 only 1 Precision, 23 digits when set to 13
 0.00729927007299270072993
 mpfr_float
 0.007299270072992700729929
 only 1 Precision, 16 digits when set to 13
 0.0072992700729928

只有 1 精度,我希望我的答案少一位小数。

其他数据类型也类似,我都试过了,所以这段代码对这里描述的所有数据类型都一样:

boost 1.69.0:多精度第 1 章

我还必须指出,我依赖 Qt,因为此函数用于 QtQuick Qml Felgo 应用程序,实际上我无法将其转换为字符串而不将其转换为指数,即使我使用了 ans.str()对于两者,我的猜测是 fromStdString 与 std::string(ans.str()) 做的事情不同。

我想如果我不能弄清楚他,我会做字符串舍入以获得正确的精度。

 std::stringstream ss;
 ss.imbue(std::locale(""));
 ss << std::fixed << std::setprecision(int(precison)) << ans.str();
 qDebug() << "divide(" << mThis << "/" << mThat << " @ " << precison << " =" << QString::fromStdString(ss.str()) << ")";
 return QString::fromStdString(ss.str());

如果不使用 QString,我仍然无法逃脱,但这不起作用,它返回 16 位而不是 13 位,我知道这是一个不同的问题,因此我只是发布它以表明我的替代方案此时不能更好地工作. 另请注意,除法函数的工作原理与乘法相同,我使用该示例来显示数学与此无关,但他们向我展示的所有示例似乎都无法正常工作,我不明白为什么,所以只是为了使步骤清晰:

  1. 创建后端:typedef boost::multiprecision::number > my_mpfr_float;
  2. 设置精度:my_mpfr_float::default_precision(precision);
  3. 设置变量的初始值:my_mpfr_float aThis(mThis.toStdString());
  4. 如果您愿意,可以做一些数学运算,以正确的精度返回值。

我肯定错过了什么。

我知道我可以得到字符串的长度,如果比 Precision 长,则检查 Precision + 1 是否大于 5,如果是,则在 Precision 上加 1 并返回 0 的子字符串,Precision 并完成所有这些正确做事的方式,我什至可以在返回后在 JavaScript 中执行此操作,而忘记以正确的方式执行此操作,但我仍然认为我只是遗漏了一些东西,因为我无法相信这实际上是应该的方式工作。

提交的错误报告:https ://github.com/boostorg/multiprecision/issues/127

4

0 回答 0