My question is how to implement the bit map in the following situation?
If a vertex of a graph is in a minimum spanning tree (MST), mark the corresponding bit; later on check whether it is in the MST by checking the bit.
At beginning, I was thinking of using
typedef struct bit_t{
char bit0:1;
} bit;
bit bitmap[num_of_vertex];
And use bitmap array to record the bit;
But then I found the sizeof (bitmap[num_of_vertex]) is num_of_vertex byte, not num_of_vertex/8 byte. so it is not saving space like what I thought;
So far I use
long bit_record = 0;
...
bit_record |= 1<< u;//set vertex as in MST
...
then later on check whether vertex is in MST using:
static bool is_in_MST(int v, int bit_record){
int mask = 1 << v;
if (mask & bit_record)
return true;
else
return false;
}
Though the code works, it will not work if num_of_vertex is larger than 32.
How in general a bitmap in the above situation is implemented?
The situation is that you just can't have 1-bit types in C. The smallest addressable unit is a byte in C, so even if you declare a struct with a one-bit bitfield, it will be padded to a byte (at least). What you can do is create an array of bytes, then access the bits in the array using division and modulus.
unsigned char bitmap[0x100] = { 0 };
void set_nth_bit(unsigned char *bitmap, int idx)
{
bitmap[idx / CHAR_BIT] |= 1 << (idx % CHAR_BIT);
}
void clear_nth_bit(unsigned char *bitmap, int idx)
{
bitmap[idx / CHAR_BIT] &= ~(1 << (idx % CHAR_BIT));
}
int get_nth_bit(unsigned char *bitmap, int idx)
{
return (bitmap[idx / CHAR_BIT] >> (idx % CHAR_BIT)) & 1;
}
about bitmap,here is an example on Programming Pearls, and I added up some notes:
#define BITPERWORD 32 //bits of int,which depends on your computer
#define N 10000000 // number of your elements
#define SHIFT 5 // 32 = 2^5
#define MASK 0x1F // 11111 in binary
int a[N/BITPERWORD + 1]; //space for your bitmap
// i is the the bit you want to use
void set(int i) { a[i>>SHIFT] |= (1<<(i&MASK));}
void clr(int i) { a[i>>SHIFT] &= ~(1<<(i&MASK));}
int test(int i) { return a[i>>SHIFT] & (1<<(i&MASK));}
and don't forget the initialization at the beginning:
for(i=0;i<N;i++)
clr(i);
Related
I'm using some sort of BitStream in my code that has a read_bit()-function. This function is called very very often (more than one billion times in a single stream). This is what the struct BitStream looks like:
typedef struct BitStream {
unsigned char* data;
unsigned int size;
unsigned int currentByte;
unsigned char buffer;
unsigned char bitsInBuffer;
} BitStream;
And the read_bit()-function is defined as follows:
unsigned char bitstream_read_bit(BitStream* stream, unsigned long long bitPos) {
unsigned int byte = bitPos / 8;
unsigned char byteVal = stream->data[byte];
unsigned char mask = 128 >> (bitPos & 7);
if (mask & byteVal) {
return 1;
} else {
return 0;
}
}
Now, I found out through trial-and-error that the line unsigned char mask = 128 >> (bitPos & 7); is very slow. Is there some way that I can speed up the check of a bit? I've already tried to use an array that indexes the 8 different possible masks, but this is not faster (I think due to memory access).
EDIT: I tried a lot of the answers over the past week and performed a lot of benchmarks but there wasn't a lot of performance improvement. I eventually managed to get a 10 seconds improvement by reversing the order of the bits in the bitstream. So instead of using the mask 128 >> (bitPos & 7), I used the function:
unsigned char bitstream_read_bit_2(BitStream* stream, const unsigned long long bitPos) {
unsigned int byte = (unsigned int) (bitPos / 8);
unsigned char byteVal = stream->data[byte];
unsigned char mod = bitPos & 7;
return (byteVal & (1 << mod)) >> mod;
}
I have obviously also changed the corresponding write-function.
The obvious first improvement is to shift the loaded value rather than the mask:
unsigned char bitstream_read_bit(BitStream* stream, unsigned long long bitPos) {
unsigned int byte = bitPos / 8;
unsigned char byteVal = stream->data[byte];
unsigned char maskVal = byteVal >> (bitPos & 7);
return maskVal & 1;
}
This removes the need for a conditional (No if or ! or ?:).
If you can modify the struct, I'd recommend accessing by larger units than bytes:
#include <stddef.h>
#include <limits.h>
#include <stdbool.h>
typedef struct WBitStream
{
size_t *data;
size_t size;
} WBitStream;
bool Wbitstream_read_bit(WBitStream* stream, size_t bitPos)
{
size_t location = bitPos / (sizeof(size_t)*CHAR_BIT);
size_t locval = stream->data[location];
size_t maskval = locval >> (bitPos & (sizeof(size_t)*CHAR_BIT-1));
return maskval & 1;
}
On some processors (notably the common x86), the mask of the shift-amount is a NOP, since the processor's native shift instruction only considers the low bits of the shift amount anyway. At least gcc knows about this.
I have tested to optimzed macro compared to your initial source code:
static unsigned char tMask[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
#define BITSTREAM_READ_BIT1(stream, bitPos) (((128 >> (bitPos & 7)) & stream->data[bitPos >> 3])!=0)
#define BITSTREAM_READ_BIT2(stream, bitPos) (((tMask[(bitPos & 7)]) & stream->data[bitPos >> 3])!=0)
Replacing mask computation by mask in array doesn't increase performance.
The main gap is between function and macro (6 times faster on my computer with 80.000.000 of calls).
And the static inline use is not far from the macro.
Here's how I initially optimized your code:
unsigned char bitstream_read_bit(BitStream* stream, unsigned long long bitPos)
{
return !!(stream->data[(bitPos / 8)] & (128 >> (bitPos % 8)));
}
But the function call overhead itself is likely more instructions than the bit tweaking code inside it. So if you really want to optimize it even further, let's take advantage of inlining and just convert it to a macro:
#define bitstream_read_bit(stream, bitPos) (!!((stream)->data[((bitPos) / 8)] & (128 >> ((bitPos) % 8))))
This is about ANSI-C (C90). This is what I know:
I can directly tell the compiler how many bits I want for a specific variable.
If I want 1 bit which can have the values zero or one.
or 2 bits for the values 0,1,2,3, and so on...;
I'm familiar with the syntax.
I have problem concerning bitfields:
I want to define a SET structure.
It can have maximum 1024 elements (it can have less, but the maximum is 1024 elements).
The domain of the set is from 1 to 1024. So an element could have any value 1-1024.
I'm trying to create a structure for a SET, and it must be efficient as possible for the memory part.
I tried:
typedef struct set
{
unsigned int var: 1;
} SET;
//now define an array of SETS
SET array_of_sets[MAX_SIZE] //didn't define MAX_SIZE, but no more than 1024 elements in each set.
I know this isn't efficient; maybe it's even not good for what I want. That's why I'm looking for help.
As noted in extensive comments, using a bit field is not the way to go. You can use just 128 bytes of storage for your set containing values 1..1024. You will need to map the value N to bit N-1 (so you have bits 0..1023 to work with). You also need to decide on the operations you need for your set. This code supports 'create', 'destroy', 'insert', 'delete' and 'in_set'. It does not support iteration over the elements in the set; that can be added if you want it.
sets.h
#ifndef SETS_H_INCLUDED
#define SETS_H_INCLUDED
typedef struct Set Set;
enum { MAX_ELEMENTS = 1024 };
extern Set *create(void);
extern void destroy(Set *set);
extern void insert(Set *set, int value);
extern void delete(Set *set, int value);
extern int in_set(Set *set, int value);
#endif /* SETS_H_INCLUDED */
sets.c
#include "sets.h"
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned long Bits;
#define BITS_C(n) ((Bits)(n))
enum { ARRAY_SIZE = MAX_ELEMENTS / (sizeof(Bits) * CHAR_BIT) };
struct Set
{
Bits set[ARRAY_SIZE];
};
Set *create(void)
{
Set *set = malloc(sizeof(*set));
if (set != 0)
memset(set, 0, sizeof(*set));
return set;
}
void destroy(Set *set)
{
free(set);
}
void insert(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("I: %d (%d:%d:0x%.2lX)\n", value+1, index, bitnum, mask); */
set->set[index] |= mask;
}
void delete(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("D: %d (%d:%d:0x%.2lX)\n", value+1, index, bitnum, mask); */
set->set[index] &= ~mask;
}
/* C90 does not support <stdbool.h> */
int in_set(Set *set, int value)
{
assert(value >= 1 && value <= MAX_ELEMENTS);
value--; /* 0..1023 */
int index = value / (sizeof(Bits) * CHAR_BIT);
int bitnum = value % (sizeof(Bits) * CHAR_BIT);
Bits mask = BITS_C(1) << bitnum;
/* printf("T: %d (%d:%d:0x%.2lX) = %d\n", value+1, index, bitnum, mask,
(set->set[index] & mask) != 0); */
return (set->set[index] & mask) != 0;
}
#include <stdio.h>
enum { NUMBERS_PER_LINE = 15 };
int main(void)
{
Set *set = create();
if (set != 0)
{
int i;
int n = 0;
for (i = 1; i <= MAX_ELEMENTS; i += 4)
insert(set, i);
for (i = 3; i <= MAX_ELEMENTS; i += 6)
delete(set, i);
for (i = 1; i <= MAX_ELEMENTS; i++)
{
if (in_set(set, i))
{
printf(" %4d", i);
if (++n % NUMBERS_PER_LINE == 0)
{
putchar('\n');
n = 0;
}
}
}
if (n % NUMBERS_PER_LINE != 0)
putchar('\n');
destroy(set);
}
return 0;
}
The functions should really be given a systematic prefix, such as set_. The BITS_C macro is based on the INT64_C macro (and the other related macros) defined in <stdint.h> in C99 and later, which is also not a part of C90.
As per my previous comments, here is an example of how you can pack eight 1-bit elements into one char physical element.
I have only implemented the function to get the value of a 1-bit element, I leave the function to set it to you (it's easy to do).
Note: you can easily change the type of the array element (unsigned char) and experiment with types which can hold more bits (e.g unsigned int) and test if they perform better in terms of speed.
You can also modify the code to make it handle elements bigger than one bit.
#include <stdio.h>
#include <limits.h>
unsigned int get_el(unsigned char* array, unsigned int index)
{
unsigned int bits_per_arr_el = sizeof(unsigned char)*CHAR_BIT;
unsigned int arr_index = index / bits_per_arr_el;
unsigned int bit_offset = index % bits_per_arr_el;
unsigned int bitmask = 1 << bit_offset;
unsigned int retval;
// printf("index=%u\n", index);
// printf("bits_per_arr_el=%u\n", bits_per_arr_el);
// printf("arr_index=%u\n", arr_index);
// printf("bit_offset=%u\n", bit_offset);
retval = array[arr_index] & bitmask ? 1 : 0; // can be simpler if only True/False is needed
return(retval);
}
#define MAX_SIZE 10
unsigned char bitarray[MAX_SIZE];
int main()
{
bitarray[1] = 3; // 00000011
printf("array[7]=%u, array[8]=%u, array[9]=%u, array[10]=%u\n",
get_el(bitarray, 7),
get_el(bitarray, 8),
get_el(bitarray, 9),
get_el(bitarray,10));
return 0;
}
outputs
array[7]=0, array[8]=1, array[9]=1, array[10]=0
typedef struct set
{
unsigned short var:10; // uint var:1 will be padded to 32 bits
} SET; // ushort var:10 (which is max<=1024) padded to 16 bits
As was commented by #Jonathan Leffler use array(unsigned short[])
and define bitmasks
#define bitZer 0x00 //(unsigned)(0 == 0)? true:true;
#define bitOne 0x10 // so from (both inclusive)0-1023 = 1024
... // added for clarification
#define bitTen 0x0A
to look into the bits of each element.
http://www.catb.org/esr/structure-packing/ detailed
To store a value from 0 to 1023 (or from 1 to 1024, which is essentially the same and only involves adding/subtracting 1) you need a minimum of 10 bits.
This means that for 32-bit (unsigned) integers, you can pack 3 values into 30 bits, which gives 2 bits of useless padding.
Example:
%define ELEMENTS 100
uint32_t myArray[ (ELEMENTS + 2) / 3 ];
void setValue(int n, int value) {
uint32_t temp;
uint32_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return;
value--; // Convert "1 to 1024" into "0 to 1023"
temp = myArray[n / 3];
mask = mask << (n % 3)*10;
temp = (temp & ~mask) | (value << (n % 3)*10);
myArray[n / 3] = temp;
}
int getValue(int n) {
uint32_t temp;
uint32_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return 0;
temp = myArray[n / 3];
temp >>= (n % 3)*10;
return (temp & ~mask) + 1;
}
You can do this with bitfields instead, but the code to get/set individual values will end up using branches (e.g. switch( n%3 )) which will be slower in practice.
Removing those 2 bits of padding will cost a little more complexity and a little more overhead. For example:
%define ELEMENTS 100
uint32_t myArray[ (ELEMENTS*10 + 31) / 32 ];
int getValue(int n) {
uint64_t temp;
uint64_t mask = (1 << 10) - 1;
if(n >= ELEMENTS) return 0;
temp = myArray[n*10/32 + 1];
temp = (temp << 32) | myArray[n*10/32];
temp >>= (n*10 % 32);
return (temp & ~mask) + 1;
}
This can't be done with bitfields. This is the most space efficient way to store an array of values that range from 1 to 1024.
If you are storing an "array of booleans" or setting flags, it can be useful. For instance, you can initialize or compare up to 64 values at a time.
These macros will work for unsigned char, short, int, long long ... but simplifies significantly if you just pick a type (so you can use a safer static inline function)
#define getbit(x,n) x[n/(sizeof(*x)*8)] & (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define setbit(x,n) x[n/(sizeof(*x)*8)] |= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define flpbit(x,n) x[n/(sizeof(*x)*8)] ^= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define clrbit(x,n) x[n/(sizeof(*x)*8)] &= ~( (typeof(*x))1 << (n&((sizeof(*x)*8)-1)) )
to initialize a large array of booleans all you need to do is: char cbits[]={0,0xF,0,0xFF};
or for all zeroes char cbits[4]={0};
or an int example: int ibits[]={0xF0F0F0F0,~0};
//1111000011110000111100001111000011111111111111111111111111111111
If you will only be accessing 1 type of array, it may be better to make the macros into proper functions like:
static inline unsigned char getbit(unsigned char *x, unsigned n){
return x[n>>3] & 1 << (n&7);
}
//etc... similar for other types and functions from macros above
You can also compare multiple flags at a time by '|'ing the flags together and using '&'ed masks; however, it does get a bit more complex when you exceed the native types
For your particular instance you can initialize to all zeroes by:
unsigned char flags[128]={0};
or all 1's by:
uint64_t flags[128] = {~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0};
You can even use enums to name your flags
enum{
WHITE, //0
RED, //1
BLUE, //2
GREEN, //3
...
BLACK //1023
}
if (getbit(flags,WHITE) && getbit(flags,RED) && getbit(flags,BLUE))
printf("red, white and blue\n");
1) The proper solution for this question is to use Bit Array
The question provided the solution with Bit Fields with Struct. There are two typical ways to save memory space for bits related problem, another is to use Bit Array. For this specific case in the question, the better way is to use Bit Array (demoed as follows).
If it is the case like purely independent bit flags here, go
for the Bit Array
If there is a group of relevant bits , such as the IP address or Control Word definition, then it's better to combine them with a struct, that is to use Bit Fields with Sturct
2) Sample code just for demo Bit Array
#include<limits.h>
#define BITS_OF_INT (sizeof(int)*CHAR_BIT)
void SetBit(int A[], int k)
{
//Set the bit at the k-th position
A[k/BITS_OF_INT] |= 1 <<(k%BITS_OF_INT);
}
void ClearBit(int A[], int k)
{
//RESET the bit at the k-th position
A[k/BITS_OF_INT] &= ~(1 <<(k%BITS_OF_INT)) ;
}
int TestBit(int A[], int k)
{
// Return TRUE if bit set
return ((A[k/BITS_OF_INT] & (1 <<(k%BITS_OF_INT)))!= 0) ;
}
#define MAX_SIZE 1024
int main()
{
int A[MAX_SIZE/BITS_OF_INT];
int i;
int pos = 100; // position
for (i = 0; i < MAX_SIZE/BITS_OF_INT; i++)
A[i] = 0;
SetBit(A, pos);
if (TestBit(A, pos)){//do something}
ClearBit(A, pos);
}
3) Furthermore, a worthwhile discussing point from this question is,
How to choose a proper solution between "Bit Array" and "Bit fields with struct"?
Here are some references about this topic.
When to use bit-fields in C?
Readable and Maintainable Bitfields in C
I'm stuck understanding bit operations on integers in C.
Suppose I have the number 13. Its binary representation is 1101. How can I set the bit at its second position? How can I clear the bit?
Here is the function I wrote so far for setting the bit:
int setBit(int data, int pos, int val)
{
if (val==1)
data |= (1U << (pos - 1));
else
data ^= (1U << (pos-1));
return data;
}
Will this work correctly?
n = n & (~(1U <<x)) will reset the bit in position x.
Actually what we are doing suppose n=1101
We want to reset 3rd bit.
How does it work?
So 1U <<3=000....1000
~( 1U <<3)=111....0111
n=000..1101
& 111..0111
Result is 000..0101.
For inserting a bit y at position x:(position starts from 0)
1101---->11y01
Giving the example for position 2.
num= FFFF FFFF (in hex)(all 1's) //1111......1111
number=N // in which you will insert bit
num1=num<<x; //for x=2 as in this case
//num1=1111.....1100
num2=~(num1); //num2=0000.....0011
lowbits=N & num2; // =0000.....0001 (N=1101)
highbits= N &num1;// =0000.....1100
highbits<<=1; // =0000....11000
N= highbits | lowbits;//=0000....11001
Now set the x-th bit(here x=2) as you required using the method described below
Note: More generally changing the kth bit of number n to y (maybe 0 or 1) can be done this way
n^=(-y ^ n) & (1U <<k); (&- logical and)
Deletion of a bit is similar to insertion. Step by step perform the operation and you will get it.
EDIT: I have changed the use of 1 to 1U because in first case when using only 1 without any modifiers is defined to be an signed int. From K&R the right shifts of signed values are implementation defined. Also if you left-shift a signed number so that the sign bit is affected, the result is undefined.
These operations on unsigned value have well define behaviour: Vacated fields are filled with zeroes.
Setting, clearing and toggling the state of a bit is straightforward:
inline void bit_set (unsigned long *bf, unsigned char n)
{ *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n)
{ *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n)
{ *bf ^= (1 << n); }
Note: bitfields, and the functions above, are zero based (i.e. the least significant bit is bit 0 not bit 1) So if you want to clear, set or toggle the second bit from the right (bit index 1, the 2's bit (binary), or bit 2 counting right-to-left), you pass a bit index of 1. n in the functions above is the bit index. The following is a quick reference:
+-----+-----+-----+-----+-----+-----+-----+-----+
bit index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+
binary | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
+-----+-----+-----+-----+-----+-----+-----+-----+
Here is a quick example of the use operating on bit 1, (the 2's bit in binary):
#include <stdio.h>
#include <stdlib.h>
#define WDSZ 64
/* bit functions */
inline void bit_set (unsigned long *bf, unsigned char n) { *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n) { *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n) { *bf ^= (1 << n); }
/* simple return of binary string */
char *binstr (unsigned long n);
int main (int argc, char **argv) {
unsigned long bf = (argc > 1) ? strtoul (argv[1], NULL, 10) : 13;
printf ("\n original value : %3lu (%s)\n", bf, binstr (bf));
bit_set (&bf, 1);
printf (" set bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_clear (&bf, 1);
printf (" clear bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_toggle (&bf, 1);
printf (" toggle bit 1 : %3lu (%s)\n\n", bf, binstr (bf));
return 0;
}
/* simple return of binary string */
char *binstr (unsigned long n) {
static char s[WDSZ + 1] = {0};
char *p = s + WDSZ;
while (n) {
p--;
*p = (n & 1) ? '1' : '0';
n >>= 1;
}
return p;
}
Output
$ ./bin/bitsetcleartoggle
original value : 13 (1101)
set bit 1 : 15 (1111)
clear bit 1 : 13 (1101)
toggle bit 1 : 15 (1111)
Here is a simple answer for what I understand your problem to be:
int setBit(int data, int pos, int val) {
if (val)
return data | (1U << (pos - 1));
else
return data & ~(1U << (pos - 1));
}
But I think numbering the bits starting at 1 is not a good idea. The more common usage is to number the bits from 0 to sizeof(type) * CHAR_BIT - 1
whenever I have a problem like this I will break it down into smaller parts...
suppose i have no 13 binary of 13 is 1101
now how can i add extra bit at second position?
ok that is pretty straight forward... first let make a number with a bit in the second position, zero's everywhere else... we will use an int for convenience...
int mask = 2; // or 0x2 if you rather or 0b10 if your compiler supports that ...
well that isn't very special, I can't reuse that machinery as it were... so let try a different way...
int mask = 1 << 1; // 1 in the fist position moved one to the left...
ok now we have part, now there are 2 intuitive ways to set that on our 13...
int answer = 13 | mask; // binary OR
or
int answer = 13 + mask;
these 2 are the same for 13... but will give you different answers for 14... because + always adds the value, and | will only change the bits that aren't set on the left side... so you need to pick the semantics that are correct for you...
now your second question is a little trickier ... first we will pick the same mask...
//pick nth bit
int mask = 1 < n;
// now to toggle that on a number... XOR
int answer = q ^ mask;
I like using the n'th vs position because it makes more sense in the 0 case...
//For Inserting Bit
int insertbit(int data,int pos,int val)
{
int no1,no2;
no1=data;
no1=no1>>(pos-1);
no1=no1<<(pos-1);
no2=data-no1;
no1=no1<<1;
no1=no1 | no2;
if(val==1)
{
no1=setbit(no1,pos,val);
}
return no1;
}
//Setting Bits
int setbit(int data,int pos,int val)
{
int no=1;
no=no<<(pos-1);
if(val==0)
{
no=~no;
data=data&no;
}
else
{
data=no|data;
}
return data;
}
I Coded This Way But I Need Some Shortcut for code insert function
I am trying to create a 48-bit integer value. I understand it may be possible to use a char array or struct, but I want to be able to do bit masking/manipulation and I'm not sure how that can be done.
Currently the program uses a 16-bit uint and I need to change it to 48. It is a bytecode interpreter and I want to expand the memory addressing to 4GB. I could just use 64-bit, but that would waste a lot of space.
Here is a sample of the code:
unsigned int program[] = { 0x1064, 0x11C8, 0x2201, 0x0000 };
void decode( )
{
instrNum = (program[i] & 0xF000) >> 12; //the instruction
reg1 = (program[i] & 0xF00 ) >> 8; //registers
reg2 = (program[i] & 0xF0 ) >> 4;
reg3 = (program[i] & 0xF );
imm = (program[i] & 0xFF ); //pointer to data
}
full program: http://en.wikibooks.org/wiki/Creating_a_Virtual_Machine/Register_VM_in_C
You can use the bit fields which are often used to represent integral types of known, fixed bit-width. A well-known usage of bit-fields is to represent a set of bits, and/or series of bits, known as flags. You can apply bit operations on them.
#include <stdio.h>
#include <stdint.h>
struct uint48 {
uint64_t x:48;
} __attribute__((packed));
Use a structure or uint16_t array with special functions for an array of uint48.
For individual instances, use uint64_t or unsigned long long. uint64_t will work fine for individually int48, but may want to mask off the results operations like * or << to keep upper bits cleared. Just some space saving routines are needed for arrays.
typedef uint64_t uint48;
const uint48 uint48mask = 0xFFFFFFFFFFFFFFFFull;
uint48 uint48_get(const uint48 *a48, size_t index) {
const uint16_t *a16 = (const uint16_t *) a48;
index *= 3;
return a16[index] | (uint32_t) a16[index + 1] << 16
| (uint64_t) a16[index + 2] << 32;
}
void uint48_set(uint48 *a48, size_t index, uint48 value) {
uint16_t *a16 = (uint16_t *) a48;
index *= 3;
a16[index] = (uint16_t) value;
a16[++index] = (uint16_t) (value >> 16);
a16[++index] = (uint16_t) (value >> 32);
}
uint48 *uint48_new(size_t n) {
size_t size = n * 3 * sizeof(uint16_t);
// Insure size allocated is a multiple of `sizeof(uint64_t)`
// Not fully certain this is needed - but doesn't hurt.
if (size % sizeof(uint64_t)) {
size += sizeof(uint64_t) - size % sizeof(uint64_t);
}
return malloc(size);
}
So if I have an integer that is 32 bits. The first 28 bits (from left) are to store the size of a memory chunk, the next two are 0s and the last two are:
to store the if it is the last node and then
to store if it is used or not (respectively).
What I am trying to do is to know how to turn the flag on and off on the isLast operation and the isUsed operation.
(If we consider only the last two integers (again, we start left) then 01 would be not last and is used for example, one more example is 11 is last and is used, 00 is not last and not used.)
I want to be able to turn the flags on and off in an easy way. I know I will need to use bit operations including & and | but I am not sure how.
Please ask me questions if you need more description of the problem.
//turn on isUsed
data |= 1;
//turn off isUsed
data &= ~1;
//turn on notLast
data &= ~2;
//turn off notLast
data |= 2;
This is very simple:
/* Turn on bit 0 */
code = code | 1;
/* Turn off bit 0 */
code = code & ~1;
/* Turn on bit 1 */
code = code | 2;
/* Turn off bit 1 */
code = code & ~2;
See Bitwise operators in C, or Google for the appropriate terms. You can find this in any book or tutorial about C.
In general, counting the least significant bit as 0, to set bit N, you need to OR the original value with 1 << N.
Eg to set bit 1:
val |= (1 << 1);
To clear bit N, you need to AND the original value with the bit-wise inverse of 1 << N.
Eg to clear bit 1:
val &= ~(1 << 1);
This is begging for an interface, either with functions or macros, something like:
// Use unsigned ints (assuming that's your 32-bit type).
#define setLast(x) (x) |= 2
#define clrLast(x) (x) &= ~2
#define isLast(x) ((x) & 2)
#define setUsed(x) (x) |= 1
#define clrused(x) (x) &= ~1
#define isUsed(x) ((x) & 1)
You can also provide macros to extract the size portion and create the whole integer:
#define getSize(x) ((x) >> 4)
#define create (sz,last,used) \
(((sz) & 0x0fffffff) << 4) | \
(((last) & 1) << 1) | \
(((used) & 1))
You'll find your code becomes a lot more readable if you provide the "functions" to do the work and give them sensible names like the above. Otherwise your code is peppered with bit manipulation instructions that are harder to understand.
Just keep in mind the normal rules for macros, things like not passing in things like x++ if your macros use it more than once (which isn't actually the case here). If you want to be ultra-safe, you can do them as functions.
Equivalent functions would be:
unsigned int setLast (unsigned int *x) { *x |= 2; return *x; }
unsigned int clrLast (unsigned int *x) { *x &= ~2; return *x; }
unsigned int isLast (unsigned int x) { return x & 2; }
unsigned int setUsed (unsigned int *x) { *x |= 1; return *x; }
unsigned int clrUsed (unsigned int *x) { *x &= ~1; return *x; }
unsigned int isUsed (unsigned int x) { return x & 1; }
unsigned int getSize (insigned int x) { return x >> 4; }
unsigned int create (unsigned int sz, unsigned int last, unsigned int used) {
unsigned int ret =
((sz & 0x0fffffff) << 4) |
((last & 1) << 1) |
((used & 1));
return ret;
}
Turn the flag on:
register |= (1<<LAST_BIT);
Turn the flag off:
register &= ~(1<<LAST_BIT);
Another way is to use union bit-fields:
union
{
uint32_t value;
struct
{
unit32_t body:28;
unit32_t reserved:2;
unit32_t last_bit:1;
unit32_t used_bit:1;
} fields;
} MyResister;
MyResister.fields.last_bit = 1;
MyResister.fields.used_bit = 0;
I would throw in a BIT(x) macro just to make the source code more clear:
#define BIT(n) (0x1U << (n))
Which would result in:
#define LAST_SET(x) ((x) |= BIT(1))
#define LAST_CLR(x) ((x) &= ~BIT(1))
Also, as previously noted, always put the parameter in parenthesis.
(OT) Edit: Changed name of macro as I do not like having the verb first. First of all a function like getWhatever is for code where you can group the function in a class. In C, IMHO, you should put the "component" name first such as, timeGet() et c
(OT2) Also if it's a register macrofication like this is nice which would result in better portability:
#define MY_REG_RD() (MY_REG)
#define MY_REG_WR(x) (MY_REG = (x))
#define MY_REG_SET(x) (MY_REG |= (x))
#define MY_REG_CLR(x) (MY_REG &= ~(x))
#define MY_REG_DIS BIT(10)
#define MY_REG_EN BIT(4)
Then you could do:
MY_REG_SET(MY_REG_EN);
bool isBitOn( int mask , int i ){ // returns True if i-Th bit is On
return mask & ( 1 << i ) ;
}
int BitOn( int mask , int i ){ // Turn On the i-Th bit of the value and then returns it
return mask | ( 1 << i ) ;
}
int BitOff( int mask , int i ){ // Turn Off the i-Th bit of the value and then returns it
return mask - ( 1 << i ) ;
}
int BitToggle( int mask , int i ){ // Toggle the i-Th bit of the value and then returns it
return mask ^ ( 1 << i ) ;
}
void printbit(int n) { // print the Binary representation of a Integer Number
for(int i = 31 ; i >=0 ; i-- )
printf("%d", isBitOn(n,i) );
printf("\n");
}