如何在 C++ 中将一个非常小的数字与自身相乘超过 100 次?
How to multiply a very small number with itself more than 100 times in c++?
我正在尝试开发一个 C++ 程序来将一个数字(比如 2.45784e-05)与自身相乘 28224 次。乘法后,我必须对输出执行另一项任务。为了将数字与自身相乘,我编写了如下 C++ 程序:
#include<iostream>
using namespace std;
int main() {
long double x = 2.45784e-05, y = 1;
cout << "Before multiplication, x= " << x << endl;
for (int i = 0; i < 28224; i++) {
y = y * x;
cout <<i+1<<". "<< "y=" << y << endl;
}
return 0;
}
但是,该程序给出了高达 1075 次的准确输出。之后,它给出 0 作为输出。结果是:
Before multiplication, x= 2.45784e-05
1. y=2.45784e-05
2. y=6.04098e-10
3. y=1.48478e-14
4. y=3.64934e-19
.
.
.
1073. y=1.15885e-4946
1074. y=3.6452e-4951
1075. y=0
1076. y=0
.
.
.
28223. y=0
朋友建议我每次自乘一个常数再乘以x。但我不明白如何用它乘以一个常数。请给我一个解决方案来获得输出。
每次您将自己的数字乘以自身,它都会增加需要保留的位数。好吧,老实说,即使从这 1075 个中,我认为也有一半是足够正确的,甚至更少,其他的会收敛到可以表示为 long double 的附近数字。要完成您想要的技巧,您需要使用一些具有任意精度数学的 3rdparty 库。在此处查看列表:
https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software
你的朋友希望你做的事情没有多大帮助:常数乘法会移动小数点,但不会减少计算所需的位数。
编辑:@Borgleader 的 解决方案看起来不错(提升:多精度)。
给定 x = 2.45784e-05 和 y = 28224,您需要 x^y(幂)。
找到 s(比例)使得 z = x * s, 0 < z < 1 (s = 10^6)
那么你的答案是 (z/s) ^ y = z^y / s^y。
如果 s 是 10^6,那么您可以将 s^y 计算为 10^(6*y)。
我预计 z^y 仍会溢出,但它会发生在更高的指数
然后你可以完善这个想法。提示:尝试使用 s 作为 2 的幂。
这里的问题实际上不是精度(或者就其本身而言,它只是问题的一部分,而不是本质问题)。
这里的主要问题是范围,结果数字太小而无法在double
中表示(结果指数超出范围double
表示的最小指数)。所以对于计算机来说,它实际上是 0.
将值乘以某个数字使其更大(即 "scale")的想法因此可行,然后您需要补偿结果指数。
另请注意,如果您想多次乘以相同的数字 multiple/a,您可以使用 pow(num, N)
代替,如果 N 很大,这会快得多。
我正在尝试开发一个 C++ 程序来将一个数字(比如 2.45784e-05)与自身相乘 28224 次。乘法后,我必须对输出执行另一项任务。为了将数字与自身相乘,我编写了如下 C++ 程序:
#include<iostream>
using namespace std;
int main() {
long double x = 2.45784e-05, y = 1;
cout << "Before multiplication, x= " << x << endl;
for (int i = 0; i < 28224; i++) {
y = y * x;
cout <<i+1<<". "<< "y=" << y << endl;
}
return 0;
}
但是,该程序给出了高达 1075 次的准确输出。之后,它给出 0 作为输出。结果是:
Before multiplication, x= 2.45784e-05
1. y=2.45784e-05
2. y=6.04098e-10
3. y=1.48478e-14
4. y=3.64934e-19
.
.
.
1073. y=1.15885e-4946
1074. y=3.6452e-4951
1075. y=0
1076. y=0
.
.
.
28223. y=0
朋友建议我每次自乘一个常数再乘以x。但我不明白如何用它乘以一个常数。请给我一个解决方案来获得输出。
每次您将自己的数字乘以自身,它都会增加需要保留的位数。好吧,老实说,即使从这 1075 个中,我认为也有一半是足够正确的,甚至更少,其他的会收敛到可以表示为 long double 的附近数字。要完成您想要的技巧,您需要使用一些具有任意精度数学的 3rdparty 库。在此处查看列表:
https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software
你的朋友希望你做的事情没有多大帮助:常数乘法会移动小数点,但不会减少计算所需的位数。
编辑:@Borgleader 的 解决方案看起来不错(提升:多精度)。
给定 x = 2.45784e-05 和 y = 28224,您需要 x^y(幂)。 找到 s(比例)使得 z = x * s, 0 < z < 1 (s = 10^6) 那么你的答案是 (z/s) ^ y = z^y / s^y。 如果 s 是 10^6,那么您可以将 s^y 计算为 10^(6*y)。
我预计 z^y 仍会溢出,但它会发生在更高的指数 然后你可以完善这个想法。提示:尝试使用 s 作为 2 的幂。
这里的问题实际上不是精度(或者就其本身而言,它只是问题的一部分,而不是本质问题)。
这里的主要问题是范围,结果数字太小而无法在double
中表示(结果指数超出范围double
表示的最小指数)。所以对于计算机来说,它实际上是 0.
将值乘以某个数字使其更大(即 "scale")的想法因此可行,然后您需要补偿结果指数。
另请注意,如果您想多次乘以相同的数字 multiple/a,您可以使用 pow(num, N)
代替,如果 N 很大,这会快得多。