1,105,332 Community Members

How to flip bits

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Hi,

Im trying to make a function that flip bits. There is not much usefull to find on the net about this.

Like an example of such function. Does anyone have a function that flipbits?

Thnx in advance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

The XOR operator is usually used to flip bits. You can flip a single bit by making a 1-bit mask (shifting 1 to the proper bit position) and then XORing the value with your mask:

inline unsigned flip ( unsigned x, unsigned bit )
{
  return x ^ (1UL << bit);
}

You can increase the number of bits affected by changing the number of set bits in the mask. For example, a 2-bit flip would change 1UL to 3UL. And the bits don't have to be adjacent.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Hi Narue,

Thnx for your reply!

This is what my main is look like:

main()
{
     int v = 0x90; /* a test value */
     int res, i;
     
     printf("\nFlipbit test %0x\n", v);
     printbinair( v ); 
     putchar('\n');
     
     res = flipbit( v, 4 ); /* bit 4 (value 16) inverts to 1->0 or 0->1 */
     printbinair( res ); 
     
     putchar('\n'); 
     printf("Hex %0x\n", res ); // result must be: 0x80

My filbit function is like this:

/* i don't know wheater x and p has to be an int or char or unsigened */
void flipbit(a,b) 
{

    /* emtpy body */

}

what should i put in the empty body, and how should i declare the a and b?

Thnx in advance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>what should i put in the empty body, and how should i declare the a and b?
In relation to my function, a is equivalent to x and b is equivalent to bit. a represents the value that you're working with and b represents the bit position that will be flipped. They should be declared as unsigned unless you're familiar with the pitfalls of twiddling bits on signed types.

However, your definition of flipbit and your use of flipbit don't match. The main function expects flipbit to return a value but flipbit is defined to return nothing. You'll need to make up your mind, because that effects how the declaration of the parameter a. If flipbit returns a value, you can simply translate the function I posted:

unsigned flipbit(unsigned a, unsigned b) 
{
    return a ^ (1UL << b);
}

If flipbit doesn't return a value, you need to pass a reference so that any changes are reflected back in the calling function:

void flipbit(unsigned& a, unsigned b) 
{
    a ^= (1UL << b);
}

But that can introduce some frustrating typing errors, so I'd recommend that you use with the option of returning the result.

Member Avatar
Rashakil Fol
Super Senior Demiposter
2,596 posts since Jun 2005
Reputation Points: 982 [?]
Q&As Helped to Solve: 209 [?]
Skill Endorsements: 42 [?]
Team Colleague
 
0
 

If flipbit doesn't return a value, you need to pass a reference so that any changes are reflected back in the calling function:

void flipbit(unsigned& a, unsigned b)

Yustme, note that what Narue posted is valid C++ code, but not C code (and it looks like you're using C based on your other thread). In C you'd want to pass the memory address of the integer, via a pointer:

void flipbit(unsigned* a, unsigned b) 
{
    *a ^= (1UL << b);
}

These are pretty much different ways of doing, but only one is allowed in C. Then you'd need to pass the memory address of your integer, instead, with:

res = v;
flipbit(&res, 4);

But it makes more sense to return the value.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Yustme, note that what Narue posted is valid C++ code, but not C code (and it looks like you're using C based on your other thread). In C you'd want to pass the memory address of the integer, via a pointer:

void flipbit(unsigned* a, unsigned b) 
{
    *a ^= (1UL << b);
}

These are pretty much different ways of doing, but only one is allowed in C. Then you'd need to pass the memory address of your integer, instead, with:

res = v;
flipbit(&res, 4);

But it makes more sense to return the value.

I see...

Could you tell me what UL does and means?

And what is the difference between function(char* var) and function(char *var) ?

Thnx inadvance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>Could you tell me what UL does and means?
UL is a suffix on a numeric constant to tell the compiler that the value's type should be an unsigned long.

>And what is the difference between function(char* var) and function(char *var) ?
There's no semantic difference.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

This is the flipbit function now:

void flipbit( unsigned* x, unsigned p )
{
     *x ^ ( 1UL << p );          
     /* UL is een toevoeging/aanhechting aan een constante getal om de compiler 
     te vertellen dat het type van de waarde een unsigned long moet zijn */
}

I understood that you (Rashakil) said that i do have to return something.
And my guess is the x.

And this is the main():

main()
{
     int v = 0x90; /* a test value */
     int res, i;
     
     printf("\nFlipbit test %0x\n", v);
     printbinair( v ); 
     putchar('\n');
     
     res = v;
     
     flipbit( &res, 4 ); /* bit 4 (value 16) inverts to 1->0 or 0->1 */
     printbinair( res ); 
     
     putchar('\n'); 
     printf("Hex %0x\n", res ); // result must be: 0x80

After compiling this code, it gives me the error: invalid conversion from int to unsigned char.
And: initializing argument 1 of void flipbit( unsigned int*, unsigned int ).

But it has to be an int. I don't wanna change that.

Never knew that programming was so hard..... :sad:

Member Avatar
Rashakil Fol
Super Senior Demiposter
2,596 posts since Jun 2005
Reputation Points: 982 [?]
Q&As Helped to Solve: 209 [?]
Skill Endorsements: 42 [?]
Team Colleague
 
0
 

Never knew that programming was so hard..... :sad:

That's just a result of the programming language you decided to learn. C wasn't designed to be the most user friendly language. But in most ways, C is relatively simple.

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>it gives me the error: invalid conversion from int to unsigned char.
Do you remember me mentioning frustrating typing errors? That's one of them.

/* UL is een toevoeging/aanhechting aan een constante getal om de compiler
te vertellen dat het type van de waarde een unsigned long moet zijn */

That's an exceptionally long comment for a small feature of the language that should be common knowledge.

>Never knew that programming was so hard.....
Most people don't realize the effort that goes into software until they've tried it.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

>it gives me the error: invalid conversion from int to unsigned char.
Do you remember me mentioning frustrating typing errors? That's one of them.

That's an exceptionally long comment for a small feature of the language that should be common knowledge.

>Never knew that programming was so hard.....
Most people don't realize the effort that goes into software until they've tried it.

That long commet is actually a note for my personal 'C notes doc'. I just pasted it there for temporarly....

Do you remember me mentioning frustrating typing errors? That's one of them.

Yes i do, but i didn't know what you ment by that. I guess i had to found out about that the hard way...

Im starting all over again and i will reorganize my way of learning this langauge.


I typed a peace of code from a book. Im trying to learn the pointer arithmetic. There is something i don't quit understand what it prints to the screen.

This is the code:

#define MAXSTRING 100

main()
{
      char c = 'a', *p, s[MAXSTRING];
      
      p = &c;   // p = nu 'a', omdat c de waarde 'a' bevat.
      
      printf( "%c%c%c ", *p, *p + 1, *p + 2 );
      strcpy( s, "ABC" );
      printf("%s %c%c%s\n", s, *s + 6, *s + 7, s + 1 );
      strcpy( s, "she sells sea shells by the seashore" );
      
      p = s + 14;
      for( ; *p != '\0'; ++p )
      {
           if( *p == 'e' )
           *p = 'E';
           
           if( *p == ' ' )
           *p = '\n';
      }
      printf( "%s\n\n", s );
      system( "\npause" );
}

This is the output:

abc ABC GHBC
she sells sea shElls
by
thE
sEashorE

I understand every output this program gives, except for 'GHBC' .

And it has to do something about this line:

printf("%s %c%c%s\n", s, *s + 6, *s + 7, s + 1 );

Even if i start counting from A, adding 6, i get 'F'. And wheni start counting from 'C' and add 6 to it, i get 'I'.

So how did they get GH and BC practicaly sticked behind it?

Thnx in advance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>I guess i had to found out about that the hard way...
Rather than enumerate the problems that you might have, I decided to let you see for yourself. :)

>I understand every output this program gives, except for 'GHBC' .
First you print *s + 6, which is identical to s[0] + 6. Since s[0] is 'A', and presumably you're using ASCII, 'A' + 6 is 'G'. Repeat the same process with 'A' + 7 for the next character to get 'H'. Then s + 1 is printed, which is the same as &s[1], which refers to a slice of the string starting at the second character "BC", and the entire slice is printed using %s.

Member Avatar
Rashakil Fol
Super Senior Demiposter
2,596 posts since Jun 2005
Reputation Points: 982 [?]
Q&As Helped to Solve: 209 [?]
Skill Endorsements: 42 [?]
Team Colleague
 
0
 

I understood that you (Rashakil) said that i do have to return something.

No, I recommended using the version (that Narue posted) that returns a value.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

>I guess i had to found out about that the hard way...
Rather than enumerate the problems that you might have, I decided to let you see for yourself. :)

>I understand every output this program gives, except for 'GHBC' .
First you print *s + 6, which is identical to s[0] + 6. Since s[0] is 'A', and presumably you're using ASCII, 'A' + 6 is 'G'. Repeat the same process with 'A' + 7 for the next character to get 'H'. Then s + 1 is printed, which is the same as &s[1], which refers to a slice of the string starting at the second character "BC", and the entire slice is printed using %s.

Rather than enumerate the problems that you might have, I decided to let you see for yourself. :)

It worked :D

First you print *s + 6, which is identical to s[0] + 6. Since s[0] is 'A', and presumably you're using ASCII, 'A' + 6 is 'G'. Repeat the same process with 'A' + 7 for the next character to get 'H'. Then s + 1 is printed, which is the same as &s[1], which refers to a slice of the string starting at the second character "BC", and the entire slice is printed using %s.

Thank you Narue's!

I almost got it. I understand that the counting starts from s[0]. And that the value of the pointer doesn't change after doing this: *s + 6. Coz its poiting to &s[0] and counts to 6, which makes it become 'G'.

And i thought counting to 7 again *s + 7 and adding that value to the prevous *s + 6 which would have make it an 'M'.

There is one thing that still bothers me....

If 'A' = &s[0], how come "BC"= &s[1]? Shouldn't that be 'B' = &s[1] and 'C' = &s[2] ?

Thnx in advance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>adding that value to the prevous *s + 6 which would have make it an 'M'.
You didn't assign the result of *s + 6 to *s, so it remains 'A'. Therefore, *s + 7 also begins with 'A' and results in 'H'. Now, *s += 6 would have the result that you expect (though adding 7 would give you 'N' rather than 'M') because the result of *s + 6 is assigned to *s and the next operation sees 'G' instead of 'A'.

>If 'A' = &s[0], how come "BC"= &s[1]? Shouldn't that be 'B' = &s[1] and 'C' = &s[2] ?
You're catching on to pointers much more quickly than most people. :) &s[0] isn't 'A', it's "ABC" because &s[0] is the string starting at the address of the single character s[0]. Likewise, &s[1] is the string starting at the second character of the array, or "BC". s[1] is the single character, 'B'.

It helps if you think in terms of addresses and contents. The address of 'A' is &s[0], and the content of the address &s[0] is 'A'. The address of 'B' is &s[1] (or s + 1 for reasons that will become clear later), and the content of the address &s[1] is 'B'.

Now, a string is a sequence of characters (the contents of a sequence of one byte memory addresses). The first address in that sequence is the beginning of the string. So &s[0] represents the string "ABC" because the starting address is the address of 'A'. Likewise, &s[1] represents the string "BC" because the starting address is the address of 'B'.

Member Avatar
dors_zone
Newbie Poster
12 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

here are the question,

a) Write a function named OutOfOrder that takes as input parameters an array of doubles named Arr and an int parameter named size and returns a value of type int. The return value is -1 if the array is in order, meaning that the first element in the array is less than or equal to the second element in the array, the second element in the array is less than or equal to the third element in the array and so on. If the array is not in order, the return value is the index of the first element in the array that is out of order.


int i,j,n;
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i;j++)
{
if (c<=c[i+1])
{
t=c[j];
c[j]=c[j+1];
c[j+1]=t;
}
else continue;
}

-----

am i correct? plz guide me...

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

If you have a separate question, post a new thread.

Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

It helps if you think in terms of addresses and contents. The address of 'A' is &s[0], and the content of the address &s[0] is 'A'. The address of 'B' is &s[1] (or s + 1 for reasons that will become clear later), and the content of the address &s[1] is 'B'.


>adding that value to the prevous *s + 6 which would have make it an 'M'.
You didn't assign the result of *s + 6 to *s, so it remains 'A'. Therefore, *s + 7 also begins with 'A' and results in 'H'. Now, *s += 6 would have the result that you expect (though adding 7 would give you 'N' rather than 'M') because the result of *s + 6 is assigned to *s and the next operation sees 'G' instead of 'A'.

I knew that :D . Coz *s keeps poiting to what the char had as value.

>If 'A' = &s[0], how come "BC"= &s[1]? Shouldn't that be 'B' = &s[1] and 'C' = &s[2] ?
You're catching on to pointers much more quickly than most people. :) &s[0] isn't 'A', it's "ABC" because &s[0] is the string starting at the address of the single character s[0]. Likewise, &s[1] is the string starting at the second character of the array, or "BC". s[1] is the single character, 'B'.

I see..... So let me get this straight with my own words and an example.

Suppose i make this peace of code, a sligthly different:

#define MAXSTRING 100

main()
{
      char c = 'd', *p, s[MAXSTRING];

      p = &c;  // p = now d
      
      printf( "%c%c%c ", *p, *p + 1, *p + 2 );
      strcpy( s, "DEFG" );
      printf("%s %c%c%s\n",  s, *s + 6, *s + 7, s + 1 );
}

The first output would be:
def

The second output would be:
DEFG (D + 6 equivalent to &s[0] + 6 which is J and adding 6 by D = J) And replaces the D with J.

And D + 7 is equivalent to &s[0] + 7 which is K and adding 7 by D = K. And K replaces the E.

And s + 1 is equivalent to 'whatever character starts at &s[1] print it with everything what is behind it. And in this case &s[1] = E and FG are behind E.

Because:

a string is a sequence of characters (the contents of a sequence of one byte memory addresses). The first address in that sequence is the beginning of the string. So &s[0] represents the string "ABC" because the starting address is the address of 'A'. Likewise, &s[1] represents the string "BC" because the starting address is the address of 'B'.

So....Conclusion:

The second output is:
DEFG JKEFG


There is just one thing i wanna know and that is what is the difference between the " " double quote tags and ' ' single quote tags in C.

Thnx in advance!

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

>D + 6 equivalent to &s[0] + 6 which is J and adding 6 by D = J
Not quite. Remember that the & operator means "address-of", so &s[0] isn't 'D', it's the address of 'D'. Remove the ampersand and you're working with 'D' itself, and your analysis is correct.

>what is the difference between the " " double quote tags and ' ' single quote tags in C.
Single quotes delimit a single character and double quotes delimit a string of characters. A string always has at least one character in it, the null terminator ('\0'). So 'A' is basically a small integer that holds the numeric value of the letter A for your character set. In ASCII that would be 65. However, "A" is a collection of small integers, in this case two: the character 'A' and the character '\0'. It helps if you think of a string literal as an unnamed constant array of char (which is basically what it is):

const char [I]<unnamed>[/I][] = {'A','\0'};
Member Avatar
Yustme
Light Poster
31 posts since Mar 2006
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 


>what is the difference between the " " double quote tags and ' ' single quote tags in C.
Single quotes delimit a single character and double quotes delimit a string of characters. A string always has at least one character in it, the null terminator ('\0'). So 'A' is basically a small integer that holds the numeric value of the letter A for your character set. In ASCII that would be 65. However, "A" is a collection of small integers, in this case two: the character 'A' and the character '\0'. It helps if you think of a string literal as an unnamed constant array of char (which is basically what it is):

const char [I]<unnamed>[/I][] = {'A','\0'};

I got it, thnx :D


>D + 6 equivalent to &s[0] + 6 which is J and adding 6 by D = J
Not quite. Remember that the & operator means "address-of", so &s[0] isn't 'D', it's the address of 'D'. Remove the ampersand and you're working with 'D' itself, and your analysis is correct.


You're right! My bad.. & means the address of. And i was working with the value not the address.


Do you have a program or could you make one for me with pointers. So i can try to find out what is pointing to what and give my analyses again :D

Thnx in advance!

And a special thnx to you (narue) for your patience and help :D

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article