Какой лучший способ подписать расширение числа в C / C ++ - PullRequest
2 голосов
/ 15 марта 2019

У меня есть 10-битное значение со знаком .На самом деле это 10-битное значение цвета, которое я хочу преобразовать в int.

. 10 битов следует интерпретировать как значение со знаком в большем int, где остальные биты равны нулю.

Я могу придумать 3 способа, показанных здесь:

#include <stdio.h>

void p(int v)
{
    printf("\t%d", v);
}

int main()
{
    for (int i = -2; i < 3; ++i)
    {
        unsigned int u = i & 0x3ff;

        int v;

        // method 1: test the bit
        v = u;
        if (u & 0x200) v = v ^ -0x400;
        p(v);

        // method 2: shift
        v = u<<(sizeof(int)*8-10);
        v >>= (sizeof(int)*8-10);
        p(v);

        // method 3: use sign extend
        v = (signed char)(u >> 2);
        v <<= 2;
        v |= u;
        p(v);


        printf("\n");

    }

    return 0;
}

Есть ли лучший способ?Часто возникают проблемы с этим небольшим поворотом.

Спасибо за любой ввод.

Обновление

Добавление еще двух методов.Первое, предложенное @ cruz-jean, это битовые поля, а второе, предложенное gcc после компиляции битовых полей.

      // method 4: bit fields
        struct { int v:10; } f;
        f.v = u;
        v = f.v;

        // method 5: sign extend short
        v = (signed short)(u << 6);
        v >>= 6;

Из интереса кажется, что MSVC компилирует # 4 в # 2, а gcc компилирует # 4 в# 5.

Метод 5 выглядит хорошо.

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Вы можете объявить 10-битный вспомогательный тип битового поля со знаком и получить доступ к значению как int:

struct signed_10_bit
{
    int val : 10;
};

int some_10_bit_num = 0x3ff;
int extended = signed_10_bit{ some_10_bit_num }.val;
0 голосов
/ 16 марта 2019

Еще один вариант:

v = u | (0 - (u&0x200));

хорошо для процессора, где сдвиг медленный.

...