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

3

我的目标是让一个十进制数,在二进制中有与用户指定相同数量的前导1,并存储在 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,我正在尝试将其转换为十进制。但是,它给出的输出结果应该是4294967040,而不是-128。我知道某些部分存在内存溢出问题,但我无法找出原因。我已经尝试了几种方法,例如将subnetMask的数据类型替换为intlong

2
%d 用于有符号整数。尝试使用 printf("%lu",subnetMask); - bruceg
1
请注意,在从输入中读取值后,不再使用mask - kaylum
1
%lu修复了问题。现在循环条件已更改,它能够正常运行。谢谢大家。 - dave
1
不要使用pow(2, counter),请改用1L << counter - phuclv
1
pow(2,counter) --> (1ul << counter) - chux - Reinstate Monica
显示剩余2条评论
2个回答

2

您可以在32位或更大的机器上解决原始问题而无需循环:

unsigned long subnetMask = mask ? - (1<<(32 - mask)) : 0;

此外,在32位机器上,子网掩码不必太长。以下代码证明了表达式的正确性:
 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,所以不足为奇的是输入"4294967040"打印出来为-128。你要找的是%lu格式说明符。

  2. pow返回一个double,而不是一个int或者unsigned long。你可能想将pow结果转换为int,或者更好的方法是,使用1UL << counter自动得到同样的结果作为unsigned long


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接