![]() |
|
![]() ![]() ![]() |
|
underW |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 142 Регистрация: 22.9.2008 Репутация: нет Всего: 3 |
Если посмотреть любой язык программирования, то в нем переменная типа byte может содержать значение из диапазона от (-128) до (127) включительно.
Суть вопроса заключается в том, что как в 1байт (8 бит) впихивается число (-128)??? Если рассматривать прямой код, то в нем при 8 битах старший бит является знаковым, а остальные 7 бит отводятся для записи самого числа, при таком раскладе, максимальным положительным числом будет - 0|1111111 (127), максимальным отрицательным числом будет - 1|1111111 (-127). Становиться вполне очевидным, что при использовании прямого кода для записи чисел со знаком в 1байт можно поместить значение из диапазона (-127) до (127). Но, Архитектура х86 для записи отрицательных чисел использует так называемый дополнительный код (ДК). Получается, что при использовании именно ДК, мы можем работать с диапазоном от (-128) до (127). Самый популярный пример алгоритма перевода в ДК, который мне удалось нагуглить, заключаеться в следующем: Для перевода десятичного числа со знаком в двоичное необходимо сначала записать его в двоичном виде. Если число отрицательное, то нужно получить обратный код (1 заменить на 0 и наоборот) и прибавить единицу к полученному результату. или другими словами, более лаконично: 1. записать прямой код модуля числа; 2. инвертировать его (заменить единицы нулями, нули — единицами); 3. прибавить к инверсному коду единицу. Пример: двоичный код +11 инверсия +1 -11 ------------> 0000 1011 ----> 1111 0100 ---> 1111 0101 В приведенном примере дополнительным кодом числа 1110 является 11110101. Знаковый бит 1 означает, что рассматриваемое число отрицательно. Исходя из такого алгоритма, вообще становиться не понятным откуда берется ограничение на (-128): в 1 пункте сразу же сказано - записать прямой код модуля числа - в 1 байт влезет не то что модуль (-128) но и модуль (-255). Но если учесть ту особенность ДК при записи отрицательного числа, что знаковый бит всегда равен 1 и немного поэкспериментировав с ним, становится видно, что только при работе с отрицательными числами до (-128) включительно, знаковый бит равен 1, если ити дальше (-129), (-130) - то знаковый бит получаем 0, то есть мы наталкиваемся на ошибку. Неужели этим и объясняется диапазон от (-128) до (127)? А теперь гляну на еще один алгоритм определения ДК: то есть алгоритм остается тот же самый, только пример другой: Для числа -1101(-13): Прямой код 1|0001101 Обратный код 1|1110010 Дополнительный код 1|1110011 Судя из этого примера, ДК формируется на основе обратного кода, тот в свою очередь формируется на прямом коде. Посмотрим, как у нас записан прямой код: 1|0001101 - видим, что старший бит отведен для записи знака, остальные 7 - для записи самого числа, значит мы снова наталкиваемся на диапазон от (-127) до (127) и опять не можем вместить (-128). Вот собственно вопрос остается открытым, как же влазит (-128) и 1 байт? |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
0 1 2 3 .. 127 идут прямо
127=7fh=0111 1111b -128 - 127 -126 .. -1 80h 81h ... FFh Положительных чисел у нас 127 плюс ноль "0" и того 128 Отрицательных тоже 128 и того 256. В байт столько значений и входит. Секрет очень прост дело в том что в Прямой код есть "+0" и "-0" 0| 000 0000 1| 000 0000 А это расточительно поэтому "-0" можно использовать как еще одно число. |
|||
|
||||
underW |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 142 Регистрация: 22.9.2008 Репутация: нет Всего: 3 |
ааааага, все вот оно что, в дополнительном коде понятие (-0) вообще отсутствует, теперь все сходиться
![]() получаем следующую картину: есть у нас 1 байт - 8 бит, в этот объем мы можем запихнуть одно из 256 значений с диапазона [0-255] и это для безнаковых чисел. Для знаковых чисел мы определяем старший бит как знаковый и само число записываем в оставшиеся 7 бит, так как есть только 7 бит, значит к-во значений, которые мы можем записать ровно в 2 раза меньше от кого количества, когда мы работаем с 8 битами: 256/2=128; само число будет принадлежать диапазону [0-127]. При переходе к отрицательным числам, первое отрицательное число, на которое мы попадаем будет 1|000 0000 - то есть это (-0). Понятие отрицательного нуля (-0) так же как и положительного нуля (+0) существует в математике, но это все скорее некие абстракции и они нам не нужны ![]() Поэтому в ДК отрицательный ноль выбрасывается и даже не рассматривается, вместо него просто вводиться еще одно дополнительное число (-128). Вот как оно туда помещается и на выходе переменная типа byte вмещает в себя значение от (-128) до (127). Pavia, громадное спасибо за открытие секрета. P.S. Поставьте Pavia + в профиль, у меня нету 100 сообщений. Это сообщение отредактировал(а) underW - 26.9.2009, 19:34 |
|||
|
||||
dinrf |
|
|||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 17.10.2011 Репутация: нет Всего: нет |
Извините, что пишу не совсем по теме. Но вопрос затронул. Дело в том, что недавно делала контрольную другу по ЭВМ. и там было задание посчитать +36 -16 в допол. коде. Я последовала алгоритму .
1.записать прямой код модуля числа; 2. инвертировать его (заменить единицы нулями, нули — единицами); 3. прибавить к инверсному коду единицу. и в результате получила правильный ответ. Но когда стала объяснять другу, он сказал, что преподка сказала, что инвертировать - заменять единицы нулями, нули — единицами - это не правильно. посмотрела, в его конспекте и точно, там обратный код числа записан просто в ОБРАТНОМ порядке. попробовала считать по этому способу - ничего не вышло. И вот как доказать преподке, что она не права? Может я уже что-то путаю и инвертировать - это просто теперь записывают число в обратном порядке? ? ? ? ? |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 2 Всего: 85 |
Не совсем понятно что значит в обратном порядке, справа налево чтоли? В любом случае, ваш алгоритм правильный.
А преподы разные бывают. нарывался тоже на идиотов. Ничего им доказывать не надо. Бесполезно. Себе же хуже будет. |
||||
|
|||||
dinrf |
|
|||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 17.10.2011 Репутация: нет Всего: нет |
да, да. обратный порядок - справа налево
![]() я тоже думаю, что доказывать такой тупой нет смысла. Меня просто это так бесит. Как преподаватель может ошибаться и утверждать неправильное в таких простых вещах, это же не сложная какая-нибудь теорема. И тем более не хотелось бы подводить друга, ведь он ей будет сдавать контрольную. В любом случае спасибо за подтверждение. А то я уже подумала что с ума сошла или что-то кардинально поменялось в двоичном коде ![]() Это сообщение отредактировал(а) dinrf - 17.10.2011, 11:20 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |