【问题标题】:masking most significant bit屏蔽最高有效位
【发布时间】:2013-02-11 02:29:09
【问题描述】:

我编写了这个函数来删除每个字节中的最高有效位。但是这个功能似乎并没有按照我想要的方式工作。

输出文件大小始终为“0”,我不明白为什么什么都没有写入输出文件。有没有更好更简单的方法来删除每个字节中的最高位??

【问题讨论】:

  • nBuffer << 8; 是什么?
  • 如果8是指一个字符的位数,请使用CHAR_BIT。幻数很难处理。
  • 所有我想做的就是重写它,它看起来对我来说真的错了。看起来你正试图通过比一个字节大的计数方式进行位移
  • 如何使用 Bit-Fields 制作 7 位数据类型并制作其数组。
  • @modifiablelvalue nBuffer << 8; 没有副作用,所以没用。也许 OP 想做nBuffer <<= 8;

标签: c compression bit-manipulation binaryfiles


【解决方案1】:

关于移位运算符,C 标准的第 6.5.7 节说:

如果右操作数的值为负数或大于或 等于提升的左操作数的宽度,行为是 未定义。

首先,删除nBuffer << 8;。即使它被很好地定义,它也不会是一个赋值运算符。

正如人们所提到的,使用 CHAR_BIT 比使用 8 更好。我很确定,你的意思不是 0x7f,而是 UCHAR_MAX >> 1,而不是 7,你的意思是 CHAR_BIT - 1

在这里,我们只关注 nBuffer 和 bit_count。我将注释掉任何不使用其中任何一个的内容。

 bit_count += 7;

 if (bit_count == 7*8)
  {
    *out_buf++ = nBuffer;
    /*if((write(out_fd, bit_buf, sizeof(char))) == -1)
      oops("Cannot write on the file", "");*/
    nBuffer << 8;
    bit_count -= 8;
  }
nBuffer = 0;
bit_count = 0;

在这段代码的最后,nBuffer 的值是多少? bit_count 呢?这会对您的第二个循环产生什么影响? while (bit_count &gt; 0)

现在让我们关注注释掉的代码:

    if((write(out_fd, bit_buf, sizeof(char))) == -1)
      oops("Cannot write on the file", "");

您在哪里为 bit_buf 赋值?使用未初始化的变量是未定义的行为。

【讨论】:

    【解决方案2】:

    不是通过所有位来找到高位,而是只通过1 位。 high() 返回参数的高位,如果参数为零,则返回零。

    inline int high(int n)
    {
        int k;
    
        do {
            k = n ^ (n - 1);
            n &= ~k;
        } while (n);
        return (k + 1) >> 1;
    }
    
    inline int drop_high(int n)
    {
        return n ^ high(n);
    }
    

    【讨论】:

      【解决方案3】:
      unsigned char remove_most_significant_bit(unsigned char b)
      {
          int bit;
          for(bit = 0; bit < 8; bit++)
          {
              unsigned char mask = (0x80 >> bit);
              if( mask & b) return b & ~mask;
          }
          return b;
      }
      
      void remove_most_significant_bit_from_buffer(unsigned char* b, int length)
      {
          int i;
          for(i=0; i<length;i++)
          {
              b[i] = remove_most_significant_bit(b[i]);
          }
      }
      
      
      
      void test_it()
      {
          unsigned char data[8];
          int i;
          for(i = 0; i < 8; i++)
          {
              data[i] = (1 << i) + i;
          }
          for(i = 0; i < 8; i++)
          {
              printf("%d\r\n", data[i]);
          }
          remove_most_significant_bit_from_buffer(data, 8);
          for(i = 0; i < 8; i++)
          {
              printf("%d\r\n", data[i]);
          }
      
      
      
      }
      

      【讨论】:

      • 我想他也想将缓冲区的大小减少 MSB*#Elements。
      【解决方案4】:

      我不会通过您的整个答案来提供您重新编写的代码,但删除最重要的位很容易。这是因为通过使用以 2 为底的对数转换为整数可以很容易地找到最高有效位。

      #include <stdio.h>
      #include <math.h>
      
      int RemoveMSB(int a)
      {
          return a ^ (1 << (int)log2(a));
      }
      
      int main(int argc, char const *argv[])
      {
          int a = 4387;
      
          printf("MSB of %d is %d\n", a, (int)log2(a));
      
          a = RemoveMSB(a);
      
          printf("MSB of %d is %d\n", a, (int)log2(a));
          return 0;
      }
      

      输出:

      MSB of 4387 is 12
      MSB of 291 is 8
      

      因此,二进制的 4387 是 1000100100011,最高有效位为 12。

      同样,二进制的 291 是 0000100100011,最高有效位为 8。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-25
        • 2020-09-07
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 2017-07-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多