我的目标是在用户指定的二进制文件中包含一个十进制数字,它存储在unsigned long
变量mask
中;其余位将设置为零。
int mask;
scanf("%d",&mask);
unsigned long subnetMask = 0;
int counter = 31,a;
for(int a = mask, a > 0; a--) {
subnetMask += pow(2,counter);
counter--;
}
printf("%ld",subnetMask);
现在,当用户键入24时,掩码的二进制字符串是11111111 11111111 11111111 00000000,我试图将其转换为基数10.
而不是给我4294967040的正确输出,它给了我-128。我知道某些部分存在内存溢出,但我无法弄清楚在哪里。我尝试过多种方法,例如将subnetMask
的数据类型替换为int
和long
。
答案 0 :(得分:2)
您可以在32位或更大的计算机上解决原始问题而无需循环:
unsigned long subnetMask = mask ? - (1<<(32 - mask)) : 0;
此外,在32位计算机上,subnetMask不必很长。表达式的正确性用以下代码显示:
for(int mask = 0; mask < 33; mask++)
{
unsigned subnetMask = mask ? - (1<<(32 - mask)) : 0;
printf("%2d => %08x = %u (decimal)\n", mask, subnetMask, subnetMask );
}
答案 1 :(得分:1)
有几件事:
%ld
格式说明符需要signed int
。数字0b11111111111111111111111100000000
在被解释为二进制补码中的有符号数时肯定看起来像负数,因为位串的左边部分都是1,所以它听起来并不令人惊讶输入&#34; 4294967040&#34;打印出-128。您正在寻找的是%lu
格式说明符。
pow
返回double
,而不是int
或unsigned long
。您可能希望将pow
结果转换为int
,或者更好,只需使用1UL << counter
自动获得与unsigned long
相同的结果。