我如何限制以十进制显示的二进制到二进制转换器?

how do i limit the binary displayed in my decimal to binary converter?

到目前为止我有这个代码:

for ( int i = 16; i >=0; i--){
   int k = n >> i;
   if (k & 1)
     printf("1");
   else
     printf("0");
}

我对 C 非常陌生,我正在为 class 开发十进制到二进制的转换器。到目前为止,这是我发现在我的参数范围内有效的方法。唯一的问题是我需要此代码仅将二进制文件输出到它提供的 MSD。

如果我有十进制 15,它应该以二进制显示 1111,如果我有十进制 16,它应该只显示其上方的下一组 4,所以 00010000。

截至目前,我可以将数量设置为我想要的任何值,如 i = 16,但这将显示总共 15 spaces。就好像我输入了小数点一样,我不希望我的程序显示所有多余的不必要的 0。

那么有没有一种方法可以限制二进制输出与准确显示其转换所必需的最重要 space 相对应?

这样做的一种方法是使用标志变量来检查我们是否有非零 msb,并且仅在遇到非零 msb 后才开始打印 0,例如

int flag
for ( int i = 16; i >=0; i--)
{
int k = n >> i;

if (k & 1){
  printf("1");
  flag = 1;
}else{
  if(flag)
    printf("0");
}

要将其以 4 个为一组进行排序,您需要一点一点地处理。打印半字节(值 0 到 15 dec)的函数可能如下所示:

void print_bin_nibble (uint8_t ls_nibble)
{
  for(size_t i=0; i<4; i++)
  {
    uint8_t bitmask = 1u << (4-1-i);
    printf("%c", (ls_nibble & bitmask) ? '1' : '0');
  }
  printf(" ");
}

现在,如果您想按半字节打印数据,同时跳过等于 0000 bin 的半字节的前导零,您需要跟踪是否应该使用布尔标志跳过打印。逻辑是:

if(nibble==0 && remove_zeroes)
{
  ; // do nothing
}
else
{
  remove_zeroes = false;
  print_bin_nibble(nibble);
}

可以重写为(德摩根定律):

if(nibble != 0 || !remove_zeroes)
{
  remove_zeroes = false;
  print_bin_nibble(nibble);
}

打印数字时需要进一步考虑 CPU 字节顺序。我们可以通过多种(不好的)方式逐字节迭代整数,例如使用指针算术或联合。但是这样输出就会依赖于字节顺序,并且在小字节序机器上看起来很奇怪。通过使用移位,我们完全消除了这个可移植性问题,因为它们是字节序无关的。

例如给定一个 32 位整数 u32,我们可以像这样屏蔽掉单个字节:

(u32 >> (24-n*8)) & 0xFF

其中 n 是字节数 0 到 3。我们最终将 n=0 移动 24 位,n=1 移动 16 位,n=2 移动 8 位,n=3 移动 0 位.

完整示例:

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

void print_bin_nibble (uint8_t ls_nibble)
{
  for(size_t i=0; i<4; i++)
  {
    uint8_t bitmask = 1u << (4-1-i);
    printf("%c", (ls_nibble & bitmask) ? '1' : '0');
  }
  printf(" ");
}

void print_bin32 (uint32_t u32)
{
  bool remove_zeroes = true;

  for(size_t i=0; i<sizeof(u32); i++)
  {
    uint8_t byte = (u32 >> (24-i*8)) & 0xFF;
    uint8_t nibble;

    nibble = (uint32_t)byte >> 4;
    if(nibble != 0 || !remove_zeroes)
    {
      remove_zeroes = false;
      print_bin_nibble(nibble);
    }

    nibble = byte & 0xF;
    if(nibble != 0 || !remove_zeroes)
    {
      print_bin_nibble(nibble);
    }
  }
  printf("\n");
}

int main (void)
{
  print_bin32(16);
  print_bin32(0xDEADBEEF);
  print_bin32(0xABBA);
}

输出:

0001 0000
1101 1110 1010 1101 1011 1110 1110 1111
1010 1011 1011 1010