LINUX.ORG.RU

История изменений

Исправление SZT, (текущая версия) :

Просто -1 это 0x1ffffff (25 бит). Если сбросить знаковый бит получится 0x0FFFF. Меняем знак - получаем -0xffff а не -1

Ну хорошо, допустим что хранится там в 25 битах в типе uint32_t

0b00000000 00000000 00000000 00000000 это 0
0b00000000 00000000 00000000 00000001 это 1
...
0b00000000 11111111 11111111 11111111 это 65535

0b00000001 11111111 11111111 11111111 это -1
0b00000001 11111111 11111111 11111110 это -2
0b00000001 00000000 00000000 00000000 это -65536
т.е. дополнительный код
Так а что собственно с ним делать? Перевести в честный int32_t? Тогда надо растянуть единичку из
0b00000001 11111111 11111111 11111111 это -1
         ^
этой позиции
на оставшиеся биты. Вроде как-то так:
uint32_t val; // тут хранится значение, которое надо перевести
bool is_signed = !!(val & (1 << SIGN_BIT_POS));
return  val | is_signed ? (0xFFFFFFFF << SIGN_BIT_POS) : 0;

Исходная версия SZT, :

Просто -1 это 0x1ffffff (25 бит). Если сбросить знаковый бит получится 0x0FFFF. Меняем знак - получаем -0xffff а не -1

Ну хорошо, допустим что хранится там в 25 битах в типе uint32_t

0b00000000 00000000 00000000 00000000 это 0
0b00000000 00000000 00000000 00000001 это 1
...
0b00000000 11111111 11111111 11111111 это 65535

0b00000001 11111111 11111111 11111111 это -1
0b00000001 11111111 11111111 11111110 это -2
0b00000001 00000000 00000000 00000001 это -65536
т.е. дополнительный код
Так а что собственно с ним делать? Перевести в честный int32_t? Тогда надо растянуть единичку из
0b00000001 11111111 11111111 11111111 это -1
         ^
этой позиции
на оставшиеся биты. Вроде как-то так:
uint32_t val; // тут хранится значение, которое надо перевести
bool is_signed = !!(val & (1 << SIGN_BIT_POS));
return  val | is_signed ? (0xFFFFFFFF << SIGN_BIT_POS) : 0;