Эффективно установить X-биты в числе N, начиная с позиции P из MSB - PullRequest
0 голосов
/ 28 декабря 2018

Приведенный ниже код устанавливает X-биты в начальном положении числа N из LSB (N - это 32-разрядное число)

//gcc 5.4.0
#include  <stdio.h>
unsigned int set_bits_pos(int N, int X, int P)
{
    unsigned int mask = ((1UL << X)-1) << P; 
    return (N|mask);
}

int main(void)
{
    unsigned int bits = 3, pos=5, num=0x0F;       
    printf("0x%X\n", set_bits_pos(num,bits,pos));
    return 0;
}

Вывод:

0xEF

Как преобразоватьвышеуказанная функция для установки X-битов с номером N, начальная позиция P от MSB?Лучший возможный способ.Спасибо

Редактировать: для установки из MSB и Arch Независимый для 32 и 64 бит N, после предложений

//gcc 5.4.0
#include  <stdio.h>
size_t set_bits_pos(size_t N, int X, int P)
{
    size_t mask = ((1UL << X)-1) << ((8*sizeof(N)) - P - X); 
    return (N|mask);
}

int main(void)
{
    size_t num=0x0F;
    int bits = 3, pos=5;       
    printf("0x%X\n", set_bits_pos(num,bits,pos));
    return 0;
}

Выход:

0x0700000F

1 Ответ

0 голосов
/ 28 декабря 2018

Я бы порекомендовал использовать целочисленные типы точной ширины:

#include <inttypes.h>

uint32_t  set_low32(const uint32_t     value,
                    const unsigned int bits,
                    const unsigned int skip)
{
    uint32_t  mask = (~(uint32_t)0) >> (32 - bits);
    return value | (mask << skip);
}

uint64_t  set_low64(const uint64_t     value,
                    const unsigned int bits,
                    const unsigned int skip)
{
    uint64_t  mask = (~(uint64_t)0) >> (64 - bits);
    return value | (mask << skip);
}

uint32_t  set_high32(const uint32_t     value,
                     const unsigned int bits,
                     const unsigned int skip)
{
    uint32_t  mask = (~(uint32_t)0) << (32 - bits);
    return value | (mask >> skip);
}

uint64_t  set_high64(const uint64_t     value,
                     const unsigned int bits,
                     const unsigned int skip)
{
    uint64_t  mask = (~(uint64_t)0) << (64 - bits);
    return value | (mask >> skip);
}

bits - это количество устанавливаемых битов (X в вопросе), а skip - это числонизкие / высокие биты для пропуска (P в вопросе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...