0

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

2
  • For readability, it is better to write the masking as c & (1 << 0). This means the very same thing, but not everyone remembers all the operator precedence rules. Commented Aug 6, 2014 at 10:02
  • For readability and maintainability, you better use the enum constants once you have defined them (with correct binary values) instead of their values: thus (c & INIT_SINE) and not (c & (1 << 0)). Commented Aug 6, 2014 at 10:10

3 Answers 3

3

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)
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

0

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

2 Comments

"0b100011" is not part of C++11 but part of C++14 or some compiler extensions.
true. i've changed whole answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.