无法将二进制转换为十进制

时间:2017-01-25 01:57:45

标签: c bit-manipulation bit

我的目标是在用户指定的二进制文件中包含一个十进制数字,它存储在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的数据类型替换为intlong

2 个答案:

答案 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)

有几件事:

  1. %ld格式说明符需要signed int。数字0b11111111111111111111111100000000在被解释为二进制补码中的有符号数时肯定看起来像负数,因为位串的左边部分都是1,所以它听起来并不令人惊讶输入&#34; 4294967040&#34;打印出-128。您正在寻找的是%lu格式说明符。

  2. pow返回double,而不是intunsigned long。您可能希望将pow结果转换为int,或者更好,只需使用1UL << counter自动获得与unsigned long相同的结果。

    < / LI>