markus_p
markus_p

Reputation: 574

BitShifting, Storing 3 u_int8_t in one integer and read out again

i have a question for you guys which is driving me nuts for 2 days already. Maybe its because i am missing the basics on bit shifting but somehow i don't get it into my head. What i want is a simple program which reads in 3 char or uint8_t's, stores them into one big int and then reads it out later again.

It is the first time that i experiment with bit shifting, and somehow i am stuck.

This is the code:

int main (int argc, const char * argv[])
{
    u_int8_t insert1;
    u_int8_t insert2;
    u_int8_t insert3;
    int data;

    printf("Please enter value1: ");
    scanf("%d", &insert1);
    printf("Please enter value2: ");
    scanf("%d", &insert2);
    printf("Please enter value3: ");
    scanf("%d", &insert3);

    data |= insert3<<16 | insert2<<8 | insert1;

    printf("\nValue1: %d\n", data);
    printf("Value2: %d\n", data>>8);
    printf("Value3: %d\n", data>>16);
    return 0;
}

When i Enter

126 103 255

i get:

Value1: 16711680 Value2: 65280 Value3: 255

Which is completely wrong. I am pretty sure that the value is stored correctly stored into data but i don't know how to read out.

Thanks very much :-)

Upvotes: 1

Views: 997

Answers (3)

Vitali Pom
Vitali Pom

Reputation: 602

I almost sure it should be >>> instead of >>. I also had similar problem. Edit: This is correct for Java when you're working with negative numbers, however you won't be able to store easily negative numbers and get them later, since you will have to know when you have a negative or a positive number inside the integer and add if's accordingly.

Upvotes: 0

Sylvain Defresne
Sylvain Defresne

Reputation: 44503

You have three errors:

  1. you're passing a pointer to a uint8_t to scanf, but you're using the %d conversion which expect a pointer to an int; you need to use %hhd to tell scanf that you are using a storage the size of a char, otherwise you risk to corrupt your stack; or you can change your variables to be of int type, or better (since the question is tagged C++) use the std::istream extraction operator (operator >>) that is type-safe

  2. you didn't initialize data, and used the |=, thus mixing uninitialized value with your user entered values (which will produce garbage)

  3. when using printf, you need to mask the high-order bit if you only want to see the low order bits

So, your code need to read:

#include <iostream>

static void readvalue(const char* name, uint8_t& outValue) {
    std::cout << "Please enter " << name << ": " << std::flush;
    std::cin >> outValue;
    std::cout << "\n";
}

int main() {
    uint8_t value1, value2, value3;
    readvalue("value1", value1);
    readvalue("value2", value2);
    readvalue("value3", value3);

    data = insert3<<16 | insert2<<8 | insert1;

    std::cout << "Value1: " << (data & 0xff);
    std::cout << "Value2: " << ((data >> 8) & 0xff);
    std::cout << "Value3: " << ((data >> 16) & 0xff);
}

Upvotes: 6

Mysticial
Mysticial

Reputation: 471299

You never initialized data and you're doing this:

data |= 

Either initialize it to zero or change the line to this:

data = insert3<<16 | insert2<<8 | insert1;

Upvotes: 6

Related Questions