K&R Exercise 2-7, оптимизации?

В настоящее время я изучаю C с помощью "The C Programming Language" от K&R. Я решил упражнение 2-7, в котором говорится:

Напишите функцию invert(x,p,n), которая возвращает x с битами n, которые начинаются с позиции p, инвертированными (т. Е. 1 изменен на 0 и наоборот), оставив другие биты без изменений.

Вот мой код (я добровольно использовал здесь символы):

#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));
}

Могу ли я внести какую-то оптимизацию в свой код? Особенно в цикле for, который создает количество n 1 бит? Спасибо!


person GilDev    schedule 26.12.2014    source источник
comment
2^n - 1 или (1<<n) -1 предоставят вам последние n битов. :)   -  person UltraInstinct    schedule 26.12.2014
comment
вы должны хотя бы использовать unsigned chars.   -  person Jasen    schedule 26.12.2014
comment
Есть другое упражнение, в котором вас просят установить диапазон битов, это просто xor с этим.   -  person harold    schedule 26.12.2014
comment
Вот решение: clc-wiki.net/wiki/K%26R2_solutions:Chapter_2 : Exercise_7   -  person SVN    schedule 26.12.2014


Ответы (2)


2^n - 1 - это всегда число со всеми установленными n младшими битами.

Например:

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

В вашем случае вы можете отказаться от цикла for для построения этого числа, просто сказав:

bitsToConvert = (1<<n) - 1;

Не забывайте заботиться о экстремальных ситуациях.

person UltraInstinct    schedule 26.12.2014
comment
Спасибо, я мало об этом подумал. ^^ - person GilDev; 28.12.2014

Альтернативой тому, что сказал Thrustmaster, которая будет работать для любого «n» без необходимости его указания, будет использование побитового, а не пустого значения.

variable = ~(variable ^ variable);
person SSWilks    schedule 26.12.2014