1)双精度(8个字节)的可能范围高达10^(308)。我说得对吗?长双精度是否增加了实际精度,但没有增加可能的数字值范围?我记得我听说过,这取决于系统和编译器。是真的吗?至少当我尝试用long double计算我的值时,仍然会得到NaN。
2)然后我寻找一种方法来实际计算这些结果,我发现GNU的gmp。我听说你可以表示非常大的整数,我想这可能有所帮助。然而,阅读文档后,似乎...
mpz_t x;
mpz_init(x);
mpz_set_*(x,#);
我可以为gmp
整数数据类型分配值,但为了做到这一点,我只能选择分配可以用内置数据类型(如double或(u/s)int等)表示的值。 我发现有关如何分配非常大的数字的所有内容都是使用mpz_set_str()
从字符串中分配数字。
如果我想要分配一个复杂计算的结果呢?简单地说,公式看起来像这样:
long double res1,res2=0.0;
int a,b;
a=780;
b=741;
float d,d1,o,s; // can be values in [0.01,100]
res1=(2*(pow(b,2)*pow(E,b*(o + s))*(pow(d1,2) + pow(E,a*s)*(-1 + pow(E,a*o)) + pow(d,2)*(-1 + pow(E,a*s))) + pow(a,2)*pow(E,a*(o + s))*(pow(E,b*s)*(pow(E,b*o) + (-1 + d)*(1 + d + b*o)) + (-d + d1)*(d + d1 + b*o + b*d*s)) - a*b*(pow(d1,2)*(pow(E,a*(o + s)) + pow(E,b*(o + s))) + pow(E,a*o + (a + b)*s)*(-2 + 2*pow(E,b*o) - b*o) + d1*pow(E,a*s)*(-pow(E,b*o) + pow(E,a*o)*(1 + b*o)) + pow(d,2)*pow(E,a*s)*(-pow(E,b*o) + pow(E,b*(o + s)) + pow(E,a*o)*(-1 + pow(E,b*s) - b*s)) + d*(-(d1*pow(E,b*(o + s))) + (1 + d1)*pow(E,b*o + a*s) - pow(E,a*s + b*(o + s)) + pow(E,b*s + a*(o + s))*(1 + b*o) + pow(E,a*(o + s))*(-1 - b*o + b*d1*s)))))......;
res2也将是这种类型,最后我需要计算res1/res2,通常会得到一个非常小的数字。
我考虑将公式拆分并向mpg_z添加项,以便不会超出每个项的双精度范围,但由于公式如此漫长和复杂,这几乎是不可能的。
因此,问题在于我的中间结果可能会变得非常巨大,没有任何数据类型能够存储它们,因此我无法将其分配给mpz并摆脱这个问题。
我知道我想要计算double值,并实际上使用mpz_t来处理整数。据我所了解,这是存储这样大的数据的唯一方法,因为mpf_t只能处理浮点类型。老实说,关于中的表示仍然让我感到困惑。
有什么想法如何解决这个问题吗?