2013-02-25 3 views
0

Я написал эту функцию, чтобы удалить самый старший бит в каждом байте. Но эта функция, похоже, не работает так, как я ее хотел.маскировка наиболее значимого бита

Размер выходного файла всегда равен «0», я не понимаю, почему ничего не было записано в выходной файл. Есть ли лучший и простой способ удалить самый старший бит в каждом байте?

+1

Что это такое 'nBuffer << 8;'? – ouah

+2

Если на '8' вы имеете в виду количество бит в символе, используйте' CHAR_BIT'. Магические числа очень трудно справиться. –

+0

все, что я хочу сделать, это переписать его, это выглядит действительно неправильно для меня.Это похоже на то, как вы пытаетесь выполнить битрейт по счету, который больше байта. –

ответ

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]); 
    } 



} 
+0

Я думаю, что он хочет уменьшить размер буфера с помощью MSB * # Elements. –

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

1

В отношении операторов сдвига в разделе 6.5.7 стандарта C говорится:

Если значение правого операнда отрицательное или больше или , равное ширине продвинутого левого операнда, то поведение равно неопределенным.

Итак, во-первых, удалите 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

Вместо того чтобы проходить через все биты, чтобы найти высокий, это проходит только по 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); 
} 
Смежные вопросы