C-大数乘法后的错误输出
我正在实施我自己的减少和征服方法 节目如下:C-大数乘法后的错误输出,c,double,multiplication,C,Double,Multiplication,我正在实施我自己的减少和征服方法 节目如下: #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> double dncpow(int a, int n) { double p = 1.0; if(n != 0) { p = dncpow(a, n / 2); p = p * p;
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
double dncpow(int a, int n)
{
double p = 1.0;
if(n != 0)
{
p = dncpow(a, n / 2);
p = p * p;
if(n % 2)
{
p = p * (double)a;
}
}
return p;
}
int main()
{
int a;
int n;
int a_upper = 10;
int n_upper = 50;
int times = 5;
time_t t;
srand(time(&t));
for(int i = 0; i < times; ++i)
{
a = rand() % a_upper;
n = rand() % n_upper;
printf("a = %d, n = %d\n", a, n);
printf("pow = %.0f\ndnc = %.0f\n\n", pow(a, n), dncpow(a, n));
}
return 0;
}
#包括
#包括
#包括
#包括
双dncpow(内部a,内部n)
{
双p=1.0;
如果(n!=0)
{
p=dncpow(a,n/2);
p=p*p;
如果(n%2)
{
p=p*(双)a;
}
}
返回p;
}
int main()
{
INTA;
int n;
INTA_上限=10;
int n_上限=50;
整数倍=5;
时间;
srand(time&t));
对于(int i=0;i
我的代码适用于较小的a和n值,但观察到输入的pow()和dncpow()输出不匹配,例如:
a=7,n=39
功率=909543680129861204865300750663680
dnc=909543680129861348980488826519552
我很确定算法是正确的,但是dncpow()给了我错误的答案。
有人能帮我纠正一下吗?提前谢谢 就这么简单,这些数字太大了,你的计算机无法在一个变量中准确地表示出来。对于浮点类型,有一个单独存储的指数,因此仍然可以表示接近实数的数字,去掉尾数的最低位 关于: 在将“double”替换为“long-long”后,我得到了类似的输出。后者应该被准确地存储,不是吗
- 如果调用一个函数时使用
,它将不会神奇地在double
上运行。您的值被简单地转换为long
,您将得到相同的结果double
- 即使使用一个函数处理
(在当今的典型平台上有64位),您也无法处理如此大的数字。64位不足以存储它们。对于无符号整数类型,它们在溢出时只会“环绕”到long
。对于有符号整数类型,溢出行为是未定义的(但仍有可能是环绕)。所以你会得到一些与你的预期结果完全无关的数字。这可以说比浮点类型的结果更糟糕,只是不精确0
uintmax\t
),然后自己实现所有的算术运算。这是一个很好的练习,需要做大量的工作,尤其是在性能令人感兴趣的情况下(“幼稚”的算术算法通常效率很低)
对于一些现实生活中的程序,您不会在这里重新发明轮子,因为这里有用于处理大量数字的库。可以说最著名的是。阅读那里的手册并使用它。就这么简单,这些数字太大了,你的计算机无法在单个变量中准确地表示出来。对于浮点类型,有一个单独存储的指数,因此仍然可以表示接近实数的数字,去掉尾数的最低位 关于: 在将“double”替换为“long-long”后,我得到了类似的输出。后者应该被准确地存储,不是吗
- 如果调用一个函数时使用
,它将不会神奇地在double
上运行。您的值被简单地转换为long
,您将得到相同的结果double
- 即使使用一个函数处理
(在当今的典型平台上有64位),您也无法处理如此大的数字。64位不足以存储它们。对于无符号整数类型,它们在溢出时只会“环绕”到long
。对于有符号整数类型,溢出行为是未定义的(但仍有可能是环绕)。所以你会得到一些与你的预期结果完全无关的数字。这可以说比浮点类型的结果更糟糕,只是不精确0
uintmax\t
),然后自己实现所有的算术运算。这是一个很好的练习,需要做大量的工作,尤其是在性能令人感兴趣的情况下(“幼稚”的算术算法通常效率很低)
对于一些现实生活中的程序,您不会在这里重新发明轮子,因为这里有用于处理大量数字的库。可以说最著名的是。阅读那里的手册并使用它。对于
double
来说,这个数字可能太大了。请注意dncpow(int a,int n)
对于dncpow(a,有些是负数)
double
的精度通常为16位小数,两个结果在该精度范围内。您是否希望像9e38 ish
这样的数字,一个100+位的数字被精确地编码为double
,通常为64位?@chux,我在用“long-long”替换“double”时得到了类似的输出。后者应该被准确地存储,不是吗?这些数字在很长一段时间内都超出了最低范围要求——也许您的实现有一个异常大的范围?在任何情况下,pow()都返回一个double,而不是long-long,因此chux提到的精度问题仍然是一个问题该数字对于double
来说可能太大double
的精度通常约为16位小数,2个结果在该精度范围内。您是否希望像9e38 ish
这样的数字,一个100+位的数字被精确地编码在双精度编码中,这通常是