为什么命令行参数-12345678969被认为是> 1?

时间:2018-02-17 14:58:06

标签: c command-line int argv atoi

这是检查给定号码是否为阿姆斯壮号码的程序

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

int main(int argc, char *argv[])
{   
    int num,n,sum=0;
    num=atoi(argv[1]);
    if(argc==2 && num>0 && num<=INT_MAX)    
    {   n=num;
        while(num>0)
        {
            sum+=(num%10)*(num%10)*(num%10);
            num/=10;
        }
        if(sum==n)
            printf("%d is an armstrong number",n);
        else    
            printf("%d is not an armstrong number",n);
        return 0;    
    }
    else
        return 1;
}

我在这里提供了一个输入

-12345678969

预期输出

命令以非零状态1退出

但它显示

539222919不是阿姆斯特朗号

2 个答案:

答案 0 :(得分:4)

数字'-12345678969'需要过多的int位。大多数C编译器中的int是32-bits wide,但是这个位不足以包含'-12345678969'。

atoi()只是尝试将数字转换为32位整数,这意味着'-12345678969'的输入值的一部分被切断;在基数2(二进制)表示中,输入数字将适合64位整数:

1111111111111111111111111111110100100000001000111110001110000111

atoi()切断高位32位时,低位32位保持不变:

00100000001000111110001110000111

不再包含任何符号(您从左侧首先读取的位为0,表示没有符号,因此签名int中的数字不是负数)。

十进制表示的数字将等于539222919,这是您在案例中看到的数字。

答案 1 :(得分:2)

-12345678969
十六进制中的

0xFFFFFFFD2023E387

(每个数字代表4位)

atoi()返回int,其中很可能是32位。

0xFFFFFFFD2023E387的最不重要的32位给我们0x2023E387实际上是

539222919 

十进制。