使用提升多精度的数学精度问题
Issues with Math Precision using boost multiprecision
我正在将一个 bash 脚本转换为一个名为 Galaxy Calculator 的 Qt Qml Felgo 应用程序,我需要计算银河的周长,浮点数在计算中失败了 100 英里,使用 JavaScript 的 C++,数字对于 long double 来说太大了。这是bash行
echo "$(bc <<< "scale=13;((241828072282107.5071453596951 * 666) * 2) * 3.14159265359")"
我解释这个是为了让你理解这个数字,我不想争论数学,它是物理学博士的一部分,描述了这个数学,但是你可以检查这个数字的任何估计的结果,但这不是我的问题的一部分,只是试图解释我正在做的哪种类型的计算需要如此高的准确性。当计算银河系中的距离时,它将是一个很大的数字,我需要帮助的是通过将两个数字相乘得到正确的输出,这是我的函数:
QString MathWizard::multiply(const QString &mThis, const QString &mThat)
{
using namespace boost::multiprecision;
cpp_dec_float_100 aThis = mThis.toFloat();
cpp_dec_float_100 aThat = mThat.toFloat();
cpp_dec_float_100 ans = (aThis * aThat);
std::stringstream ss;
ss.imbue(std::locale(""));
ss << std::fixed << std::setprecision(16) << ans;
return QString::fromStdString(ss.str());
}
大多数程序员只看代码就会注意到我的第一个错误:toFloat()
我传入字符串和 return 字符串以避免必须使用 Float,但我找不到另一种方法来填充此数据类型,因为我不知道如何传入字符串,我一直在寻找举个例子两天,所以这是我的第一个问题,这可能会导致我的第二个问题,也就是我得到一个 return 的值:
1011954108252979200.000000
当我预料到这一点时(bc 很棒:获取一个字符串,然后将其返回);
1011954093357316199.9999999999118107708
也许我有点挑剔,数字很接近,但那些额外的数字是英里、英尺和英寸,这只是一个方程式,这个错误会随着我做的越多而加起来,而这个只是一个例子,有些计算比其他计算有更多的数学运算,所以我需要帮助来弄清楚如何传入一个字符串,以及如何 return 这个函数可以给我的所有精度的刺痛,我可以四舍五入稍后,我需要一些其他计算,所以我不希望它们超过 16,因为在那之后我们谈论的是一英寸的分数,我不需要那么多的精度,但我确实需要分数英里,英尺到最后一英寸。
我确实尝试过 mpfr_float,其他人也喜欢它,所以我想知道我是否必须将其转换为浮点数,这是否会弄乱它;所以我真的需要能够用字符串填充这个值,这样我就不会丢失任何精度。
我对这个函数的输入是在 bash 脚本中,我必须这样做 3 次才能得到答案,我不介意,在 运行 上使用 eval, PI 固定在那么多位数,因为那是我的大表弟多次删除艾萨克牛顿在他所有计算中使用的东西,所以我不能使用 PI。我可以使用任何有效的数据类型,如果您知道显示如何执行此操作的文档,请包括它们,links to boost 很可能是我已经阅读过的,自从成为 boost 用户以来它第一次出来,我第一次使用这个库,但是他们所有的例子都是一样的,他们的文档非常临床,不是很糟糕,你明白我的意思,它读起来就像计算机写的,并使用了一个页面作为下一个模板,所以所有的文档在一段时间后看起来都一样,我的很长一段时间,我喜欢每个功能的很多例子,以及在使用中展示它的真实世界的应用程序,我还没有在 boost 上找到任何类似的文档,如果您认为我在夸大或咆哮,请按照此 link 了解我的意思:
提升:https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/index.html
您不必将 QString 转换为浮点数,因为 cpp_dec_float_100 接受 std::string
;
QString MathWizard::multiply(const QString &mThis, const QString &mThat){
using namespace boost::multiprecision;
cpp_dec_float_100 aThis(mThis.toStdString());
cpp_dec_float_100 aThat(mThat.toStdString());
cpp_dec_float_100 ans = (aThis * aThat);
return QString::fromStdString(ans.str());
}
输出:
1011954093357316199.999999999911810770784788
我正在将一个 bash 脚本转换为一个名为 Galaxy Calculator 的 Qt Qml Felgo 应用程序,我需要计算银河的周长,浮点数在计算中失败了 100 英里,使用 JavaScript 的 C++,数字对于 long double 来说太大了。这是bash行
echo "$(bc <<< "scale=13;((241828072282107.5071453596951 * 666) * 2) * 3.14159265359")"
我解释这个是为了让你理解这个数字,我不想争论数学,它是物理学博士的一部分,描述了这个数学,但是你可以检查这个数字的任何估计的结果,但这不是我的问题的一部分,只是试图解释我正在做的哪种类型的计算需要如此高的准确性。当计算银河系中的距离时,它将是一个很大的数字,我需要帮助的是通过将两个数字相乘得到正确的输出,这是我的函数:
QString MathWizard::multiply(const QString &mThis, const QString &mThat)
{
using namespace boost::multiprecision;
cpp_dec_float_100 aThis = mThis.toFloat();
cpp_dec_float_100 aThat = mThat.toFloat();
cpp_dec_float_100 ans = (aThis * aThat);
std::stringstream ss;
ss.imbue(std::locale(""));
ss << std::fixed << std::setprecision(16) << ans;
return QString::fromStdString(ss.str());
}
大多数程序员只看代码就会注意到我的第一个错误:toFloat() 我传入字符串和 return 字符串以避免必须使用 Float,但我找不到另一种方法来填充此数据类型,因为我不知道如何传入字符串,我一直在寻找举个例子两天,所以这是我的第一个问题,这可能会导致我的第二个问题,也就是我得到一个 return 的值:
1011954108252979200.000000
当我预料到这一点时(bc 很棒:获取一个字符串,然后将其返回);
1011954093357316199.9999999999118107708
也许我有点挑剔,数字很接近,但那些额外的数字是英里、英尺和英寸,这只是一个方程式,这个错误会随着我做的越多而加起来,而这个只是一个例子,有些计算比其他计算有更多的数学运算,所以我需要帮助来弄清楚如何传入一个字符串,以及如何 return 这个函数可以给我的所有精度的刺痛,我可以四舍五入稍后,我需要一些其他计算,所以我不希望它们超过 16,因为在那之后我们谈论的是一英寸的分数,我不需要那么多的精度,但我确实需要分数英里,英尺到最后一英寸。
我确实尝试过 mpfr_float,其他人也喜欢它,所以我想知道我是否必须将其转换为浮点数,这是否会弄乱它;所以我真的需要能够用字符串填充这个值,这样我就不会丢失任何精度。
我对这个函数的输入是在 bash 脚本中,我必须这样做 3 次才能得到答案,我不介意,在 运行 上使用 eval, PI 固定在那么多位数,因为那是我的大表弟多次删除艾萨克牛顿在他所有计算中使用的东西,所以我不能使用 PI。我可以使用任何有效的数据类型,如果您知道显示如何执行此操作的文档,请包括它们,links to boost 很可能是我已经阅读过的,自从成为 boost 用户以来它第一次出来,我第一次使用这个库,但是他们所有的例子都是一样的,他们的文档非常临床,不是很糟糕,你明白我的意思,它读起来就像计算机写的,并使用了一个页面作为下一个模板,所以所有的文档在一段时间后看起来都一样,我的很长一段时间,我喜欢每个功能的很多例子,以及在使用中展示它的真实世界的应用程序,我还没有在 boost 上找到任何类似的文档,如果您认为我在夸大或咆哮,请按照此 link 了解我的意思:
提升:https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/index.html
您不必将 QString 转换为浮点数,因为 cpp_dec_float_100 接受 std::string
;
QString MathWizard::multiply(const QString &mThis, const QString &mThat){
using namespace boost::multiprecision;
cpp_dec_float_100 aThis(mThis.toStdString());
cpp_dec_float_100 aThat(mThat.toStdString());
cpp_dec_float_100 ans = (aThis * aThat);
return QString::fromStdString(ans.str());
}
输出:
1011954093357316199.999999999911810770784788