3

I'm currently learning C with "The C Programming Language" from K&R. I solved the exercise 2-7, which says:

Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the other bits unchanged.

Here is my code (I voluntarily used chars here):

#include <stdio.h>

#define NUMBER   235
#define POSITION 2
#define AMOUNT   4

unsigned invert(unsigned char x, char p, char n)
{
    unsigned char bitsToInvert = 0, i;

    for (i = 1; i < n; i++) { // Make a number n-bits width, full of 1
        bitsToInvert |= 1;
        bitsToInvert <<= 1;
    }
    bitsToInvert |= 1;

    bitsToInvert <<= p;

    x ^= bitsToInvert;

    return x;
}

int main()
{
    printf("%d\n", invert(NUMBER, POSITION, AMOUNT));
}

Is there any optimisation I could bring to my code? Especially on the for loop which create a number of n 1 bits? Thanks!

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
GilDev
  • 514
  • 5
  • 14

2 Answers2

2

2^n - 1 is always a number with all n LSB bits set.

For eg:

2 ^ 3 - 1 = 7  => 111
2 ^ 5 - 1 = 31 => 11111

In your case, you can do away with the for loop to construct this number by simply saying:

bitsToConvert = (1<<n) - 1;

Dont forget to take care of extreme situations.

UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
0

An alternative to what Thrustmaster said, that would work for any "n" without the need for specifying it, would be using a bitwise not on an empty value.

variable = ~(variable ^ variable);
SSWilks
  • 105
  • 8