Skip to main content
GameDev.net gamedev.net
🔒 Locked

Getting 2 values in one byte

Started by V3rt3x Jun 20, 2002 at 2:40 AM 15 replies 650+ views
Original Post
V3rt3x
V3rt3x
Hi all!! I have a byte to store 2 values (so, 4 bits per var). for exemple: int byte = 10010110; // (150) the first value would be 1001 => 9 the second 0110 => 6 for the first I can get it with opérator >> right? int var1 = (byte >> 4); // 00001001 => 9 but for the second, the best I have found is: int var2 = (byte & 1)+(byte & 2)+(byte & 4)+(byte & 8); My question : Is there a better way to extract the 4 last bits of the byte? I tried with << and then >> but there is no change
Crispy
Crispy
try: byte & 16 for 4 bits (255 for 8 bits etc.)

edit: nothing special...

Crispy


[edited by - crispy on June 20, 2002 4:15:56 AM]
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
Assassin
Assassin
var = byte & 0x00ff;
var2 = byte >> 4;

[edited by - Assassin on June 20, 2002 4:12:42 AM]
Assassin, aka RedBeard. andyc.org
Crispy
Crispy
quote:
Original post by davidsporn
I think you mean : byte & 15
(15 = 00001111 so only the 4 low-order bit are kept)



Gotta get some more sleep... zzzzzz.... 8|

Crispy

"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
gimp
gimp

  
#pragma pack( push, Packing )
#pragma pack( 1 )

struct Nibbles
{
char x : 4;
char y : 4;
};

#pragma pack(pop, Packing)



The packing is to ignore the compiler set alignment. The numbers after the colon is the number of bits assigned to the variable. The type(char) what is being divided up.

If you use an int it''ll leave 3 bytes empty(I guess you could cast it away)

I''d betting this is to be transported across a network link? If so to get your data back out of a char later just cast the char from your datastream back to a (Nibble&) (Thats how I did it, probably not the best way but it worked.

This is probably a lot more readable than bit shifting, besides I''m crap as bit shifting the right bits

HTH




Chris Brodie
http:\\fourth.flipcode.com
Chris Brodie
KalvinB
KalvinB
If you have two variables (x,y) that can have a value 0-15 getting them into a byte (byte z) is easy;

z=x*16+y;

x=z/16;
y=z%16;

Or you could do bitshifting but I think that''s a bit overkill.

Ben


IcarusIndie.com [ The Rabbit Hole | The Labyrinth | DevZone | Gang Wars | The Wall | Hosting ]
Useless Hacker
Useless Hacker
quote:
Original post by KalvinB
If you have two variables (x,y) that can have a value 0-15 getting them into a byte (byte z) is easy;

z=x*16+y;

x=z/16;
y=z%16;

Or you could do bitshifting but I think that's a bit overkill.
Except that bit shifting is faster that multiplying/dividing.

z = (x << 4) | y;

x = z >> 4;
y = z & 0x0F;




[edited by - Useless Hacker on June 20, 2002 6:42:56 AM]
Dean Harding
Dean Harding
quote:
Original post by Useless Hacker
Except that bit shifting is faster that multiplying/dividing.



The compiler will probably optimize it anyway and turn it into bit shifts. In this case, it''s really just preference, but for things like this, I prefer bit shifts/masks (cause I find them to be more "natural" than multiplying/dividing)


codeka.com - Just click it.
Trugath
Trugath
Bitshifting is blindingly fast and is probably the best solution.

just setup a couple of macros for accessing the hi/lo (nibble? someone called it?) in the byte. same way you would access hi-lo words in a dword.
gimp
gimp
The pragma I used stores the current struct packing alignment in ''Packing'' allowing me to reset it to whatever it was befor with the pop. You don''t really need it as the alignment wil reset at he end of the file anyway.

The pragma I used was VC specific. Here is my whole code segment:


  
#ifdef WIN32
#pragma pack( push, Packing )
#pragma pack( 1 )
#endif

#if defined(__GNUC__)
#define PACK_STRUCT __attribute__((packed))
#endif


struct TGA_IMAGE_DESCRIPTOR
{
unsigned char AlphaChannelBits : 4;
unsigned char LeftToRightOrder : 1;
unsigned char TopToBottomOrder : 1;
unsigned char Unused : 2;
};


struct TGA_HEADER
{
unsigned char IdLength;
unsigned char ColourMapType;
unsigned char ImageType;
unsigned short ColourMapIndex;
unsigned short ColourMapLength;
unsigned char ColourEntrySize;
unsigned short XOrigin;
unsigned short YOrigin;
unsigned short Width;
unsigned short Height;
unsigned char PixelDepth;
TGA_IMAGE_DESCRIPTOR ImageDescriptor;
unsigned char Data[1];
} ;


#ifdef WIN32
#pragma pack(pop, Packing)
#endif


The GNU stuff was just copied from somewhere so I can look in to it later when porting.

I never use bitshifting. I''ve always tending to think of it as a throw back to C which I only learnt for about a week. Not to say it''s bad, probably much faster than the way I do things.

However, I like the struct metho as it''s very readable, esp when your packing 4-6 values in a byte. Each shift is then named and easy to identify. Though I''m writing a game, readability it more important to me than speed. CPU''s are fast and compilers smarter than me.

I''ll handle the high level stuff... For me ''optimisation'' is not doing stupid things like transforming more than needed or using NV_vertex array range, etc.

HTH



Chris Brodie
http:\\fourth.flipcode.com
Chris Brodie
V3rt3x
V3rt3x
Thanx for these answers guys, I could solve my pb (using x = z >> 4; y = z & 0x0F; )


quote:
Original post by Ziphnor
If you want to store 2 values in an 8-bit variable(1 byte) why are you using an int which on most machines will be 32-bit/4-bytes in memory(even though you dont use all of it)?

If you want the equivalent of a byte use a char.....


It was for decoding a 4-bit encoded bitmap

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.