2013-11-21 5 views
0

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

#include <iostream> 
#include <fstream> 
#include <string> 
#include <iomanip> 
using namespace std; 

#define A1 0x00 //0000-0 000 
#define T1 0x01 //0000-0 001 
#define G1 0x02 //0000-0 010 
#define C1 0x03 //0000-0 011 
#define N1 0x04 //0000-0 100 

void bitcompress(int value, int bits, int end_flag); 
int getHex(const char letter); 

int main(int argc, const char * argv[]) 
{ 
    string test = "GATGATGG";//compresses to 0x40a052 with my definitions 
    for (int i=0; i<test.size(); i++) { 
     int val = getHex(test.at(i)); 
     bitcompress(val, 3, 0); 
    } 

    return 0; 
} 

void bitcompress(int value, int bits, int end_flag) 
{ 
    static char data = 0; 
    static int bitsused = 0; 

    int bytesize = 8; 
    int shift = bytesize - bitsused - bits; 

    //cout << "bitsused = " << bitsused << endl; 
    //cout << "shift = " << shift << endl << endl; 

    if(shift >= 0) { 
     data  |= (value << shift); 
     bitsused += bits; 
     if(bitsused == bytesize) { 
      cout << hex << setw(2) << setfill('0') << (int)data; 
      data  = 0; 
      bitsused = 0; 
     } 
    } 

    else { 
     data |= (value >> -shift); 
     cout << hex << setw(2) << setfill('0') << (int)data; 
     data = 0; 
     shift = bytesize + shift; 

     if(shift >= 0) { 
      data |= (value << shift); 
      bitsused = bytesize - shift; 
     } else { 
      data |= (value >> -shift); 
      cout << hex << setw(2) << setfill('0') << (int)data; 
      data  = 0; 
      shift = bytesize + shift; 
      data |= (value << shift); 
      bitsused = bytesize - shift; 
     } 
    } 

    if(end_flag && bitsused != 0) 
     cout << hex << setw(2) << setfill('0') << (int)data; 
} 

int getHex(const char letter) { 
    if (letter == 'A') 
     return (int)A1; 
    else if (letter == 'T') 
     return (int)T1; 
    else if (letter == 'G') 
     return (int)G1; 
    else if (letter == 'C') 
     return (int)C1; 
    else 
     return (int)N1; 
} 

Я ожидаю 0x40a052, но это выходы:

40ffffffa052 

Я не уверен, где все ф-ых как. Если вы прокомментируете все изгибы после инструкции if и раскомментируете предыдущие, вы увидите, что значения сдвига и битвы верны. Тем не менее, если у вас есть все без ранения, значение «shift» получает назначение fffffffe, а не -2 (что можно увидеть, комментируя цитаты ниже оператора if). Я чувствую, что проблема может быть связана с выходом в поток, но я не уверен. Любая помощь будет принята с благодарностью!

+0

Если вы знаете, что ваше целое число будет не меньше 0, я предлагаю вам использовать 'unsigned char'. –

ответ

1

Измените тип data от char до unsigned char. В какой-то момент data имеет отрицательное значение, поэтому, когда вы отбрасываете его на int, его распечатайте с 1-го.

+0

Это исправило мою проблему, спасибо! –

Смежные вопросы