Jump to content
  • 0

PHP. Двоичная система. Дополнительный код.


underW
 Share

Question

Если посмотреть любой язык программирования, в том числе и на PHP, то в нем переменная типа 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

В приведенном примере дополнительным кодом числа 1011 является 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 байт?

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

да, рассуждения кажутся логичными, но в твоих рассуждениях есть несколько фундаментальных ошибок:

1) с чего ты взял, что переменная, типа byte хранится в 1 байте? В пхп все переменные, типы которых отличны от float, strings, array и object хранятся в переменной типа long. Поэтому все ограничения таких переменных, связанны не с памятью, а сдругими вещами.

2) открою один большой секрет, который полностью выбивает опоры из твоих рассуждений. В пхп нет такого типа данных как byte (http://www.php.net/manual/en/language.types.php)

Link to comment
Share on other sites

  • 0

Поскольку институтская информатика была мной прогуляна, то точно ничего не знаю. Если действительно первый бит определяет знак, то мы имеем два варианта записи нуля (10000000 и 00000000) и один из вариантов вполне можно использовать для своих нужд, а другой для нуля. Вообще об этом задумываться следует в том случае, если нужно получить мизерную информацию (например, какие-нибудь 4 бита подтверждения при опросе оборудования), а для PHP это применять не стоит ибо нафиг

Link to comment
Share on other sites

  • 0

ну вообще то я согласен, если смотреть со стороны РНР - то это мой чистейший провал, согласен :)

Если смотреть со стороны фундаментального программирования, без привязки к конкретному языку - то все нормально :)

Veseloff, Вы абсолютно правы, все опирается в два варианта записи нуля.

На самом деле имеем такую картину:

есть у нас 1 байт - 8 бит, в этот объем мы можем запихнуть одно из 256 значений с диапазона [0-255] и это для безнаковых чисел.

Для знаковых чисел мы определяем старший бит как знаковый и само число записываем в оставшиеся 7 бит, так как есть только 7 бит, значит к-во значений, которые мы можем записать ровно в 2 раза меньше от кого количества, когда мы работаем с 8 битами: 256/2=128; само число будет принадлежать диапазону [0-127].

При переходе к отрицательным числам, первое отрицательное число, на которое мы попадаем будет 1|000 0000 - то есть это (-0).

Понятие отрицательного нуля (-0) так же как и положительного нуля (+0) существует в математике, но это все скорее некие абстракции и они нам не нужны smile

Поэтому в ДК отрицательный ноль выбрасывается и даже не рассматривается, вместо него просто вводиться еще одно дополнительное число (-128).

Вот как оно туда помещается и на выходе переменная типа byte вмещает в себя значение от (-128) до (127).

Все, вопрос решен.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy