この関数を作成して、すべてのバイトの最上位ビットを削除しました。しかし、この機能は私が望んでいたようには機能していないようです。
出力ファイルのサイズは常に「0」です。出力ファイルに何も書き込まれていない理由がわかりません。すべてのバイトの最上位ビットを削除するためのより良い簡単な方法はありますか??
この関数を作成して、すべてのバイトの最上位ビットを削除しました。しかし、この機能は私が望んでいたようには機能していないようです。
出力ファイルのサイズは常に「0」です。出力ファイルに何も書き込まれていない理由がわかりません。すべてのバイトの最上位ビットを削除するためのより良い簡単な方法はありますか??
シフト演算子に関して、C 標準のセクション 6.5.7 は次のように述べています。
右オペランドの値が負の値であるか、プロモートされた左オペランドの幅以上である場合、動作は未定義です。
ということで、まずは削除nBuffer << 8;
。明確に定義されていたとしても、代入演算子にはなりません。
人々が言及したように、CHAR_BIT
8 よりも使用したほうがよいでしょ0x7f
う。UCHAR_MAX >> 1
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 はどうですか?2 番目のループにどのような影響がありますか?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]);
}
}
作り直したコードを提供するために回答全体を説明することはしませんが、最も重要なビットを削除するのは簡単です。これは、整数に変換された底 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 です。