0

我编写了这个简单的代码来生成高达 1005 的所有正整数的 4 次方。它只能在整数 215 之前正常工作。之后它会给出错误的读数。为什么这样?

# include<stdio.h>

int main(void)
{
    int i;
    unsigned long long int j;

    for (i = 1; i <= 1005; i++){
        j = i*i*i*i;
        printf("%i.........%llu\n",i,j);

    }

    return 0;

}
4

2 回答 2

6

您可以通过进行这个小改动来修复它。

unsigned long long i;

问题是,在该行j = i*i*i*i;中,右手边int在被分配到之前被计算为一个j。因此,如果i^4超过整数限制,它基本上会首先开始变为负数,并在高位被剪裁时开始循环。当负数分配给 时j,因为junsigned-i变成max - i,这就是巨大数字的来源。您还需要将printf格式说明符从更改%i%llufor i

您也可以通过执行以下操作来解决此问题

j = (unsigned long long)i*i*i*i;

这基本上强制强制转换为j在执行乘法之前的类型。

健全性检查 - 215 ^4= 2136750625,非常接近上限signed int2,147,483,647。

于 2013-01-12T08:43:40.730 回答
4

i*i产生一个int. i*i*i和也是如此i*i*i*i。215 是 4 次方适合 32 位的最大正整数int

除此之外,结果通常会被截断(通常是因为严格来说,您遇到了未定义行为的情况;有符号整数溢出导致根据 C 标准的 UB)。

您可能希望将其i转换为unsigned long long或将其定义为unsigned long long,因此乘法是 64 位的:

    j = (unsigned long long)i*i*i*i;
于 2013-01-12T08:48:01.060 回答