gmp库提供了void mpf_pow_ui (mpf_t rop, const mpf_t op1, unsigned long int op2)函数,将op1提高到功率op2 (根据https://gmplib.org/manual/Float-Arithmetic#index-Powering-functions-1)。
但是,在c++接口中,文档似乎并没有提到这一点。我试过使用pow、pow_iu、power等名称,但没有定义它们。
是否有方法使用gmpxx将浮点数提高到指数(浮点数或整数)?
发布于 2022-01-11 16:16:19
gmpxx.h包含一些数学操作的接口,如sqrt (参见第3341行)
__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)caps命名的宏依赖于一个名为__gmp_expr<T, U>的通用评估类模板,该模板又允许具有混合本地和仲裁精度类型的表达式的eval,这就是使C++ GMP接口更易于使用的原因。
但是pow没有这样的定义。正如Marc所指出的,您必须使用C++函数将您的mpf_class::get_mpf_t对象转换为C类型。
下面是一个示例代码。说吧,test.cpp。
#include <iostream>
#include <gmpxx.h>
using namespace std;
int main (void) {
mpf_class a = 12.3;
unsigned long int b = 123UL;
mpf_t c;
mpf_set_default_prec(100000);
mpf_init(c);
mpf_pow_ui(c, a.get_mpf_t(), b);
gmp_printf("c = %.50Ff\n", c);
return 0;
}和编译与
g++ test.cpp -o test -lgmpxx -lgmp它产生的输出:
114374367934618002778643226182707594198913258409535335775583252201365538178632825702225459029661601216944929436371688246107986574246790.32099077871758646985223686110515186972735931183764
不幸的是,即使提高了强积金的精度,我也不能让这个数字与WolframAlpha的答案更接近14位数
114374367934617190099880295228066276746218078451850229775887975052369504785666896446606568365201542169649974727730628842345343196581134.89591994282087444983721209947664895835902379607854
请注意,如果要将任意精度浮点数引发为任意精度浮点数,则需要使用MPFR库中的函数MPFR,顺便说一句,该函数库是推荐库,用于处理任意精度浮点数:
新项目应考虑使用GMP扩展库MPFR (http://mpfr.org)。MPFR提供了定义良好的精度和精确的舍入,从而自然地扩展了IEEE P754.
编辑:由于GMP和WolframAlpha之间的差异(顺便说一句,它在内部使用GMP ),我已经发布了这个问题。
EDIT2:正如在这和这注释中所提到的,这种差异是预期的,因为当使用mpf_pow_ui函数时,编译器会将12.3转换为一个double,这在二进制文件中是不完全可表示的,而Mathematica则对该值使用任意精度,因此在这种特殊情况下它更准确。
EDIT3:GMP实际上可以与WolframAlpha的结果相匹配,正如John在其回答中所解释的那样。
我的原始代码的问题在于使用mpf_set_d函数来设置值12.3,因为它转换为double,从而降低了精度。John修改了代码以使用mpf_set_str函数,该函数被转换为C++,变成:
#include <iostream>
#include <gmpxx.h>
using namespace std;
int main (void) {
mpf_class a("12.3",2000);
unsigned long int b = 123UL;
mpf_t c;
mpf_set_default_prec(2000);
mpf_init(c);
mpf_pow_ui(c, a.get_mpf_t(), b);
gmp_printf("c = %.50Ff\n", c);
return 0;
}它输出完全正确的答案(最后一个数字四舍五入为'5‘,因为那个数字是'4’,后面是'9'):
114374367934617190099880295228066276746218078451850229775887975052369504785666896446606568365201542169649974727730628842345343196581134.89591994282087444983721209947664895835902379607855
https://stackoverflow.com/questions/70520908
复制相似问题