Как сделать число отрицательным в двоичной системе
Мои мысли: если кто-то объявляет int , он в основном получает unsigned int . Поэтому, если мне нужно отрицательное значение, я должен явно создать подписанный int.
Так я ошибаюсь, что целое число со знаком в двоичном формате является отрицательным значением?
Как я могу создать отрицательное значение в двоичном формате?
Редактировать Даже если я использую 16/32/64 бит, я получаю тот же результат. unsigned/signed , кажется, не имеет значения без ручного сдвига битов.
int является всегда signed , поэтому в вашем примере нет разницы между a и b . Наиболее распространенный способ представления целочисленных типов со знаком — дополнение до двух, поэтому, пожалуйста, узнать больше об этом.
Some programmer dude
-10 в двойке - это leading ones. 11110110 . почему вы ожидаете, что 0b10000101 будет -10?
chux - Reinstate Monica
Ответы 4
Имейте в виду, что в зависимости от вашей цели int может иметь размер 2 или 4 байта. Это означает, что int a=0b10000101 недостаточно бит для установки знакового бита.
Если ваш int имеет размер 4 байта, вам нужен 0b10000000 0000000 0000000 00000000 (для ясности добавлены пробелы).
Например, на 32-битной цели:
Посмотрите мой обновленный пример, убедитесь, что у вас правильное количество бит. Двойной счет, если необходимо, легко ошибиться.
О, хорошо, я подумал, что мне не нужно выполнять двоичную операцию (переворачивать биты), если я объявлю подписанный или неподписанный? Так зачем его использовать?
int по умолчанию является signed , вам нужно только указать unsigned . также имейте в виду, что для печати без подписи вам нужно использовать %u .
@StrangerThings это означает, что значения могут быть отрицательными или положительными, без знака означает, что у вас есть только положительные числа.
Нет, подписанный не означает отрицательный. Подробнее о подписанный против неподписанного
потому что int a = 0b10000101 имеет только 8 бит, а вам нужно 16 или 32. Попробуйте:
это должно создать отрицательное число, если ваша машина 32-битная. Если это не работает, попробуйте:
есть и другие способы получения отрицательных чисел:
или если у вас 16 битная система
или этот будет работать как для 32, так и для 16 бит
или это еще один, который будет работать на обоих, если вы хотите получить -5
поэтому 0b101 - это 5 в двоичном формате, ~0b101 дает -6 , поэтому, чтобы получить -5 , вы добавляете 1
Обновлено: Поскольку теперь я вижу, что у вас есть путаница в том, что такое знаковые и беззнаковые числа, я постараюсь объяснить это как можно проще int
Итак, когда у вас есть:
и оба они будут положительными. Теперь это было бы так же, как:
потому что 5 является положительным числом.
С другой стороны, если у вас есть:
это было бы то же самое, что
но это не будет таким же, как следующее:
первый 2 будет -5 , третий уже не тот. На самом деле было бы то же самое, если бы вы ввели 4294967291 , потому что они одинаковы в двоичной форме, но тот факт, что вы указали unsigned впереди, означает, что компилятор сохранит его таким же образом, но обработает его как положительное значение.
Это не работает, но ответ ODYN-Kon сработал для меня. Но я ожидал того же, что и вы. Конечно, сдвиг битов работает, как и ожидалось, но я спрашивал об использовании со знаком/без знака.
Все ваши первые четыре примера связаны с неопределенным поведением в отношении языка C. Кроме того, C определяет эффект присвоения отрицательного значения целому числу без знака таким образом, который не зависит от представления. В результате нет будет иметь одно и то же представление на знаке/величине или машине дополнения — и то, и другое явно разрешено C — не то чтобы вы, вероятно, действительно столкнетесь с такой машиной.
@JohnBollinger, так что я получил вторую часть, и вы правы. Я совсем забыл об этом. Но почему неопределенное поведение? Другое дело, что я стремлюсь иногда упростить вещи для начинающих.
@Gox, константы положительные. Присвоение большой положительной константы целому числу со знаком, чтобы вызвать переполнение, приводит к неопределенному поведению. Точно так же сдвиг влево целого числа со знаком (включая целочисленную константу со знаком), математический результат которого выходит за пределы допустимого диапазона для типа, также приводит к неопределенному поведению.
@JohnBollinger спасибо за ваш вклад. Я узнал, что вы говорите. Я могу сказать, что я узнал немного здесь.
Если числа представлены в виде дополнения до двух, вам просто нужно установить бит знака, чтобы число было отрицательным. Это МСБ. Если int является 32-битным, то 0b11111111111111111111111111111111 — это -1 , а 0b10000000000000000000000000000000 — это INT_MIN .
Чтобы настроить размер int(8|16|64)_t , просто измените количество бит. Бит знака по-прежнему является MSB.
How to create a negative binary number using signed/unsigned in C?
Просто инвертируйте константу положительного значения. Чтобы попытаться сделать это с many 1's . 1110110 , предполагается, что int имеет разрядность. Лучше быть портативным.
ПРР222 Комментарии (2)
какое это имеет отношение к подписанному/неподписанному заявлению?
Дополнительный код (англ. two’s complement , иногда twos-complement) — наиболее распространённый способ представления отрицательных целых чисел в компьютерах. Он позволяет заменить операцию вычитания на операцию сложения и сделать операции сложения и вычитания одинаковыми для знаковых и беззнаковых чисел, чем упрощает архитектуру ЭВМ. Дополнительный код отрицательного числа можно получить инвертированием модуля двоичного числа (первое дополнение) и прибавлением к инверсии единицы (второе дополнение), либо вычитанием числа из нуля.
Дополнительный код (дополнение до 2) двоичного числа получается добавлением 1 к младшему значащему разряду его дополнения до 1. [1]
Дополнение до 2 двоичного числа определяется как величина полученная вычитанием числа из наибольшей степени двух (из 2 N для N-битного дополнения до 2).
Содержание
Представление отрицательного числа в дополнительном коде
При записи числа в дополнительном коде старший разряд является знаковым. Если его значение равно 0, то в остальных разрядах записано положительное двоичное число, совпадающее с прямым кодом. Если число, записанное в прямом коде, отрицательное, то все разряды числа инвертируются, а к результату прибавляется 1. К получившемуся числу дописывается старший (знаковый) разряд, равный 1.
Десятичное представление | Код двоичного представления (8 бит) | ||
---|---|---|---|
прямой | обратный | дополнительный | |
127 | 01111111 | 01111111 | 01111111 |
1 | 00000001 | 00000001 | 00000001 |
0 | 00000000 | 00000000 | 00000000 |
-0 | 10000000 | 11111111 | --- |
-1 | 10000001 | 11111110 | 11111111 |
-2 | 10000010 | 11111101 | 11111110 |
-3 | 10000011 | 11111100 | 11111101 |
-4 | 10000100 | 11111011 | 11111100 |
-5 | 10000101 | 11111010 | 11111011 |
-6 | 10000110 | 11111001 | 11111010 |
-7 | 10000111 | 11111000 | 11111001 |
-8 | 10001000 | 11110111 | 11111000 |
-9 | 10001001 | 11110110 | 11110111 |
-10 | 10001010 | 11110101 | 11110110 |
-11 | 10001011 | 11110100 | 11110101 |
-127 | 11111111 | 10000000 | 10000001 |
-128 | --- | --- | 10000000 |
Дополнительный код для десятичных чисел
Тот же принцип можно использовать и в компьютерном представлении десятичных чисел: для каждого разряда цифра X заменяется на 9−X, и к получившемуся числу добавляется 1. Например, при использовании четырёхзначных чисел −0081 заменяется на 9919 (9919+0081=0000, пятый разряд выбрасывается).
При применении той же идеи к привычной 10-ричной системе счисления получится (например, для гипотетического процессора использующего 10-ричную систему счисления):
10-ричная система счисления ("обычная" запись) | 10-ричная система счисления, дополнительный код |
---|---|
. | . |
13 | 0013 |
12 | 0012 |
11 | 0011 |
10 | 0010 |
9 | 0009 |
8 | 0008 |
. | . |
2 | 0002 |
1 | 0001 |
0 | 0000 |
-1 | 9999 |
-2 | 9998 |
-3 | 9997 |
-4 | 9996 |
. | . |
-9 | 9991 |
-10 | 9990 |
-11 | 9989 |
-12 | 9988 |
. | . |
Преобразование в дополнительный код
Преобразование числа из прямого кода в дополнительный осуществляется по следующему алгоритму.
- Если число, записанное в прямом коде, положительное, то к нему дописывается старший (знаковый) разряд, равный 0, и на этом преобразование заканчивается;
- Если число, записанное в прямом коде, отрицательное, то все разряды числа инвертируются, а к результату прибавляется 1. К получившемуся числу дописывается старший (знаковый) разряд, равный 1.
Пример. Преобразуем отрицательное число −5, записанное в прямом коде, в дополнительный. Прямой код числа −5, взятого по модулю:
Инвертируем все разряды числа, получая таким образом обратный код:
Добавим к результату 1
Допишем слева знаковый единичный разряд
Для обратного преобразования используется тот же алгоритм. А именно:
Инвертируем все разряды числа, получая таким образом обратный код:
Добавим к результату 1 и проверим, сложив с дополнительным кодом
p-адические числа
В системе p-адических чисел изменение знака числа осуществляется преобразованием числа в его дополнительный код. Например, если используется 5-ричная система счисления, то число, противоположное 1000. (1) равно 4444. (−1).
Читайте также: