zeus_masta_funk
zeus_masta_funk

Reputation: 1498

Can't get my Compression algorithm to function correctly

I am using a function to compress a sequence of characters into 3 bits. My alphabet contains the letters ATGCN. I am inputting a test string and getting an answer that has the correct values but also some values I was not expecting. Here is my code:

#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;
}

I am expecting 0x40a052 but this outputs:

40ffffffa052

I'm unsure where all of the f's are coming from. If you comment out all of the couts after the if statement and uncomment the ones before, you see that the shift and bitsused values are correct. However, if you have them all uncommented the "shift" value get an assignment of fffffffe, instead of -2 (which can be seen by commenting out the couts below the if statement). I feel like the issue may be something to do with outputting to the stream, but I'm not sure. Any help would be greatly appreciated!

Upvotes: 0

Views: 78

Answers (1)

Taylor Brandstetter
Taylor Brandstetter

Reputation: 3623

Change the type of data from char to unsigned char. At some point, data has a negative value, so when you cast it to int to print it, it's left-filled with 1's.

Upvotes: 1

Related Questions