Как сделать шестнадцатеричное число отрицательным
Основание этой системы счисления p равно шестнадцати. Эту систему счисления можно считать ещё одним вариантом записи двоичного числа. В этой системе счисления используется шестнадцать цифр. Здесь уже не хватает десяти цифр, поэтому приходится придумать недостающие шесть цифр.
Для обозначения этих цифр можно воспользоваться первыми буквами латинского алфавита. При записи шестнадцатеричного числа неважно буквы верхнего или нижнего регистра будут использоваться в качестве цифр. В качестве цифр в шестнадцатеричной системе используются символы 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
Так как здесь появляются новые цифры, то приведём таблицу соответствия этих цифр десятичным значениям.
Таблица 6. Таблица соответствия шестнадцатеричных цифр десятичным значениям
Шестнадцатеричная цифра | Десятичный эквивалент |
A | |
B | |
C | |
D | |
E | |
F |
Число в этой системе счисления записывается как сумма единиц, чисел шестнадцать, двести пятьдесят шесть и так далее. То есть веса соседних разрядов различаются в шестнадцать раз. Точно также записываются и числа, меньшие единицы. В этом случае разряды числа будут называться как шестнадцатые, двести пятьдесят шестые и так далее доли единицы.
Рассмотрим пример записи шестнадцатеричного числа:
Из приведённых примеров записи чисел в различных системах счисления вполне очевидно, что для записи одного и того же числа с одинаковой точностью в разных системах счисления требуется различное количество разрядов. Чем больше основание системы счисления, тем меньшее количество разрядов требуется для записи одного и того же числа.
Представление чисел в ЭВМ
Целые числа
Прямой код. Прямой код двоичного числа совпадает по изображению с записью самого числа. Значение знакового разряда для положительных чисел равно 0, а для отрицательных чисел 1.
Обратный код. Обратный код для положительного числа совпадает с прямым кодом. Для отрицательного числа все цифры числа заменяются на противоположные (1 на 0, 0 на 1), а в знаковый разряд заносится единица.
Дополнительный код. Дополнительный код положительного числа совпадает с прямым кодом. Для отрицательного числа дополнительный код образуется путем получения обратного кода и добавлением к младшему разряду единицы.
В любом представлении старший бит определяет знак числа:
0 - положительное число;
1 - отрицательное число
ПРИМЕР.
Прямой код | Обратный код | Дополнительный код |
0,0001101 | 0,0001101 | 0,0001101 |
Прямой код | Обратный код | Дополнительный код |
1,0001101 | 1,1110010 | 1,1110011 |
· Вещественные числа (числа с плавающей точкой)
Все равные по абсолютному значению положительные и отрицательные числа отличаются только этим битом. В остальном числа с разным знаком полностью одинаковы. Для представления отрицательных чисел здесь не используется дополнительный код.
Поле мантиссы содержит мантиссу нормализованного числа.
Одинарная точность:
1.(цифры мантиссы)*2 (P-127)
Двойная точность:
1.(цифры мантиссы)*2 (P-1023)
Расширенная точность:
1.(цифры мантиссы)*2 (P-16383)
ПРИМЕР.
Запишите код действительного числа, интерпретируя его как величину типа Double.
а) 446,15625;
Переводим десятичное число в двоичное представление.
Целая часть от деления | Остаток от деления |
446 div 2 = 223 | 446 mod 2 = 0 |
223 div 2 = 111 | 223 mod 2 = 1 |
111 div 2 = 55 | 111 mod 2 = 1 |
55 div 2 = 27 | 55 mod 2 = 1 |
27 div 2 = 13 | 27 mod 2 = 1 |
13 div 2 = 6 | 13 mod 2 = 1 |
6 div 2 = 3 | 6 mod 2 = 0 |
3 div 2 = 1 | 3 mod 2 = 1 |
1 div 2 = 0 | 1 mod 2 = 1 |
Остаток от деления записываем в обратном порядке. Получаем число в 2-ой системе счисления: 110111110
446 = 1101111102
Для перевода дробной части числа последовательно умножаем дробную часть на основание 2. В результате каждый раз записываем целую часть произведения.
0.15625*2 = 0.313 (целая часть 0)
0.313*2 = 0.626 (целая часть 0)
0.626*2 = 1.252 (целая часть 1)
0.252*2 = 0.504 (целая часть 0)
0.504*2 = 1.008 (целая часть 1)
Получаем число в 2-ой системе счисления: 00101
0.15625 = 001012
446.15625 = 110111110,001012 = 1,1011111000101*2 8
Знак S = 0
Порядок P = 8 + 1023 = 103110 = 100000001112
Мантисса: 1011111000101
Для числа с двойной точностью мантисса занимает 52 разряда. Добавляем нули.
Мантисса: 1011 1110 0010 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Запишем число:
0 10000000111 1011 1110 0010 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000
В шестнадцатеричной системе счисления: 407BE2800000000016
б) -455,375.
Переводим десятичное число в двоичное представление.
Целая часть от деления | Остаток от деления |
455 div 2 = 227 | 455 mod 2 = 1 |
227 div 2 = 113 | 227 mod 2 = 1 |
113 div 2 = 56 | 113 mod 2 = 1 |
56 div 2 = 28 | 56 mod 2 = 0 |
28 div 2 = 14 | 28 mod 2 = 0 |
14 div 2 = 7 | 14 mod 2 = 0 |
7 div 2 = 3 | 7 mod 2 = 1 |
3 div 2 = 1 | 3 mod 2 = 1 |
1 div 2 = 0 | 1 mod 2 = 1 |
Остаток от деления записываем в обратном порядке. Получаем число в 2-ой системе счисления: 111000111
455 = 1110001112
Для перевода дробной части числа последовательно умножаем дробную часть на основание 2. В результате каждый раз записываем целую часть произведения.
0.375*2 = 0.75 (целая часть 0)
0.75*2 = 1.5 (целая часть 1)
0.5*2 = 1 (целая часть 1)
0*2 = 0 (целая часть 0)
Получаем число в 2-ой системе счисления: 0110
0.375 = 01102
455,375 = 111000111,01102 = 1,110001110110*2 8 2
Знак S = 1
Порядок P = 8 + 1023 = 103110 = 100000001112
Мантисса: 1100 0111 0110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Запишем число:
1 10000000111 1100 0111 0110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
В шестнадцатеричной системе счисления: -455,375 = C07C76000000000016
Как предполагает заголовок, я пытаюсь преобразовать шестнадцатеричные числа, такие как 0x320000dd, в десятичные числа.
Мой код работает только для положительных чисел, но не работает, когда дело доходит до шестнадцатеричных чисел, которые представляют отрицательные десятичные числа. Вот выдержка из моего кода:
Мой ввод уже в шестнадцатеричном формате, и компьютер автоматически преобразует его в целое число. Я пытаюсь получить операнд шестнадцатеричного числа, то есть последние 24 бита.
Можете ли вы помочь мне заставить мой код работать для отрицательных значений, таких как: 0x32fffdc9 или 0x32ffffff? Большое спасибо!
Я хотел бы, чтобы мой вывод был:
0x32fffdc9 -> -567
или же
0x32ffffff -> -1
так что просто простые десятичные значения, но вместо этого он дает мне 16776649 и 16777215 для верхних примеров.
Решение
vector или же bitset может стоить вашего рассмотрения, так как они будут разъяснять шестнадцатеричные числа в диапазоне битов, которые будут установлены.
Прямой, дополнительный и обратный код числа (создан по запросу).
Далее идет калькулятор, который переводит введенное положительное или отрицательное целое число в двоичный код, а также выводит обратный код этого числа и его дополнительный код. Под калькулятором, как водится, немного теории.
Обновление: Из комментариев становится ясно, что люди не вполне понимают, что делает этот калькулятор. Точнее, что делал — применял алгоритм вычисления дополнительного кода к любому числу. Люди хотят, чтобы он им просто показывал дополнительный код числа. Ну хорошо — теперь при вводе положительного числа калькулятор показывает представление числа в двоичной форме, ибо для него нет обратного и дополнительного кода, а при вводе отрицательного показывает дополнительный и обратный код.
Прямой, дополнительный и обратный код
Прямой код числа это представление беззнакового двоичного числа. Если речь идет о машинной арифметике, то как правило на представление числа отводится определенное ограниченное число разрядов. Диапазон чисел, который можно представить числом разрядов n равен
Обратный код числа, или дополнение до единицы (one’s complement) это инвертирование прямого кода (поэтому его еще называют инверсный код). То есть все нули заменяются на единицы, а единицы на нули.
Дополнительный код числа, или дополнение до двойки (two’s complement) это обратный код, к младшему значащему разряду которого прибавлена единица
А это все для удобной работы со знаками. Поскольку я все люблю понимать на примерах, рассказывать я тоже буду на примерах. Итак, предположим, что у нас 4 разряда для работы с двоичными числами. Представить таким образом можно 16 чисел — 0, 1, . 15
00 — 0000
.
15 — 1111
Но если нет знака, убогая получается арифметика. Нужно вводить знак. Чтобы никого не обидеть, половину диапазона отдадим положительным числам (8 чисел), половину — отрицательным (тоже 8 чисел). Ноль, что отличает машинную арифметику от обычной, мы отнесем в положительные числа (в обычной арифметике у нуля нет знака, если не ошибаюсь). Итого, в положительные числа попадают 0. 7, а в отрицательные -1, . -8.
Для различия положительных и отрицательных чисел выделяют старший разряд числа, который называется знаковым (sign bit)
0 в этом разряде говорит нам о том, что это положительное число, а 1 — отрицательное.
С положительными числами все вроде бы понятно, для их представления можно использовать прямой код
0 — 0000
1 — 0001
7 — 0111
А как представить отрицательные числа?
Вот для их представления как раз и используется дополнительный код.
То есть, -7 в дополнительном коде получается так
прямой код 7 = 0111
обратный код 7 = 1000
дополнительный код 7 = 1001
Обратим внимание на то, что прямой код 1001 представляет число 9, которое отстоит от числа -7 ровно на 16, или .
Или, что тоже самое, дополнительный код числа "дополняет" прямой код до , т.е. 7+9=16
И это оказалось очень удобно для машинных вычислений — при таком представлении отрицательного числа операции сложения и вычитания можно реализовать одной схемой сложения, при этом очень легко определять переполнение результата (когда для представления получившегося числа не хватает разрядности)
Пара примеров
7-3=4
0111 прямой код 7
1101 дополнительный код 3
0100 результат сложения 4
Что касается переполнения — оно определяется по двум последним переносам, включая перенос за старший разряд. При этом если переносы 11 или 00, то переполнения не было, а если 01 или 10, то было. При этом, если переполнения не было, то выход за разряды можно игнорировать.
Примеры где показаны переносы и пятый разряд
00111 прямой код 7
00001 прямой код 1
01110 переносы
01000 результат 8 — переполнение
Два последних переноса 01 — переполнение
Два последних переноса 11 з перенос в пятый разряд можно отбросить, оставшийся результат, ноль, арифметически корректен.
Опять же проверять на переполнение можно простейшей операцией XOR двух бит переносов.
Вот благодаря таким удобным свойствам дополнительный код это самый распространенный способ представления отрицательных чисел в машинной арифметике.
The Flaming Lips - The Yeah Yeah Yeah Song (Официальное аудио)
Я только что научился читать шестнадцатеричные значения. До сих пор я считал их только положительными числами. Я слышал, что вы также можете писать отрицательные шестнадцатеричные значения.
Моя проблема в том, что Я не могу сказать, положительное или отрицательное значение. Я нашел несколько объяснений здесь и там, но если я попытаюсь проверить их, используя онлайн-преобразователи из шестнадцатеричного в десятичный, они всегда дают разные результаты.
Я прав? Если нет, не могли бы вы сказать, что я не понимаю?
- 9 Строго говоря, просто глядя на число, нельзя сказать, положительное оно или отрицательное; вам также необходимо знать, насколько широким должно быть число, и должно ли оно быть подписанным или беззнаковым.
- @ IgnacioVazquez-Abrams Хорошо, допустим, я знаю, что номер подписан 32 бита, правда ли то, что я утверждаю (выделено жирным шрифтом) в моем вопросе?
- 1 Это упрощено только достаточно, чтобы быть неточным. Вам нужно посмотреть бит n-1, где n - это размер бит, а крайний правый бит - это бит 0.
- @ IgnacioVazquez-Abrams Спасибо, теперь я вижу более ясно.
Еще одно преимущество этого представления (два дополнения) заключается в том, что вы получаете только одно представление для нуля, чего не было бы, если бы вы отметили числа со знаком, установив MSB или просто инвертируя их.
- но тогда почему шестнадцатеричный %p = 0x7ffc9f7662f0 , и то же, что и %d = -1619631376 , шестнадцатеричный код начинается с 7 , но отрицательный
Ответ здесь, на форуме, выглядит неплохо:
Вы можете определить, является ли шестнадцатеричное целое положительным или отрицательным, проверив его самую значительную (самую высокую) цифру. Если цифра - 8, число отрицательное; если цифра 7, число положительное. Например, шестнадцатеричный 8A20 отрицательный, а 7FD9 положительный.
Читайте также: