[英]masking most significant bit
我写了这个函数来删除每个字节中最重要的位。 但是这个功能似乎并没有像我希望的那样工作。
输出文件大小始终为“0”,我不明白为什么没有写入输出文件。 是否有更好,更简单的方法来删除每个字节中最重要的位?
关于班次操作员,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 > 0)
现在让我们关注注释掉的代码:
if((write(out_fd, bit_buf, sizeof(char))) == -1)
oops("Cannot write on the file", "");
你在哪里为bit_buf赋值? 使用未初始化的变量是未定义的行为。
它不是通过所有的位来找到高位,而是仅通过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);
}
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]);
}
}
我不会通过您的整个答案来提供您重写的代码,但删除最重要的一点很容易。 这是因为通过使用转换为整数的log base 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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.