Если предположить, что ваш компьютер/компилятор использует двоичное дополнение (почти наверняка случай) и при условии, что вы хотите, чтобы результат в виде дополнения до двух.
Используйте знак uint8_t
, чтобы держать знак и величину величины.
Чтобы проверить, установлен ли бит, используйте побитовый оператор И &
вместе с битовой маской, соответствующей значению msb. Чтобы получить битовую маску, соответствующую бит n, сдвиньте влево значение 1 n раз. В C-коде:
#define SIGN (1 << 7)
uint8_t sm = ...;
if(sm & SIGN) // if non-zero, then the SIGN bit is set
{
}
else // it was zero, the SIGN bit is not set
{
}
Чтобы сделать фактическое преобразование, существует несколько способов. Я бы просто маскировать и скопировать соответствующие части числа, снова побитового И:
#define MAGNITUDE 0x7F
int8_t magnitude = sm & MAGNITUDE; // variable magnitude is two's compl.
EDIT полное решение (так как кто-то уже писал один):
#define SIGN (1 << 7)
#define MAGNITUDE 0x7F
uint8_t sm = ...;
int8_t twos_compl = sm & MAGNITUDE;
if(sm & SIGN) // if non-zero, then the SIGN bit is set
{
twos_compl = -twos_compl;
}
int8_t x = ...; // some other number in two's complement
int16_t result = twos_compl + x;
В качестве побочной заметки будьте очень осторожны при смешивании оператора ~
с малыми целыми типами, поскольку он выполняет неявное целочисленное продвижение. Например, uint8_t x = 1
, а затем ~my_uint8
дает вам 0xFFFFFFFE (32-битная система), а не 0xFE, как вы могли ожидать.
Для вышеуказанной задачи нет необходимости использовать ~
.
Пожалуйста, покажите свое усилие до сих пор. – Marievi
Хммм ... если последний бит в подписанной переменной равен 1, тогда 'x <0' должно быть истинным ... вам не нужно проверять конкретный бит. – Myst
Для этого вы можете использовать '&'. '0b01111111 & bits', таким образом, результат будет иметь восьмой бит, равный 0, независимо. – yeyo