0

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

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

4

4 回答 4

1

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

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

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

正如人们所提到的,你最好使用CHAR_BIT8。我很确定,而不是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 > 0)

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

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

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

于 2013-02-25T21:34:14.987 回答
1

这不是通过所有位来找到高位,而是仅通过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);
}
于 2013-02-25T23:27:42.283 回答
0
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]);
    }



}
于 2013-02-25T20:37:13.957 回答
0

我不会通过您的整个答案来提供您重新编写的代码,但删除最重要的位很容易。这是因为通过使用以 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。

于 2013-02-25T21:31:39.297 回答