无法以编程方式更改Boost Boost多精度mpfr精度

时间:2019-03-31 01:37:27

标签: boost mpfr boost-multiprecision

请记住,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在其示例中显示的示例那样,但是仍然没有返回正确的值,而是在之后做保持不变。

更新:将我所做的与他们在这篇文章中所说的进行比较: how to change at runtime number precision with 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之间的差异,例如,如果我采用数字(1/137),则mpfr_float会给我带来更高的精度:

 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: multiprecision Chapter 1

我还必须指出,由于QtQuick Qml Felgo应用程序中使用了此函数,因此我依赖Qt,即使我使用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,则检查Precision + 1是否大于5,如果是,则将1加到Precision并返回0的子字符串Precision,然后用所有这些正确的做事方式,我什至可以在返回后用JavaScript做到这一点,而忘了以正确的方式做事,但我仍然认为我只是缺少了一些东西,因为我不敢相信这就是这种方式实际上应该工作。

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

0 个答案:

没有答案