【问题标题】:how do i limit the binary displayed in my decimal to binary converter?如何限制以十进制显示的二进制到二进制转换器?
【发布时间】:2019-07-15 02:21:00
【问题描述】:

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

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。

那么有没有办法限制二进制输出与准确显示其转换所需的最重要的空间相对应?

【问题讨论】:

  • 欢迎来到 Stack Overflow。请阅读the help pages,取the SO tour,阅读有关how to ask good questions,以及this question checklist
  • 至于解决问题的可能方法(据我了解),您可以找到最高的非零 nibble 并从那里开始打印。
  • 减一,为什么是16?您正在使用 17 位数字?
  • 我在 0 到 65537 之间的数字范围内工作。我刚刚设置了 'i = 15' 以从最大数字中获取最小位。
  • 这是一个非常奇怪的范围。 16 位无符号整数从 065535(含)。

标签: c binary decimal converters


【解决方案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 位。

完整示例:

#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

【讨论】:

  • 嗯,这完全超出了我目前对 C 编程的理解范围,但我可以做出一些解释。我仍然很欣赏这些信息,但令我震惊的是,似乎没有更简单的方法可以将您创建的二进制数排序为 4 的增量。不一定将其分解为第 4 位,但只需将其限制为 4、8 , 16, 32 如果它在该范围内。这更有意义吗?就像它是一个介于 1 和 15 之间的数字,我希望它显示在 4 个空格中。非常感谢所有这些信息。我很高兴整理这一切。
【解决方案2】:

这样做的一种方法是使用标志变量来检查我们是否有非零 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 的空间中。
  • @AnonLaughingman 很高兴为您提供帮助,您可以点击绿色勾号,表示此答案解决了您的问题。
  • 也感谢您提供的信息。现在我要问我的下一个问题了!
猜你喜欢
  • 2016-08-26
  • 1970-01-01
  • 2021-07-29
  • 2020-06-27
  • 2023-04-11
  • 2020-06-25
  • 2012-05-28
  • 2013-05-14
  • 1970-01-01
相关资源
最近更新 更多