Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-大数乘法后的错误输出_C_Double_Multiplication - Fatal编程技术网

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
    ,您将得到相同的结果
  • 即使使用一个函数处理
    long
    (在当今的典型平台上有64位),您也无法处理如此大的数字。64位不足以存储它们。对于无符号整数类型,它们在溢出时只会“环绕”到
    0
    。对于有符号整数类型,溢出行为是未定义的(但仍有可能是环绕)。所以你会得到一些与你的预期结果完全无关的数字。这可以说比浮点类型的结果更糟糕,只是不精确
对于大数的精确计算,唯一的方法是将它们存储在数组中(通常是无符号整数,如
uintmax\t
),然后自己实现所有的算术运算。这是一个很好的练习,需要做大量的工作,尤其是在性能令人感兴趣的情况下(“幼稚”的算术算法通常效率很低)


对于一些现实生活中的程序,您不会在这里重新发明轮子,因为这里有用于处理大量数字的库。可以说最著名的是。阅读那里的手册并使用它。

就这么简单,这些数字太大了,你的计算机无法在单个变量中准确地表示出来。对于浮点类型,有一个单独存储的指数,因此仍然可以表示接近实数的数字,去掉尾数的最低位

关于:

在将“double”替换为“long-long”后,我得到了类似的输出。后者应该被准确地存储,不是吗

  • 如果调用一个函数时使用
    double
    ,它将不会神奇地在
    long
    上运行。您的值被简单地转换为
    double
    ,您将得到相同的结果
  • 即使使用一个函数处理
    long
    (在当今的典型平台上有64位),您也无法处理如此大的数字。64位不足以存储它们。对于无符号整数类型,它们在溢出时只会“环绕”到
    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+位的数字被精确地编码在
双精度编码中,这通常是