Solved

# How to assign a value to 'bit 0' of a 32 bit integer

Posted on 2006-05-15
Medium Priority
316 Views
Greetings:

I need to know how to assign a value to any bit of a 32 bit integer.  I also need to know how to access any bit for the sake of obtaining its value.  For starters, how would I access bit '0' ?

Thanks

0
Question by:John500
• 12
• 8
• 5
• +1

LVL 45

Expert Comment

ID: 16682458
Hi Jorgen,

GET_VALUE(var,bit_number) (((var)>>(bit_number))&(0x01))

Idea is to move the bit to LSB and AND it with 0x01 to get its current value ...

Likewise to set a bit
SET_VALUE(var,bit_number) ((var)|(0x01<<(bit_number)))

Bits are assumed to be numbered 0 to 31

Cheers!
Sunnycoder
0

LVL 53

Expert Comment

ID: 16682557
>> SET_VALUE(var,bit_number) ((var)|(0x01<<(bit_number)))
Just to expand on this : tu unset a bit (ie. set it to 0), you can do this :

UNSET_VALUE(var,bit_number) ((var)&(~(0x01<<(bit_number))))

This will only work correctly with integers though. And you have to make sure to not feed the macro wrong values, or you can be debugging forever :)
0

Author Comment

ID: 16682846
Thanks for the help.  What header file do I need to support these functions ?  For whatever it's worth, I'm using the VS C++ .Net environment.

Also, let me state exactly how I'm using the integer(s) in question.  I've boosted up the points to accomodate.

I have a struct that looks something like this:

typedef enum tagSignals
{
SIG_NUMBER_0
SIG_NUMBER_1
SIG_NUMBER_2
SIG_NUMBER_3
}Signals

So then, I will need to set bit '0' for any of the signals above to either '0' or '1'.

Thanks

0

LVL 45

Expert Comment

ID: 16682881
You do not need any header file for these macros .. they only use standard bitwise operators ....

0

LVL 53

Expert Comment

ID: 16683004
Don't forget to put #define in front of them :)
0

LVL 5

Expert Comment

ID: 16683430
A more crude way is to make use of a Union. I will show you , how to do for a byte.

typedef struct {

unsigned bit_0:1;
unsigned bit_1:1;
unsigned bit_2:1;
unsigned bit_3:1;
unsigned bit_4:1;
unsigned bit_5:1;
unsigned bit_6:1;
unsigned bit_7:1;

}bits;

typedef union {

struct bits byte;
unsigned char c_byte;

}BYTE;

As you see in the above declaration , we have a union, containing 2 elements , one is a structure and the other is a unsigned char, they will share a single BYTE location in memory.

So here you can access the data using 'c_byte' variable as a character variable, or you can access invidual bits.

This works well, but i don't know how comfortable you would be to make a 32 bit structure with 32 elements :-)

Choice is yours :-)

Regards,
Siddhesh
0

LVL 45

Expert Comment

ID: 16683465
Yet bigger problem with such unions is that you need to be absolutely sure that all your flags are going to be mutually exclusive - "always" - i.e. now and in the evolution/maintenance phase ... In practice this is not very common ... Often a combination of flags is used to reflect state.

nice to see you around sid ... do drop by more often
0

LVL 53

Expert Comment

ID: 16683480
Using a bit struct is not guaranteed to give the same result on different platforms, so it's not really advised to use it to do bitwise operations on an existing, fixed datatype !!

The most important problem you'll have is byte order (little endian vs. big endian), as well as compiler optimizations, system limitations, CPU word sizes, etc.

So, not advised at all !!! better stick to the good old bitwise operations as demonstrated by sunnycoder !!
0

Author Comment

ID: 16683536
Ok .... but instead of putting macros in a header file can I do something like this:

void MySignalSettingFunction(int SignalNumber, int BitValue, int BitNumber)
{

if(BitValue == 0)
((SignalNumber)|(0x01<<(BitNumber)))   // set to zero

else
((SignalNumber)|(0x01<<(BitNumber)))   //  set to one

return;
}

In the function above I'm only concerned with bit zero.  Is ' 0x01 ' equal to bit zero  ?
0

LVL 45

Expert Comment

ID: 16683564
void MySignalSettingFunction(int SignalNumber, int BitValue, int BitNumber)
{

if(BitValue == 0)
SignalNumber=SignalNumber & (~(0x01))   // set to zero

else
SignalNumber=SignalNumber|0x01   //  set to one

return;
}

0

LVL 45

Expert Comment

ID: 16683571
>Is ' 0x01 ' equal to bit zero  ?
0x01 is hexadecimal for 1 ... It is same as bit sequence 0000 0001
0

LVL 53

Expert Comment

ID: 16683600
Something like this you mean : ?

void MySignalSettingFunction(int *SignalNumber, int BitValue, int BitNumber) {
if(BitValue == 0)
*SignalNumber = ((*SignalNumber)&(~(0x01<<(BitNumber))))   // set to zero
else
*SignalNumber = ((*SignalNumber)|(0x01<<(BitNumber)))   // set to one
return;
}

called like this eg. :

Signals signal = ...;
MySignalSettingFunction(&signal, 1, 5);
0

LVL 53

Expert Comment

ID: 16683623
btw, note that i forgot the ;'s at the end of those statements !! Should be :

void MySignalSettingFunction(int *SignalNumber, int BitValue, int BitNumber) {
if(BitValue == 0)
*SignalNumber = ((*SignalNumber)&(~(0x01<<(BitNumber))));   // set to zero
else
*SignalNumber = ((*SignalNumber)|(0x01<<(BitNumber)));   // set to one
return;
}
0

Author Comment

ID: 16683851
Sorry if this has become more confusing than is necessary.  I boosted the points again.  I'm not too strong in this area (obviously).

The above code looks close to the answer but I still don't understand a couple of things.  To make this more simple, let's just say I want to set the following signal:

SIG_NUMBER_0    // member of Signals structure

... and I want to set bit zero to either 0 or 1.     Therefore, it would look something like this:

SIG_NUMBER_0 =   ???????           // bit zero set to zero

SIG_NUMBER_0 =   ???????           // bit zero set to one

0

LVL 45

Expert Comment

ID: 16683933
assuming SIGNUMBER_0 is an int initialized to 0 (32 bits) .. it would look like this
0000 0000 0000 0000 0000 0000 0000 0000

Rightmost is LSB (least significant bit) and left most is MSB (most significant bit)

To set bit n, what you need to do is OR (|) that bit with 1.
How do you get 1 on that bit ... take 1 and left shift it by those many positions!!!

0000 0001, left shifted by 2 gives you

0000 0100

Now if you OR this with SIGNUMBER_0, you get 2nd bit (3rd from LSB since we are counting from 0) set

0000 0000 0000 0000 0000 0000 0000 0000
0000 0100
--------------------------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0100

Hence to set nth bit

SIGNUMBER_0 = SIGNUMBER_0 | (0x01 << bit_number)

Now to reset this bit, you need to AND it with 0. Note that ORing with 0 had no effect in previous case however ANDing with 0 would set all bits to 0 ... Hence we need to AND only this bit with 0, all remaining bits must be ANDed with 1 .. How do you get such a number ...
Invert all bits of 0x01<<bit_number
~ (0x01<<2) would give you
1111 1011 .... AND this with SIGNUMBER_0 and you would successfully reset 2nd bit

0000 0000 0000 0000 0000 0000 0000 0000
1111 1011
--------------------------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0000

Hence to reset nth bit

SIGNUMBER_0 = SIGNUMBER_0 & (~ (0x01 << bit_number))

I hope that clears up the things.
0

Author Comment

ID: 16684338
sunnycoder,

That does clear up a lot, thanks!  Here's where I'm at now - when I compile I get the following error for these lines:

SIG_NUMBER_0  = SIG_NUMBER_0 | (0x01 << bit_number);
SIG_NUMBER_0  = SIG_NUMBER_0 & (~ (0x01 << bit_number));

error C2440:  '='  cannot convert from 'int' to tagSignals

As you know, in the Signals structure I have SIG_NUMBER_0 and this is of 'type' - enumeration

The person who receives this signal has stipulated that I need to set bit zero to either 0 or 1 depending on the preceding logic of the program.  I say this because it is assumed that I should be able to address the requirement.

Why is the compiler saying this member (SIG_NUMBER_0) is a struct (tagSignals) ?  It's only a member of the structure and it is an integer by default since it is used as an enumerator - right ?

0

LVL 45

Expert Comment

ID: 16684366
SIG_NUMBER_0 is a variable of type enumeration ? Or is it a value in enumeration ?
If latter then this code will not work .. you can work on variables of type enumeration .. and yes enumerations are treated as ints.

Post the declarations if you are still stuck
0

LVL 5

Expert Comment

ID: 16684418
I do agree that structure and bit members method is platform dependent, that's why in my first sentence , I mentioned that this is a 'crude' way.

But it works if you are getting too messed up. So essentially you have a choice whether you should implement this or not. If you are sure that your code is not going to be re-used you can go ahead and implement it.

Regards,
Siddhesh
0

Author Comment

ID: 16684776
To add more information here, I'm working with network packets.  The schema used has been in place for a long time.... I'm the one who's ramping up so nothing will change in terms of architecture.   Here are all the structures which I feel apply to my issue:

typedef enum tagDATA_TYPE
{
SIZ_NOT_USED = 0,       // Don't use this data type!
SIZ_INT32,              // Signed 32-bit integer
SIZ_LONGLONG,           // Signed 64-bit integer
SIZ_FLOAT32,            // IEEE 32-bit floating point (float)
SIZ_FLOAT64,            // IEEE 64-bit floating point (double)
SIZ_STRING96,           // Null-terminated string in 96 byte fixed-size field
SIZ_CODE,               // 32-bits, unknown internal structure
SIZ_BLOCK,              // Block data follows. The first 4 bytes holds the size (in bytes)  7
// Including the first 4 bytes. The size MUST be an integral of 4
SIZ_UN_INT32,           // 32 bit unsigned integer
SIZ_UN_LONGLONG,        // 64 bit unsigned integer
SIZ_TYPE_END            // Renamed Size Type Enumeration Terminator

} DATA_TYPE;

// used for signaling
typedef enum tagSignals
{
SIG_NUMBER_0 = SIG_SPARE, //equal to 500,
SIG_NUMBER_1,
SIG_NUMBER_2,
SIG_NUMBER_3,
...
...
}Signals

// buffer holding packet information
static struct _DATA_ELEMENT
PacketObject[] = {

{SIZ_INT32,Header_source,"\0",0},      // Signed 32-bit integer, #define   -2
{SIZ_INT32,Acknowledge,"\0",0},      // Signed 32-bit integer, #define   -3
{SIZ_INT32,Operation,"\0",0},            // Signed 32-bit integer, #define   -4
{SIZ_INT32,Object,"\0",0},            // Signed 32-bit integer, #define   -5
{SIZ_INT32,SIG_NUMBER_0,"\0",0},      // Signed 32-bit integer, enum SIG_SPARE_7 equal to 500
{-1,-1,"",-1}};

Notice the signal 'SIG_NUMBER_0' in the 5th row of the PacketObject[] array.  This is the item I need to manipulate.   Does the compiler recognize the data type 'SIZ_INT32' ?  I don't know why a 'DATA_TYPE' structure would even need to be created unless it was to somehow aid remote systems in terms of little endian and big endian .......

0

LVL 45

Expert Comment

ID: 16687524
>Notice the signal 'SIG_NUMBER_0' in the 5th row of the PacketObject[] array.  This is the item I need to manipulate.
This seelms to be the value of the variable and not the name ... You cannot acess a variable by its value!!!!

What is the definition for struct _DATA_ELEMENT? In that definition there would be some name assigned for second element ... you can access this as

PacketObject[4].name_of_second_element_as_defined_in_struct_DATA_ELEMENT
0

Author Comment

ID: 16690927
sunnycoder,

I've boosted up the points here again ........

Here is the _DATA_ELEMENT struct:

struct _DATA_ELEMENT {
int      sizeType;
int      signalType;
char      data [100];
int       dataLength;
};

The code below shows how ' SIG_NUMBER_0 ' is stuffed into the _DATA_ELEMENT variable array.  From the looks of it, this would also be where the bit is set - right ?  Let me know if this is where I should be setting the bit.  Remember that I have to set _ONLY_ bit zero to either '0' or '1' :

int SendBuffer;

PacketObject[4].sizeType = SIZ_INT32;
PacketObject[4].signalType = SIG_NUMBER_0;
SendBuffer = BitStatus;                                      //  either 1 or 0
memset (PacketObject[4].data,0x00,100);
memcpy (PacketObject[4].data,&SendBuffer,4);   //  is this where the bit is actually set ?
PacketObject[4].dataLength = 4;

At any rate, if you don't mind - please explain what each line above accomplishes.  Once each array slot is stuffed another function is called to make the packet using this _DATA_ELEMENT.

0

LVL 45

Expert Comment

ID: 16691161
>int     signalType;
>PacketObject[4].signalType = SIG_NUMBER_0;
The value is stuffed in signalType element .. you need to manipulate thae value by using this variable name.

>SendBuffer = BitStatus;                                      //  either 1 or 0
Clear enough

>memset (PacketObject[4].data,0x00,100);
Clears the data element of the struct ... all elements in the data array would now be 0

>memcpy (PacketObject[4].data,&SendBuffer,4);   //  is this where the bit is actually set ?
No ... The bit (actually 4 bytes) are being copied to data element of the struct while your flags are held in signalType

PacketObject[4].signalType = PacketObject[4].signalType | (0x01 << bit_number)
PacketObject[4].signalType = PacketObject[4].signalType & (~ (0x01 << bit_number))

Since you only wish to set/rest bit 0, these simplfy to
PacketObject[4].signalType = PacketObject[4].signalType | 0x01
PacketObject[4].signalType = PacketObject[4].signalType & (~ (0x01))
0

Author Comment

ID: 16692549
Ok... making progress.   I know that the six lines below demonstrate the standard process for packet assignment of the fifth element (signalType).  What I don't understand is whether I'm now adding one additional line to set the value.  In other words - I need to send the actual signal name 'SIG_NUMBER_0' because the receiving system uses a CASE statement to look for that particular signal.  Once the signal is identified, the bit setting is obtained.

// typical construction
PacketObject[4].sizeType = SIZ_INT32;
PacketObject[4].signalType = SIG_NUMBER_0;
SendBuffer = BitStatus;
memset (PacketObject[4].data,0x00,100);
memcpy (PacketObject[4].data,&SendBuffer,4);
PacketObject[4].dataLength = 4;

// modified construction to set the bit
PacketObject[4].sizeType = SIZ_INT32;
PacketObject[4].signalType = SIG_NUMBER_0;
PacketObject[4].signalType = PacketObject[4].signalType | 0x01   // set the bit
SendBuffer = BitStatus;
memset (PacketObject[4].data,0x00,100);
memcpy (PacketObject[4].data,&SendBuffer,4);
PacketObject[4].dataLength = 4;

You wrote:
>memset (PacketObject[4].data,0x00,100);
Clears the data element of the struct ... all elements in the data array would now be 0

Does this mean I should not use this line to clear all elements since I just set the bit for signalType ?  Or should I call it first and then set the bit ?  Or what ?

0

LVL 45

Accepted Solution

sunnycoder earned 2000 total points
ID: 16692790
>the receiving system uses a CASE statement to look for that particular signal.
In that case you should not add the information to signalType field ... Current code would work fine ... It copies your flags to data array .... receiver should read the contents of data array to determine the flags.

>Does this mean I should not use this line to clear all elements since I just set the bit for signalType ?
Clearing out is essential .. clearing out is essentially initialization ... otherwise array may contain junk values.

> Or should I call it first and then set the bit ?  Or what ?
Clean it first and then dump the flags as the current code is doing.
0

Author Comment

ID: 16693184
sunnycoder - thanks man .........
0

LVL 45

Expert Comment

ID: 16693288
0

LVL 5

Expert Comment

ID: 16709789
sunny,

looks like you are full time on EE :-)

GREAT GOING...how are you doing.. long time no see

Regards,
Siddhesh
0

LVL 45

Expert Comment

ID: 16711117
Yep sid :) .. back for a looong break ...
Life's been good here ... how about you ..

Cheers!
0

LVL 5

Expert Comment

ID: 16718954
me doing fine.. back in BLR.. working in the same company... but no coding for me :-)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address.Â This address might be address of another variable/address of devices/address of fuâ€¦
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and infâ€¦
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
###### Suggested Courses
Course of the Month15 days, 12 hours left to enroll