2

我有这个代码

#include <stdio.h>
#include <math.h>

static double const x = 665857;
static double const y = 470832;

int main(){
    double z = x*x*x*x -y*y*y*y*4 - y*y*4;
    printf("%f \n",z);
    return 0;
}

这个问题的真正解决方案是方程 1。正如我自己在上一个问题上已经回答的那样,此代码由于灾难性取消而失败。然而,现在我发现了一件更奇怪的事情。如果您使用 long long,它会起作用,而据我所知,它们的范围小于 doubles。为什么?

4

3 回答 3

4

long long范围更小,double.

然而,这不是这里的工作。您的计算实际上也超出了范围long long,但是由于系统上处理整数溢出的方式,正确的结果无论如何都会失败。(请注意,有符号整数溢出的行为不受 C 标准限制,但“通常”的行为与您在此处看到的一样)。

如果你看一下中间结果x*x*x*x,你会发现如果你使用 double 计算它,它有一个合理的值;不精确,但圆润且足以满足大多数用途。然而,如果你在 中计算它long long,你会发现一个起初看起来绝对是疯狂的数字,因为溢出。

于 2012-05-11T16:39:32.867 回答
1

在 double 中有尾数和指数位。对于大双打,两个双打之间的距离(相同的指数,尾数加 1)结果远大于 1。因此,您处于与无穷大 + 1 = 无穷大相同的情况。

long long 会溢出,以 2 为模计算,因此应该为 1 的结果确实可以是 1。

于 2012-05-11T16:46:38.060 回答
0

浮点类型的溢出可以被视为未定义或错误,具体取决于语言和环境。整数类型的溢出只是简单地环绕(有时仍会产生正确的结果,有时不会)。

于 2012-05-11T16:39:29.363 回答