# Thread: Combining several variables into one

1. ## Combining several variables into one

For those of you that read the game forum here, you might have seen that I have been interested in how speed up some graphics functions I have.

From reading this article I learned that it is possible to take two 16bit variables and store them in a 32 bit variable. But I am not really sure how to do this, so here are some questions:

When you assign the two variables to the bit one, is it done like this:
The first 16bit variable is stored in the front, and the second in the back? So the two variables are not added together, they are just stored in the same place.

100 and 100 would not be 200, but 100100?

Code:
```¦             size of 32bit                ¦
/                              \
/                                  \
¦ size of 16bit ¦   ¦ size of 16bit ¦```
I have made a small test program where I try to place two chars in one int, but I cant get it to work. Could anyone give me a helping hand or point me to a place where I can read up on this?

Code:
```#include "stdafx.h"
#include <iostream>

using namespace std;

int main ()
{

char a = 0;
char b = 25;
char c = 50;
char d = 75;

int test = b | (c << 4);

test = test * 2;

cout <<" size of char = " << sizeof(char) << endl;
cout <<" size of int  = " << sizeof(int) << endl;

cout << " a = " << (int)a << endl;
cout << " b = " << (int)b << endl;
cout << " c = " << (int)c << endl;
cout << " d = " << (int)d << endl;

cout << endl;

cout << "b = " << (test >> 8) << endl;
cout << "c = " << (test >> 4) << endl;

system("Pause");
return 0;
}```
Thank you

2. This is what the bitshift operators are for.

Check out the macros MAKELONG(16bit, 16bit), LOWORD(32bit), and HIWORD(32bit).

4. Yes, it would (in concept) be 100100.

Taking that example, you could multiply the first 100 by 1000, and then add them for saving. In practice, since you are using 16 bit values, you would add 2^16 to the first value and then add (or OR) the two together.

To break the values up later on, you could use the modulo operator, or shift, or AND.

Todd

5. It may be better to just use the short type, and let the compiler optimize it for you, If you use binary operators, then you cannot take advantage of the machine commands designed for accessing high and low register parts.

Using a struct of two shorts (with a good compiler) may make it easier for the compiler notice the opportunity for optimization.

Using compiler macros, if they exist, is the best solution for this, as those will be optimized as best as possible for the compiler; they are likely stand-ins for the machine commands.

6. Originally Posted by h3ro
Code:
`	int test = b | (c << 4);`
You are only shifting left by 4, yet a char is (usually) 8 bits. So you are overlapping the two values, losing their identities.

7. This is what the bitshift operators are for.

Check out the macros MAKELONG(16bit, 16bit), LOWORD(32bit), and HIWORD(32bit).
Do I need to include anything to get them to work? I just got errors. Im using visual studio 2008

What I want is calculating two screen pixels at the same time. Im not sure that I can do that with a struct?

Yes, it would (in concept) be 100100.
When I do: int test = a | ( b <<8 );
I get this:
Code:
```   b       a
1011010   10001

test
101101000010001```
Where does the extra zeros between the numbers come from?

When do sizeof() of a int and on a char I get 4 and 1. Does that mean that I can add four chars in an int?
I tried doing it like this: a | ( b <<8 ) | (c<<16);
But that did not work.

Also, how do I get the value of a after I added them? I can get b, but not sure about a.

Here is my code now:
Code:
```int main ()
{
char a = 17;
char b = 90;

int test = a | ( b <<8 );

test *=2;

cout <<" size of char = " << sizeof(char) << endl;  // 1
cout <<" size of int  = " << sizeof(int) << endl;   // 4

cout << endl;

cout << " a    = " << (int)a << endl;
cout << " b    = " << (int)b << endl;
cout << " test = " << (int)test << endl;

cout << " newA = " << (int)(test>>8) << endl;
cout << " newB = " << (int)(test>>16) << endl;

cout << endl;

cout << " a | b = " << (a | b) << endl;
cout << " a ^ b = " << (a ^ b) << endl;
cout << " a & b = " << (a & b) << endl;
cout << " a ^ a = " << (a ^ a) << endl;	 // Always zero

system("Pause");
return 0;
}```
Thanks a lot for the help so far

8. [quote="h3ro"]
When do sizeof() of a int and on a char I get 4 and 1. Does that mean that I can add four chars in an int?
I tried doing it like this: a | ( b <<8 ) | (c<<16);
But that did not work
[/code]
It should do. Although it's probably more reliable if you have unsigned chars that you work on.

--
Mats

9. Where does the extra zeros between the numbers come from
They are not between, they are inside - each char has 8 binary digits, you just skipped the leading zeroes.
a is not 10001, it is 00010001

10. i had to make a gradient function a while ago. probably not the fastest, but it definitely does the kind of thing you want to do here.

color data is stored as 0x00BBGGRR

Code:
```int * __fastcall gradient(int *colors,const int size,int c0,int cf)
{
byte r0 = (byte)c0;
byte g0 = (byte)(c0>>8);
byte b0 = (byte)(c0>>16);
byte rf = (byte)cf;
byte gf = (byte)(cf>>8);
byte bf = (byte)(cf>>16);
for(int i=0;i<size;i++)
{
int R = ((size-i)*r0+i*rf)/size;
int G = ((size-i)*g0+i*gf)/size;
int B = ((size-i)*b0+i*bf)/size;
G*=0x00000100;
B*=0x00010000;
colors[i] = R+G+B;
}
}```

11. Thank you for the code m37h0d. But I am not 100% sure what is going on there. Do you know of any code that does roughly the same but has more comments or a good article?

Code:
```	unsigned char a = 17;
unsigned char b = 90;
unsigned char c = 50;

unsigned int test = a | (b <<8) | (c <<16);```
How do I print out the value of a,b and c by using test?

12. Originally Posted by h3ro
Thank you for the code m37h0d. But I am not 100&#37; sure what is going on there. Do you know of any code that does roughly the same but has more comments or a good article?

Code:
```	unsigned char a = 17;
unsigned char b = 90;
unsigned char c = 50;

unsigned int test = a | (b <<8) | (c <<16);```
How do I print out the value of a,b and c by using test?
Code:
```printf("a = %d\n", test & 0xff);
printf("b = %d\n", (test >> 8) & 0xff);
printf("c = %d\n", (test >> 16) & 0xff);```
EDIT: Once again I forgot which board I'm on. Same basic idea, but matsp's is actually in C++

13. Code:
```cout << "a = " << (test & 0xff) << endl;
cout << "b = " << ((test >> 8) & 0xff) << endl;
cout << "c = " << ((test >> 16) & 0xff) << endl;```
--
Mats

14. Originally Posted by h3ro
Thank you for the code m37h0d. But I am not 100% sure what is going on there. Do you know of any code that does roughly the same but has more comments or a good article?

Code:
```	unsigned char a = 17;
unsigned char b = 90;
unsigned char c = 50;

unsigned int test = a | (b <<8) | (c <<16);```
How do I print out the value of a,b and c by using test?
sorry i don't. my basic understanding is this:

an int is 32 bits, or 4 bytes.

a byte, or char, is 8 bits.

casting an int to char or byte will simply truncate the int's data to the least significant 8 bits.

bit shifting does essentially what the name implies, it reorders the bits in the operand.

as someone will undoubtedly point out, i'm probably off in some of the details, but this is how i understand the process currently.

15. Thank you. I did not know that I had to AND it with 255.

Is there a difference between using hex and decimals, or is it just that that is how its down when working with bits?

Now I have 4 chars in a int. But I tried putting 8 chars in a __int64, and it did not work out to good.

Code:
```       unsigned __int64 test = a | (b <<8) | (c<<16) | (d<<24) | (e<<32) | (f<<40) | (g<<48) | (h <<56);

cout << " newA = " << (test & 0xff) << endl;
cout << " newB = " << ((test >> 8) & 0xff) << endl;
cout << " newC = " << ((test >> 16) & 0xff) << endl;
cout << " newD = " << ((test >> 24) & 0xff) << endl;
cout << " newE = " << ((test >> 32) & 0xff) << endl;
cout << " newF = " << ((test >> 40) & 0xff) << endl;
cout << " newG = " << ((test >> 48) & 0xff) << endl;
cout << " newH = " << ((test >> 56) & 0xff) << endl;```
I have read that c++ does not have a standard 64bit value, so is this simply impossible?