Gcc C迭代到一个非常大的数字-编译器关于无符号int的警告
我有以下代码:Gcc C迭代到一个非常大的数字-编译器关于无符号int的警告,gcc,c,compiler-warnings,gcc-warning,unsigned-integer,Gcc,C,Compiler Warnings,Gcc Warning,Unsigned Integer,我有以下代码: #include <stdio.h> #define POWER 10000000000000000000 int main() { int i; for (i = 0; i < POWER; i++) { .... } return 0; } #包括 #定义功率100000000000000000 int main() { int i; 对于(i=0;i
#include <stdio.h>
#define POWER 10000000000000000000
int main()
{
int i;
for (i = 0; i < POWER; i++)
{
....
}
return 0;
}
#包括
#定义功率100000000000000000
int main()
{
int i;
对于(i=0;i
编译器会给我以下警告:
ex1.c:33:19:警告:整数常量太大,以至于它是无符号的[默认情况下启用]
ex1.c:33:2:警告:此十进制常量仅在ISO C90中无符号[默认启用]
如何使用
I
迭代所有值,直到达到POWER
?我尝试将I
声明为unsigned int
,但警告仍然存在。值100000000000000000
(=10^19,如果我计算正确)需要分配64位,这是8字节。您将收到警告,因为类型int
使用4个字节,因此无法存储该数字。使用unsigned int
可以将可存储的最大正数翻倍,但它是4294967295,这仍然不够。如果要使用int
,可以使用迭代循环
for(i=0;i<p;i++){
for(j=0;j<p;j++){
for(k=0<p;k++){
/*loop*/
}
}
}
for(i=0;i值100000000000000000
(=10^19,如果我计算正确)需要为分配64位,这是8个字节。您将收到警告,因为类型int
使用4个字节,因此无法存储该数字。使用unsigned int
可以将可存储的最大正数加倍,但仍然是4294967295,这是不够的。如果要使用int
,您可以使用迭代循环
for(i=0;i<p;i++){
for(j=0;j<p;j++){
for(k=0<p;k++){
/*loop*/
}
}
}
for(i=0;i常数100000000000000000
需要64位来表示它。在十六进制中,它是0x8ac7230489e80000
。它可以用无符号64位类型表示,但不能用有符号64位类型表示
从C99开始,所有整数常量都是某种有符号类型:值将适合的int
、long int
或long long int
中的第一个
C90(还没有long-long-int
)有不同的规则。在C90中,无固定小数整数常量的类型为int
、long-int
或无符号长int
gcc的默认模式是-std=gnu90
,它支持C90标准加上GNU特定的扩展。如果您在64位系统上,long
和无符号long
为64位。根据C90规则,常量的类型为无符号long
(假设无符号long
至少为64位)。在C99和更高版本的规则下,假设没有大于64位的整数类型,则这是违反约束的。(gcc版本5将默认值更改为-std=gnu11
)
显然是在C90规则下运行的编译器警告您,100000000000000000
的含义因编译器运行的标准版本而异
您可以通过以下更改使程序“正常工作”:
#define POWER 10000000000000000000ULL // suffix to specify the type
...
for (unsigned long long = 0; i < POWER; i ++)
...
#定义POWER 100000000000000000ull//后缀以指定类型
...
for(无符号长=0;i
但是,尽管这使程序有效,但它并不实用。以每纳秒一次迭代的速度,这个循环将需要3个多世纪才能完成。我自己的相当现代化的计算机在大约1.6纳秒的时间内执行一次空for
循环的迭代。无论你想解决什么问题,我建议用一种不同的方法来解决它,或者把它简化成一个更小的问题。执行这个循环的最快方法是等待几十年,让硬件变得更快,然后编译并执行它
(这假设循环体是非平凡的。如果循环体什么都不做,编译器可能会优化整个循环。)常数100000000000000000
需要64位来表示。在十六进制中,它是0x8ac7230489e80000
。它可以用无符号64位类型表示,但不能用有符号64位类型表示
从C99开始,所有整数常量都是某种有符号类型:值将适合的int
、long int
或long long int
中的第一个
C90(还没有long-long-int
)有不同的规则。在C90中,无固定小数整数常量的类型为int
、long-int
或无符号长int
gcc的默认模式是-std=gnu90
,它支持C90标准加上GNU特定的扩展。如果您在64位系统上,long
和无符号long
为64位。根据C90规则,常量的类型为无符号long
(假设无符号long
至少为64位)。在C99和更高版本的规则下,假设没有大于64位的整数类型,则这是违反约束的。(gcc版本5将默认值更改为-std=gnu11
)
显然是在C90规则下运行的编译器警告您,100000000000000000
的含义因编译器运行的标准版本而异
您可以通过以下更改使程序“正常工作”:
#define POWER 10000000000000000000ULL // suffix to specify the type
...
for (unsigned long long = 0; i < POWER; i ++)
...
#定义POWER 100000000000000000ull//后缀以指定类型
...
for(无符号长=0;i
但是,尽管这使程序有效,但它并不实用。以每纳秒一次迭代的速度,这个循环将需要3个多世纪才能完成。我自己的相当现代化的计算机在大约1.6纳秒的时间内执行一次空for
循环的迭代。无论你想解决什么问题,我建议使用不同的方法来解决这个问题,或者将它简化为一个更小的问题。执行这个循环的最快方法是等待几十年,让硬件变得更快,然后编译