Decoding an Int using Bitwise Operators (C++)

I've been planning to write a function that takes an int that has arguments encoded into it, IE: 100101010

Before I start writing, I created a test program to make sure I understand how to decode and encode the values. Encoding them worked immediately, but decoding them worked less successfully.

Below is the test code I've been using:

#include <iostream>

using namespace std;

enum Math_Init
{
    INIT_SINE = 1, INIT_COS = 10, INIT_TAN = 100,
    INIT_COT = 1000, INIT_SEC = 10000, INIT_CSC = 100000,
    INIT_ALL = 111111
};

int main()
{
    //cout << "Init Sine: " << INIT_SINE << endl;
    //cout << "Init Sine | Init Cos: " << (INIT_SINE | INIT_COS) << endl;
    //cout << "Init Sine | Init Cos | Init Sec: " << (INIT_SINE | INIT_COS | INIT_SEC)         << endl;
    //cout << "Attempting to Decode Bits..." << endl;
    int c = /*(INIT_SINE | INIT_COS | INIT_SEC);*/ 100011;
    cout << "Value of Bits: " << c << endl;
    cout << "Is Sine Present? " << (c & 1 << 0) << endl;
    cout << "Is Cos Present? " << (c & 1 << 1) << endl;
    cout << "Is Tan Present? " << (c & 1 << 2) << endl;
    cout << "Is Cot Present? " << (c & 1 << 3) << endl;
    cout << "Is Sec Present? " << (c & 1 << 4) << endl;
    cout << "Is Csc Present? " << (c & 1 << 5) << endl;
    system("PAUSE");
    return 0;
}

I've not been able to isolate / decode the values in the int, what am I doing wrong? I've been looking at this to try and fix the issue with no luck: http://www.cprogramming.com/tutorial/bitwise_operators.html

Upvotes: 0

Views: 1408

Answers (3)

macfij
macfij

Reputation: 3209

Math_Init is wrong. those values are decimals, not binaries with bits set on particular position. should be like this:

enum Math_Init
{
    INIT_SINE = 1 << 0, INIT_COS = 1 << 1, INIT_TAN = 1 << 2,
    INIT_COT = 1 << 3, INIT_SEC = 1 << 4, INIT_CSC = 1 << 5,
    INIT_ALL = INIT_SINE | INIT_COS | INIT_TAN | INIT_COT |
               INIT_SEC | INIT_CSC
};

the c value is represented as decimal. here's a not-so-efficient program that converts decimal to binary representation. it might be useful for you to specify some decimal value, see how it's represented in binary and then play with your masks.

int main()
{
    int cx = 27;  /*that's some random base 10 value. play with it*/
    int i;
    int flag = 0;
    cout << cx << " in binary is:" << "\n";
    for (i = 31; i >= 0; i--) {
        int mask = 1 << i;
        int bit = cx & mask;
        if (bit) {
            bit = 1;
            flag = 1;
        }
        if (flag) {
            cout << bit << " ";
        }
    }
    cout << "\n";
    return 0;
}

Upvotes: 0

Quentin
Quentin

Reputation: 63114

You are using int literals (i.e 12345). They are in decimal by default, so what your think are bits are actually tens.

You need to use one of the following type prefixes for bit-aligned literals :

012345    octal
0x12345   hexadecimal
0b010101  binary (GCC or C++14)

Upvotes: 3

Bathsheba
Bathsheba

Reputation: 234635

Your enumerator definitions are suspect: they are base 10 integers. For example 10 (your value for INIT_COS) in binary is 0b1010. Your mask value INIT_ALL is not doing what it should do and that should be specified differently too.

Ideally you want to be able to supply binary literals but unfortunately current C++ standards don't allow that.

The idiom I use (which will be evaluated at compile-time so no performance penalty is incurred) is

INIT_SINE= 1 << 0,
INIT_COS = 1 << 1,
INIT_TAN = 1 << 2,

and so on. For your mask, use INIT_ALL = INIT_SINE | INIT_COS | INIT_TAN etc.

I believe that C++14 will give you binary literals (like 0b1010) which will mean that my idiom will be obsolete. GCC allows this already but note that it is not standard C++ so I'd advise against it in the interests of portability.

Upvotes: 2

Related Questions