Hello ladies and gents,

I'm starting on the next exercise, but I'm puzzled a bit and was wondering if any of you might help me with this.

I have to enter four integer numbers, non negative and smaller then 16 into ONE variable int x, now, the thing I was wondering is, do I have to use an array for this int x, so that I get int x[3] put the four numbers smaller then 16 into the array or is it possible to solve this solely by using a certain bit operator?

The idea is, when those four numbers are entered, I then have to select a number from 0 to 3 and depending on the selection it has to give me the previous entered number smaller then 16!

Hope you understood what I'm trying to accomplish.

Recommended Answers

All 33 Replies

Play around with this and see what you can come up with:

#include <iostream>

using namespace std;

#define bit(x) (1UL << (x))

int main()
{
  unsigned int x = 0;

  x = 1; // 00000001
  cout<< x <<endl;
  x |= bit(1) | 1; // 00000011
  cout<< x <<endl;
  x |= bit(2) | 1; // 00000111
  cout<< x <<endl;

  // Get back a sliver
  cout<< (x >> 1) <<endl; // 00000011
  cout<< (x >> 2 << 2) <<endl; 00000100
}

I will ;)

Thanks Narue!

Hi Narue,

Ive been playing around with the code you gave me and alltough I'm pretty sure I understand what is happening, I can't really figure out how this is going to help me in getting four different numbers smaller then 16 into one variable x :o

I understand that when having four bits 1111, I get a decimal maximum of 15.

I understand that by using those binary operators << or >> you can shift the binary to the left or right adding a ZERO to the four bits and changing the decimal number.

I understand that using the code x = bit(i) | 1; am putting the bit (i) to 1 and changing the decimal number again.

Have a few question about it also

#define bit(x) (1UL << (x))

int main()
{
  unsigned int x=0;

  x |= bit(0) | 1; // 00000001 = 1
  cout<< x <<endl;
  x |= bit(1) | 1; // 00000011 = 3
  cout<< x <<endl;
  cout<< (x >> 1 << 1) <<endl; // 00000010 = 2 
  x |= bit(2) | 1; // 00000111 = 7
  cout<< x <<endl;
  x |= bit(6) | 1; // 01000111 = 71
  cout<< x <<endl;

  // Get back a sliver
  cout<< (x >> 1) <<endl; // 00100011 = 35
  cout<< (x >> 2 << 2) <<endl; // 01000100 = 68
  cout<< (x >> 1) <<endl; // 00100011 = 35
  cout<< (x >> 1 << 1) <<endl; // 01000110 = 70
  cout<< (x >> 2 << 1) <<endl; // 00100010 = 34

  return 0;
}

1) #define bit(x) (1UL << (x)): what does the UL stand for and what does it do? Unsigned Long?

Also, when I deleted UL and left (1 << (x)) it worked aswell, with this the binary operator makes it shift one place to the left.

2) Tough I understand what happens when using these binary operators, I can't really figure out how this is going to help me getting those four decimal numbers into a variable x :?:
Not only that, but when they are entered, I have to retrieve one of them using a number from 0 to 3, so, when I have decimal numbers entered like:
3
7
14
6

And I enter for example 1, it should give me 7 as result, sorry, but I don't see how this could be done with the example code you gave me :o

If you could give me any further hints, I would greatly appreciate it.

Each nibble takes up 4 bits. So shifting by 4 times the desired position would get you to the desired spot.

#include <stdio.h>

unsigned int set(unsigned char nibble, int pos)
{
   return nibble << ( pos * 4 );
}

unsigned char get(unsigned int value, int pos)
{
   return ( value >> ( pos * 4 ) ) & 0xF;
}

int main ( void )
{
   unsigned int x = set(3,0) + set(7,1) + set(14,2) + set(6,3);
   int i;
   for ( i = 0; i < 4; ++i )
   {
      printf ( "get(%d) = %d\n", i, get(x,i) );
   }
   printf ( "x = %X\n", x );
   return 0;
}

/* my output
get(0) = 3
get(1) = 7
get(2) = 14
get(3) = 6
x = 6E73
*/

Thanks for the help Dave, but, can you explain this to me without using those two functions, it's an exercise in wich functions an references aren't seen yet and to be honest, I'd rather do this exercise without them, it's to confusing for me at this moment ;)

So, how could I do that without using those functions?

Thanks

Thanks for the help Dave, but, can you explain this to me without using those two functions, it's an exercise in wich functions an references aren't seen yet and to be honest, I'd rather do this exercise without them, it's to confusing for me at this moment ;)

So, how could I do that without using those functions?

I feel like I'm stepping on Narue's toes already, but...

#include <stdio.h>

int main ( void )
{
   unsigned int   x;
   unsigned char  nibble;
   /*
    * Set the value 3 in the 0th nibble.
    */
   x = 3 << (0 * 4);
   printf ( "x = %04X\n", x );
   /*
    * Add in the value 7 in the 1st nibble.
    */
   x += 7 << (1 * 4);
   printf ( "x = %04X\n", x );
   /*
    * Add in the value 14 in the 2nd nibble.
    */
   x += 14 << (2 * 4);
   printf ( "x = %04X\n", x );
   /*
    * Add in the value 6 in the 3rd nibble.
    */
   x += 6 << (3 * 4);
   printf ( "x = %04X\n", x );
   /*
    * Get the value in the 1st nibble.
    */
   nibble = ( x >> (1 * 4) ) & 0xF;
   printf ( "nibble = %d\n", nibble );
   return 0;
}

/* my output
x = 0003
x = 0073
x = 0E73
x = 6E73
nibble = 7
*/

The amount of left or right shift is some parenthesized multiple of 4, which is enough bits for each nibble value.

The bits could be ORed in (|) instead of adding.

For extraction, the & 0xF masks off the lowest 4 bits, after the appropriate shift, and clears any others.

Thanks,

But why does the nibble need to be a char and can't it be an integer?

Can you explain how this can be summorized: printf ( "x = %04X\n", x );

Using cout, can I write it like this: cout<< "x = " <<hex<<x<<endl; ????

Can I compare putting the numbers 3, 7, 14, 6 into a binary operator as a sort of array?

>But why does the nibble need to be a char and can't it be an integer?

It doesn't need to be a char. [rhetorical]But why waste a full int for 4 bits?[/rhetorical]

>Can you explain how this can be summorized: printf ( "x = %04X\n", x );
>Using cout, can I write it like this: cout<< "x = " <<hex<<x<<endl; ????

Yup.

>Can I compare putting the numbers 3, 7, 14, 6 into a binary operator as a sort of array?

I suppose you could think of the int as an array of nibbles.

Nope, can't figure it out :sad:

int main()
{
	unsigned int x, j;
	unsigned char  nibble;
	
	for (int i=0;i<4;i++)
	{
		cin>>j;cin.get();
		x+= j << (i * 4);
	}

	for (i=0;i<4;i++)
		cout<< hex << nibble = x << (i * 4) <<endl;

	return 0;

}

What I want to do is, is enter four different numbers smaller then 16 and then just print them!

One error that I keep getting is: error C2297: '<<' : illegal, right operand has type 'class ostream &(__cdecl *)(class ostream &)'

This has to do with the last loop, but don't know how to solve it, could someone please help me.

Thank you!

cout<< hex << nibble = x << (i * 4) <<endl;

Try not do so much as a one-liner: it can add to confusion and and be more error prone. Also, cout adds some fun that printf didnt when it comes to displaying the value.

unsigned int x, j;
	unsigned char  nibble;
	
	for (int i=0;i<4;i++)
	{
		cin>>j;cin.get();
		x+= j << (i * 4);
	}

You don't initialize x before you add to it -- not good. Initialize it to 0.

unsigned int x, j;
	unsigned char  nibble;
	
	for (int i=0;i<4;i++)
	{
		cin>>j;cin.get();
		x+= j << (i * 4);
	}

	for (i=0;i<4;i++)

This is a MSVC6 thing, but it is incorrect: i should not be in scope for the the second for loop.

From the top:

#include <iostream>
using namespace std;

int main()
{
   unsigned int x = 0, i, j, nibble;

   for ( i = 0; i < 4; ++i )
   {
      cin >> j;
      cin.get();
      x += j << (i * 4);
   }

   for ( i = 0; i < 4; ++i )
   {
      nibble  = x >> (i * 4);
      [B]nibble &= 0xF;[/B]
      cout << hex << nibble <<endl;
   }

   return 0;
}

Pfffffffffff, why do you guys and girls allways make it look so simple :mrgreen:

On a serious note, thanks a lot Dave ;)

>>Try not do so much as a one-liner: it can add to confusion and and be more error prone. Also, cout adds some fun that printf didnt when it comes to displaying the value.

Do you mean that It's best not to write to much code on one line? Maybe a stupid question, but being a non native English speaking person, I'dd like to be sure!

>>

nibble &= 0xF;

Could you explain this please, I think I understand 0xF wich equals a number in the decimal notation correct?

But why do you use the ampersand '&' , what does it do, I don't understand what happens with the nibble when you use it?
Is there a possibility to write a piece of code without using '&'?

Is the use of '&' related to the error message I got?

Do you mean that It's best not to write to much code on one line?

Yes.

nibble &= 0xF;

Could you explain this please, I think I understand 0xF wich equals a number in the decimal notation correct?

It isolates the lowest 4 bits (values between 0 and 15).

But why do you use the ampersand '&' , what does it do, I don't understand what happens with the nibble when you use it?
Is there a possibility to write a piece of code without using '&'?

No. Watch what it does:

#include <iostream>
using namespace std;

int main()
{
   unsigned int x = 0, i, j, nibble;

   for ( i = 0; i < 4; ++i )
   {
      cin>>j;
      cin.get();
      x+= j << (i * 4);
   }

   cout << hex << x << endl;

   for ( i = 0; i < 4; ++i )
   {
      nibble  = x >> (i * 4);
      cout << "before: " << hex << nibble << endl;
      nibble &= 0xF;
      cout << "after:  " << hex << nibble << endl;
   }

   return 0;
}

/* my output
15 1 9 3
391f
before: 391f
after:  f
before: 391
after:  1
before: 39
after:  9
before: 3
after:  3
*/

Is the use of '&' related to the error message I got?

No. It's because of trying to do too much in one line.

cout<< hex << (nibble = x << (i * 4)) <<endl;

Ok, got it now, thanks for the explanation :)

I think JoBe got it, folks are smart in Belgium!
Just in case there are some stragglers, here is another twist to Dave's wonderful code. I am trying to make the whole thing more visible ...

// bitwise operations  << shift left, >> shift right, & bitwise AND 
// a nibble is 4 bits, char is 8 bits, int is 32 bits
// try to store values 3, 7, 14, 6 in an integer

#include <stdio.h>

// prototype
void dec2bin(long decimal, char *binary);

int main ()
{
   unsigned int   x;
   unsigned char  nibble;
   char binary[80];
   
   x = 0;
   printf("count groups of 4 bits (nibbles) from right to left ...\n\n");

   // put 3 into the first group of 4 bits (nibble #0)
   x = 3 << (0 * 4);
   dec2bin(x,binary);
   // added 00 to make the groups of 4 bits show better
   printf("value 3 in nibble #0  = 00%s\n", binary);   

   // put 7 into the second group of 4 bits (nibble #1)
   x += 7 << (1 * 4);
   dec2bin(x,binary);
   printf("value 7 in nibble #1  = 0%s\n", binary);

   // put 14 into the third group of 4 bits (nibble #2)
   x += 14 << (2 * 4);
   dec2bin(x,binary);
   printf("value 14 in nibble #2 = %s\n", binary);

   // put 6 into the fourth group of 4 bits (nibble #3 and so on, plenty of space)
   x += 6 << (3 * 4);
   dec2bin(x,binary);
   printf("value 6 in nibble #3  = %s\n", binary);
   
   printf("\n... retrieve values ...\n\n");

   // retrieve the values in nibble #0, #1, #2 and #3
   // & is bitwise AND, 0xF is binary 1111
   nibble = ( x >> (0 * 4) ) & 0xF;
   printf ( "value in nibble #0 = %d\n", nibble );   
   nibble = ( x >> (1 * 4) ) & 0xF;
   printf ( "value in nibble #1 = %d\n", nibble );
   nibble = ( x >> (2 * 4) ) & 0xF;
   printf ( "value in nibble #2 = %d\n", nibble ); 
   nibble = ( x >> (3 * 4) ) & 0xF;
   printf ( "value in nibble #3 = %d\n", nibble );      
   
   getchar();    // wait
   return 0;
}

//
// accepts a decimal integer and returns a binary coded string
//
void dec2bin(long decimal, char *binary)
{
  int  k = 0, n = 0;
  int  neg_flag = 0;
  int  remain;
  char temp[80];

  do 
  {
    remain    = decimal % 2;
    decimal   = decimal / 2;   // whittle down decimal 
    temp[k++] = remain + 0x30; // makes characters 0 or 1 
  } while (decimal > 0);

  while (k >= 0)
    binary[n++] = temp[--k];   // reverse spelling
  binary[n-1] = 0;             // end with NULL = EOS
}

I think JoBe got it, folks are smart in Belgium!

Smart people here, of course, but don't think I'm one of them, certainly not in programming :cheesy:

But, must admit, it is fun to try and be smart :cheesy:

Seeing as the next exercise is also about the use of binary operators I figured I'd use the same tread.

Idea is to multiply a certain number (not to large) by one hundred using the binary operator << a few times :!:

My solution:

int main()
{
	unsigned short x;

             cin>>x;cin.get();

             cout<< ((x << 7) - (x << 5) + (x << 2))<<endl;

	return 0;

Alltough this works, I was wondering If it isn't possible to get this done without adding and subtracting this and still only use one variable x?

(x << 7) - (x << 5) + (x << 2)

What this is doing is this:

(x * 128) - (x * 32) + (x * 4)

Which would be the same as

x * (128 - 32 + 4) // which is the same as...
x * 100

So you could do it other ways too, like this

(x << 6) + (x << 5) + (x << 2) // (64 + 32 + 4)

But unless you are multiplying be a power of 2, you'll probably need to add and/or subtract to achieve the desired result.

Hi Dave,

I allready understood this threw the exercise before this one and your explanation on that one, thanks ;)

Maybe I didn't explain it to well, so here it goes.

Using the binary operator <<, I can make sure that a certain variable is multiplied, this however is done in my example and your examples by using the + and - operator!

Question is, could this same exercise be done without the use of these two operators but still with the use of the binary operator << ?????

Question is, could this same exercise be done without the use of these two operators but still with the use of the binary operator << ?????

Unless someone wants to show me a new trick...

But unless you are multiplying be a power of 2, you'll probably need to add and/or subtract to achieve the desired result.

Unless someone wants to show me a new trick...

EUh :o ok, :o

Why oh why do I feel so stupid right now :cheesy:

Hi, next exercise is this one: take a hexadecimal number like F703 and switch the last two hexadecimal numbers with eachother so that:

bit 0 switch with bit 7
bit 1 switch with bit 6
bit 2 switch with bit 5
bit 3 switch with bit 4


for example F703 would become F7C0.

I understand that 03 changing into C0 has to do with the fact that 03 is binary equal to --> 0000 0011 so switching these binary is 1100 0000 with C0 as result.

I have been trying to do this as instructed in the exercise using binary operators but with no result :o

I tried to use the inverter ~ because this can change a binary code from 0011 to 1100 but isn't related to exchanging bits with eachother, this one can be use only as a unary operator!

I tried to use the ^ operator since this one turns a bit into 0 when two bits are the same and into 1 when they are different like this code:

..1001
^0010
-------
..0100

I know the use of << wich can result in 0011 turning into 0110

I think that as in the previous exercise, I have to use the nible and have to cut the hexadecimal number into pieces of four bits like this (i *4) & 0xF;
But I fail to see how I can control these and switch them with the others :sad:

Also, I don't have a clue how I should leave the first two hex numbers alone and work solely with the last two?

Any help is as allways very much appreciated.

This is a bit reverser I'd done a long time ago.

#include <stdio.h>
#include <limits.h>

unsigned char bitrev(unsigned char value)
{
   unsigned char mask = 1 << (CHAR_BIT - 1), result = 0;
   while ( value )
   {
      if ( value & 1 )
      {
         result |= mask;
      }
      mask  >>= 1;
      value >>= 1;
   }
   return result;
}

int main(void)
{
   unsigned char value = 5, reversed = bitrev(value);
   printf("value = 0x%02X, reversed = 0x%02X\n", value, reversed);
   return 0;
}

/* my output
value = 0x05, reversed = 0xA0
*/

Throw in some debugging outputs to get a better feel for what's going on.

Then using masking (the & 0xFF00 type stuff) you can assemble your integer. Remember to post the code of your attempt.

Thanks for the example Dave, Im testing it to see what it does and I partially understand what's happening.

As soon as I understand it completly, I'll try it out on the exercise I got and I'll show it!

Found this is the MSDN Library: CHAR_BIT 8 Number of bits in a char wich is related towards the <limits.h> library.

What I don't understand is why you write (-1) behind the CHAR_BIT part because you are allready changing the place by one by this unsigned short mask = 1 << (CHAR... ?

I'm puzzled :?:

What I don't understand is why you write (-1) behind the CHAR_BIT part because you are allready changing the place by one by this unsigned short mask = 1 << (CHAR... ?

If CHAR_BIT is 8, then CHAR_BIT - 1 is 7. So 1 << 7 is 0x80. This would be an unsigned char value with only the highest bit set.

Hi Dave,

Tried it out, this is what I'm getting, the reverser as you showd is working fine, but I'm not getting the first two nibble's in front of the hexadecimal number as I should?

int main()
{
	unsigned short i, x=0, nibble, number, reverse = 0, mask = 1 << (CHAR_BIT - 1);

	cin>> hex >> x; cin.get();

	for (i = 0; i<4;++i)
	{
		if (i < 2)
		{
			nibble = x << (i * 4);
			nibble &= 0xF;

			while (nibble)
			{
				if (nibble & 1)
				{
					reverse |= mask;    
				}
				mask   >>= 1;
				nibble >>= 1;
			}
		}
			else			// this part serves for the last
			{				// two nibbles wich don't have to be altered!
				nibble = x << (i * 4);
				nibble &= 0xF;
			}
		number = reverse + nibble;	// <-- not getting the result
	}								// I should get.

	cout<< hex << reverse <<endl;

	return 0;
}

/*	when I enter: f703
	result is   : c0
	result should be: f7c0*/

You want a certain part of the original value untouched, so mask that part off and combine it with the other results.

reverse |= (0xFF00 & x);
   cout<< hex << reverse <<endl;

Yep, that did it:

int main()
{
	unsigned short i, x = 0;
	unsigned short nibble, reverse = 0;
	unsigned char mask = 1 << (CHAR_BIT - 1);

	cin>> hex >> x; cin.get();

	for (i = 0; i<2;++i)
	{
	             nibble = x << (i * 4);
		nibble &= 0xF;

		while (nibble)
		{
			if (nibble & 1)
			{
				reverse |= mask;    
		             }
			mask  >>= 1;
			nibble >>= 1;
		}
	}
	reverse |= (0xFF00 &x);

	cout<< hex << reverse <<endl;

	return 0;
}

Do have question tough.

reverse |= (0xFF00 & x);

Is it because I'm linking variable x towards 'FF00' that the compiler knows I want to hold the value of the last two nibbles?

If so,

for (i = 0; i<2;++i)

I changed 2 into 4 wich gave me the same result, does this mean that alltough I'm changing the value during the loop, the value of x seeing as it was f7 therefore remains f7?

Thanks for the help again Dave, two more binary operator exercises to go before I start tackling functions :D

Do have question tough.

reverse |= (0xFF00 & x);

Is it because I'm linking variable x towards 'FF00' that the compiler knows I want to hold the value of the last two nibbles?

If I'm reading this correctly, no. It's because of the |=. You got what you wanted for reverse for the lowest 2 nibbles and then masked off the higher 2 nibbles of x and ORed them together.

Yep, that was the question Dave, thanks.

Ive been trying to get the next one working in wich I have to switch bit 0--> 1, 1-->2, ... , 7-->0 and each bit has to hold it's own value when it get's switched.

It isn't doing what it should do, as I thought you should divide each bit separatly

for (i = 0; i < 8; ++i)

and then cut of each bit

bit = x << (i * 1);  
bit &= 0xF;

I think my main problem is the fact to get the previous bit into the next one and especially number 7 into number 0 :?:

Here's what Ive got sofar,

int main()
{
	unsigned short i, x = 0;
	unsigned short bit, leftbit = 0;
	unsigned char mask = 1 << (CHAR_BIT - 1);

	cin>> hex >> x; cin.get();

	for (i = 0; i < 8; ++i)
	{
		bit = x << (i * 1);
		bit &= 0xF;

		while (bit)
		{
			if (bit & 1)
			{
				leftbit |= mask;
			}
			mask<<=1;
			bit <<=1;
		}
	}

	leftbit |= ( 0xFF00 &x);

	cout<< hex << leftbit <<endl;

	return 0;
}

Hope your able to help me out Dave, or, anyone else ofcourse ;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.