我正在尝试使用我在下面的C中编写的函数将十进制值转换为二进制。我无法弄清楚为什么它打印32个零而不是二进制值2的原因。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
int binaryConversion(int num){
int bin_buffer[32];
int mask = INT_MIN;
for(int i = 0; i < 32; i++){
if(num & mask){
bin_buffer[i] = 1;
mask >> 1;
}
else{
bin_buffer[i] = 0;
mask >> 1;
}
}
for(int j = 0; j < 32; j++){
printf("%d", bin_buffer[j]);
}
}
int main(){
binaryConversion(2);
}
谢谢
答案 0 :(得分:3)
两个错误:
>>
而不是>>=
,因此实际上并没有更改mask
。mask
声明为unsigned
,所以当您移位时,它将得到符号扩展,这是您不希望的。答案 1 :(得分:2)
如果您输入:
printf("%d %d\n", num, mask);
立即在您的for
循环中,您会看到原因:
2 -2147483648
2 -2147483648
2 -2147483648
2 -2147483648
:
2 -2147483648
表达式mask >> 1
确实将mask
的值右移,但实际上并未将其分配回mask
。我认为您想要使用:
mask >>= 1;
最重要的是(一旦解决了这个问题),您会发现掩码中的值有些奇怪,因为右移负值可以保留符号,这意味着您将得到设置多个位。
使用无符号整数会更好,因为>>
运算符将对它们进行更符合您期望的操作。
此外,将所有这些位写入缓冲区没有什么意义,只是以后可以将它们打印出来。除非您需要对这些位进行一些操作(在这里似乎不是这种情况),否则您可以直接在计算出它们时直接输出它们(并摆脱现在不必要的i
变量)。 / p>
因此,考虑到所有这些要点,您可以极大地简化代码,例如使用以下完整程序:
#include <stdio.h>
#include <limits.h>
int binaryConversion(unsigned num) {
for (unsigned mask = (unsigned)INT_MIN; mask != 0; mask >>= 1)
putchar((num & mask) ? '1' : '0');
}
int main(void) {
binaryConversion(2);
putchar('\n');
}
还有一点需要注意,实际上只需要设置最高位就不需要INT_MIN
的值。由于C当前允许处理负数的补码和符号幅度(以及二进制补码),因此INT_MIN可能会设置一个设置了多个位的值(例如-32767
)。 / p>
可以采取一些措施来从C中删除这些很少使用的编码(C ++ 20已将其标记出来),但是,为了实现最大的可移植性,您可以选择使用以下功能:
int binaryConversion(unsigned int num) {
// Done once to set topBit.
static unsigned topBit = 0;
if (topBit == 0) {
topBit = 1;
while (topBit << 1 != 0) topBit <<= 1;
}
// Loop to process all bits.
for (unsigned mask = topBit; mask != 0; mask >>= 1)
putchar(num & mask ? '1' : '0');
}
这将在您第一次调用该函数时将高位设置为高,而不考虑负编码的变化情况。只要注意是否在线程程序中同时调用它即可。
但是,如上所述,这可能不是必需的,使用非常粗心/不幸的工业机器操作员的手指上,使用其他两种编码的环境数量是可以计数的。
答案 2 :(得分:1)
您已经回答了有关使用>>
而不是=>>
的主要问题。但是,从根本上讲,不需要将1
和0
缓存在int
(例如int bin_buffer[32];
)数组中,也不需要使用{ {1}} variadic
函数用于显示printf
值,如果您要做的只是输出数字的二进制表示形式。
相反,您只需要int
来输出putchar()
或'1'
,这取决于是否设置了位或将其清除。您还可以通过提供所需的表示形式的大小来使输出功能更有用,例如'0'
(8位),byte
(16位),等等。
例如,您可以这样做:
word
您可以通过其中设置要显示的位数,例如
使用/输出示例
#include <stdio.h>
#include <limits.h>
/** binary representation of 'v' padded to 'sz' bits.
* the padding amount is limited to the number of
* bits in 'v'. valid range: 0 - sizeof v * CHAR_BIT.
*/
void binaryConversion (const unsigned long v, size_t sz)
{
if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
if (!v) { while (sz--) putchar ('0'); return; }
if (sz > sizeof v * CHAR_BIT)
sz = sizeof v * CHAR_BIT;
while (sz--)
putchar ((v >> sz & 1) ? '1' : '0');
}
int main(){
fputs ("byte : ", stdout);
binaryConversion (2, 8);
fputs ("\nword : ", stdout);
binaryConversion (2, 16);
putchar ('\n');
}
您的方法没有什么问题,但是可能会有更简单的方法来获得相同的输出。
如果您还有其他问题,请告诉我。
答案 3 :(得分:0)
INT_MIN
是一个负数,因此当您使用>>
移到右侧时,最高有效位仍然是1
而不是零,最后以{{1 }}所有位的值为mask=11111...111
。同样1
的值也没有改变。最好改用mask
。您可以尝试对>>=
进行屏蔽,并像这样将0x1
的实际值而不是num
移位。
mask