C 大数字之间的比较不';好像不行
我写的程序取两个数,进行除法和模运算 代码是C 大数字之间的比较不';好像不行,c,if-statement,C,If Statement,我写的程序取两个数,进行除法和模运算 代码是 #define ADDRESS_SPACE 4294967295 int main (int argc, char *argv[]) { long int pagesize = atoi(argv[1]), virtaddr = atoi(argv[2]); if (virtaddr >= ADDRESS_SPACE) {puts("Address is too large"); return 1;} printf(
#define ADDRESS_SPACE 4294967295
int main (int argc, char *argv[]) {
long int pagesize = atoi(argv[1]), virtaddr = atoi(argv[2]);
if (virtaddr >= ADDRESS_SPACE) {puts("Address is too large"); return 1;}
printf("%lu\n", virtaddr);
printf("%lu\n", ADDRESS_SPACE);
printf("Page = %lu\nOffset = %lu\n", virtaddr/pagesize, virtaddr%pagesize);
return 0;
}
执行/page 1024 99999999999999999999999999999999999999999999999999999999
将给出以下输出
18446744073709551615
4294967295
Page = 0
Offset = 18446744073709551615
如果
virtaddr
大于ADDRESS\u SPACE
,为什么If语句不能工作?我知道有溢出,但打印变量不会显示任何错误,它们仍然是数字(长整型可以接受的最大值).因为atoi
从ASCII转换为int
,而不是长int
,而且99999999999999999999999999999
转换为int
太大了
尝试使用字符串转换并尝试更合理的数字。因为
atoi
将ASCII转换为int
,而不是长int
,而且99999999999999999999999999999999999999999
转换为int
要大得多
尝试使用进行字符串转换,并尝试更合理的数字。
atoi
当数字超出范围时返回INT\u MAX
。将32位int
与4294967295
进行比较总是错误的,因为int\u MAX
大约小两倍。如果使用而不是atoi
,您的解决方案将有效,因为结果将在long
范围内。或者,当数字超出范围时,可以使用INT\u MAX
而不是ADDRESS\u SPACE
atoi
返回INT\u MAX
。将32位int
与4294967295
进行比较总是错误的,因为int\u MAX
大约小两倍。如果使用而不是atoi
,您的解决方案将有效,因为结果将在long
范围内。或者,您可以使用INT\u MAX
而不是ADDRESS\u SPACE
18446744073709551615
是-1的未签名版本virtaddr
已签名,但显示为未签名;当然-1将小于任何有效的正数。18446744073709551615
是-1的未签名版本virtaddr
已签名,但显示为未签名;当然-1将小于任何有效的正数。嗯。。。可能是因为99999999999999999999999999999999999999999999999999999999
太大,无法放入无符号长字符串中
?您的变量是有符号的,但您打印它们时没有符号。(atoi返回一个int.)(提示:将virtaddr比较为零)它与无符号说明符一起工作。对不起,这个愚蠢的问题,我没有注意到。嗯。。。可能是因为99999999999999999999999999999999999999999999999999999999
太大,无法放入无符号长字符串中
?您的变量是有符号的,但您打印它们时没有符号。(atoi返回一个int.)(提示:将virtaddr比较为零)它与无符号说明符一起工作。对不起,这个愚蠢的问题,我没有注意到。这个数字是用来测试溢出情况下会发生什么。但看起来只是缺少了未签名的位。现在,即使使用了愚蠢的大数字,它也能工作。这个数字被用来测试在溢出的情况下会发生什么。但看起来只是缺少了未签名的位。现在它甚至可以处理愚蠢的大数字。实际上,atoi
在溢出时调用了未定义的行为。永远不要使用此函数。@R。。不是根据:“如果正确的值超出了可表示值的范围,则返回INT_MAX或INT_MIN。”该站点不是“参考”。它是网络上C和C++错误信息的1来源。不要用它。阅读标准。7.20.1.2:“atoi、atol和atol函数分别将nptr指向的字符串的初始部分转换为int、long int和long long int表示。除了错误行为外,它们等效于…atoi:(int)strtol(nptr,(char**)NULL,10)”唯一有问题的部分是它的含义“除了出错时的行为“并且没有指定任何错误行为……但是,在等价的情况下,调用strtol
并强制转换到int
不会在int
溢出时给出int\u MAX
或int\u MIN
的值。相反,它将提供一个实现定义的long
转换。POSIX版本的规范(应该与C对齐)更明确:“如果无法表示值,则行为未定义。”()实际上atoi
在溢出时调用了未定义的行为。永远不要使用此函数。@R。。不是根据:“如果正确的值超出了可表示值的范围,则返回INT_MAX或INT_MIN。”该站点不是“参考”。它是网络上C和C++错误信息的1来源。不要用它。阅读标准。7.20.1.2:“atoi、atol和atol函数分别将nptr指向的字符串的初始部分转换为int、long int和long long int表示。除了错误行为外,它们等效于…atoi:(int)strtol(nptr,(char**)NULL,10)”唯一有问题的部分是它的含义“除了出错时的行为“并且没有指定任何错误行为……但是,在等价的情况下,调用strtol
并强制转换到int
不会在int
溢出时给出int\u MAX
或int\u MIN
的值。相反,它将提供一个实现定义的long
转换。POSIX版本的规范(应该与C对齐)更明确:“如果无法表示值,则行为未定义。”()