如何将十进制中显示的二进制限制为二进制转换器?

时间:2019-02-21 08:33:32

标签: c binary decimal converters

到目前为止,我有此代码:

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

我是C语言的新手,我正在为一个类使用十进制到二进制转换器。到目前为止,这是我发现在我的参数范围内起作用的内容。唯一的问题是我需要此代码仅将二进制文件输出到给出的MSD。

就像我有小数点15一样,它应该以二进制显示1111,如果我有小数点16,则它应该仅显示比其高的下一组4,即00010000。

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

那么,有没有一种方法可以将二进制输出限制为与准确显示其转换所需的最大有效空间相对应?

2 个答案:

答案 0 :(得分:1)

要以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位移位。 / p>

完整示例:

#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

答案 1 :(得分:0)

一种方法是使用标志变量来检查我们是否有一个非零的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");
}