1

I have experience with Java and Python, but this is my first time really using C, for my first assignment also haha.

I'm having trouble figuring out how to convert an unsigned char to a bit, so I would be able to get/set/swap some bit values.

I'm not looking for someone to do my assignment of course, I just need help accessing the bit. I came across this Access bits in a char in C But it seems like that method only showed how to get the last two bits.

Any help or guidance is much appreciated. I tried Googling to see if there was some sort of documentation on this, but couldn't find any. Thanks in advance!

Community
  • 1
  • 1
user1730056
  • 623
  • 3
  • 11
  • 19
  • google bit operations in c, then look for getbit, setbit, clearbit, things like that. – Charlie Burns Oct 09 '13 at 23:33
  • possible duplicate of [What are bitwise operators?](http://stackoverflow.com/questions/276706/what-are-bitwise-operators) – Carl Norum Oct 09 '13 at 23:35
  • I'd say http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c/47990#47990 is a better dup as long as the poster knows a character is stored as a number in C – lsiebert Oct 09 '13 at 23:50

1 Answers1

4

Edit: Made changes in accordance with Chux's comment. Also introduced rotl function which rotates bits. Originally reset function was wrong (should have used the rotation instead of shift tmp = tmp << n;

unsigned char setNthBit(unsigned char c, unsigned char n) //set nth bit from right
{
  unsigned char tmp=1<<n;
  return c | tmp;
}

unsigned char getNthBit(unsigned char c, unsigned char n)
{
  unsigned char tmp=1<<n;
  return (c & tmp)>>n;
}

//rotates left the bits in value by n positions
unsigned char rotl(unsigned char value, unsigned char shift)
{
    return (value << shift) | (value >> (sizeof(value) * 8 - shift));
}

unsigned char reset(unsigned char c, unsigned char n) //set nth bit from right to 0
{
  unsigned char tmp=254; //set all bits to 1 except the right=most one
//tmp = tmp << n; <- wrong, sets to zero n least signifacant bits
                 //use rotl instead
  tmp = rotl(tmp,n);
  return c & tmp;
}

//Combine the two for swapping of the bits ;)
char swap(unsigned char c, unsigned char n, unsigned char m)
{
  unsigned char tmp1=getNthBit(c,n), tmp2=getNthBit(c,m);
  char tmp11=tmp2<<n, tmp22=tmp1<<m;
  c=reset(c,n); c=reset(c,m);
  return c | tmp11 | tmp22;
}
Igor Popov
  • 2,588
  • 17
  • 20
  • Thank you, simpler than I thought – user1730056 Oct 09 '13 at 23:59
  • My function has to take (unsigned char c, int n), how would I approach these using ints instead of an unsigned char for n – user1730056 Oct 10 '13 at 00:08
  • @user1730056 you can use the same code with `int`. However, it is better to use `char` because `int` will either be 2 or 4 bytes on most architectures and that much space is not really required. Since you can shift atmost by 8 bits (because you are assigning values to `char`), 8 bits are enough to represent that value – Poojan Oct 10 '13 at 00:15
  • I would if I could ): but I would lose half marks. I'm trying to call the function, with "unsigned char p = getBit(120, 2);" however I'm getting an error, conflicting types for 'getBit' is there somethign wrong with how I called it? – user1730056 Oct 10 '13 at 00:18
  • 1
    @Robin Odd choice to use 1 based indexing instead of 0. – Mike Makuch Oct 10 '13 at 00:24
  • How come an "experienced" Java and Python programmer don't know these simple logic functions? Logic is the most basic thing in computer that every programmer/electronics designer should know, all languages must have logic operators – phuclv Oct 10 '13 at 04:45
  • Certain `swap()` fails. `getNthBit()` returns 0 or 1 or 2 or 4 .... Using a `tmp2` greater than 1 in `tmp11=tmp2<<(n-1)` is certainly not intended. Suggest changing last line of `getNthBit()` to `return !!(c & tmp);`. Further, suggest using `unsigned char` in `swap()` for consistency. – chux - Reinstate Monica Oct 11 '13 at 13:17
  • @chux Thanks! I fixed those as well as an addition mistake :) – Igor Popov Oct 11 '13 at 14:27
  • 1
    Cool. Idea: an idiomatic alternative for `reset()`. `unsigned char mask = ~(1u << n); return c & mask;` – chux - Reinstate Monica Oct 11 '13 at 15:03
  • @chux It is simpler & faster than my reset(). – Igor Popov Oct 11 '13 at 23:29