Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Первые шаги в программировании: основы, Си, Objective-c


1.14
Математические операции с двоичными числами


Сейчас мы разберемся со следующими моментами:

1 - сложение двоичных чисел "столбиком" (поразрядное сложение двоичных чисел с переносом)
2 - умножение «столбиком»
3 - умножение посредством сдвига (влево)
4 - отрицательное число
5 - перевод положительного числа в отрицательное.
6 - вычитание двоичных чисел (столбиком)



1

Поразрядное сложение двоичных чисел с переносом



В данном случае сложение производится как и обычные десятичные числа в столбик.
Если складываем 0 и 1 - получается 1
Если складываем 1 и 1 - получается 0 и единица переходит в старший разряд (влево) где складывается со следующим значением.

Примеры показаны для беззнаковых чисел, в которых старший разряд (крайний левый) не является показателем знака.

+ 0 0 1 0   ( 210 )
1 0 1 1 ( 1110 )
1 1 0 1 ( 1310 )


Переполнение
Здесь в качестве примера показано сложение двух двоичных чисел ( в десятичном эквиваленте 15 + 1 )в результате которого происходит "переполнение" ячейки памяти в результате которого результат будет не таким, как ожидалось.
+ 1 1 1 1   ( 1510 )
0 0 0 1 ( 110 )
1 0 0 0 0 0



Другой пример переполнения памяти, когда результатом сложения двух чисел будет 3, а не 19.
Это происходит потому что в четырех битах максимальное число равно 1510 = 11112.
Число 19 не помещается туда физически, как и в примере выше.

+ 1 1 1 0   ( 1410 )
1 0 1 ( 510 )
1 0 0 1 1 ( 310 )




2

Умножение «столбиком»



Показан просто пример исполнения - без учета знака числа.
Умножение производится по тому же принципу что и для обычных десятичных чисел.
Умножение на ноль дает единицу, а умножение единицы на единицу дает, естественно, тоже единицу.

После перемножения производится сложение для получения общего результата.

Пример умножения «столбиком» 1110 x 101 - в десятичном представлении - 14 x 5 = 70:

64 32 16 8 4 2 1
26 25 24 23 22 21 20
× 1 1 1 0
1 0 1
+ 1 1 1 0
1 1 1 0
1 0 0 0 1 1 0




3

Умножение посредством сдвига (влево)




Сдвиг - простыми словами это перенос числа влево (в сторону старшего разряда). При этом в младший разряд записывается 0.

Пример:
имеем число 00112 (это у нас 310)

0 0 1 1


Сдвигаем его влево и получаем такое число:

0 1 1 0


Это уже число 610

Что произошло при сдвиге?
Произошло обычное УМНОЖЕНИЕ на 2!
Было 3 - стало 6

Давайте сдвинем это число еще раз:
Имеем:

0 1 1 0


Сдвигаем его влево и получаем:

1 1 0 0


Если перевести это число в десятичную систему, то получим число 1210
Если это число снова подвергнуть сдвигу, то результатом будет переполнение.

Следует заметить, что операция сдвига осуществляется намного быстрее, чем операция умножения (или деления)

Следует запомнить, что:
- производя сдвиг влево на ОДИН РАЗРЯД мы производим умножение на 2
- производя сдвиг влево на ДВА РАЗРЯДА мы производим умножение на 4
- производя сдвиг влево на ТРИ РАЗРЯДА мы производим умножение на 8 и т.д.


Сдвиг можно осуществлять и вправо
- в этом случае при сдвиге на 1 разряд будет производиться деление на 2,
- сдвигая вправо на 2 разряда будет производиться деление на 4 и т.д...


Что самое интересное, сдвиг можно производить и с десятичными числами!
Взять то же число 1010 и сдвинуть его влево - т.е. мы присоединяем дополнительный 0 со стороны младшего разряда. Получается 10010
В основе сдвига операция производится с основой системы счисления к которой относится число, над которым проводятся операции сдвига.

[url=http://www.tryobj.com/15-python.html]В Терминале при помощи Python'а[/url] можно также производить операцию сдвига применительно к числам.

Производится эта операция посредством оператора:
- "<<" для сдвига влево
- ">>" для сдвига вправо


Если применять сдвиг к десятичным числам в Питоне, то операция производится путем битового сдвига, т.е. происходит преобразование десятичного числа в двоичное, далее применяется сдвиг и полученное число снова преобразуется в десятичное.

Т.е. если мы наберем в Терминале:
6 << 1 # сдвигаем 6 влево на один разряд

То получим 12, т.е. произошло умножение на 2

Если полученное число 12 сдвинуть влево на один разряд еще раз
12 << 1

Получим 24

Соответственно при сдвиге вправо происходит деление:
Сдвинем десятичное число 24 вправо на один разряд
24 >> 1

Получим - 12

Чтобы применить сдвиг к другой системе счисления, необходимо использовать соответствующую запись.
Например для двоичного числа:
0b0011 << 1

В результате получаем 6
Двоичная форма записи после сдвига преобразовывается в десятичное.



4

Отрицательное число



Это числа меньше нуля, записываются с приставкой "-" перед числом...
Определение отрицательного числа: при наличии положительного числа "a" при сложении такого же отрицательного числа дает в результате НОЛЬ, т.е. при взаимном сложении они "уничтожаются"

Для двоичного формата это утверждение также справедливо

Естественно данные примеры производятся над ЗНАКОВЫМИ числами, в которых старший разряд отведен под указание того, какой знак у числа.
При программировании мы как правило всегда знаем с какого типа данными мы работаем - со знаковыми или беззнаковыми...
В основном, в языках программирования производится так называемое "объявление" переменной, когда мы явным образом указываем с каким типом чисел (в данном случае) мы будем работать.
При объявлении числа типом int - мы будем работать со знаковыми числами, а если число объявить как unsigned int - тогда число будет восприниматься беззнаковым (без какого либо указания на знак в старшем бите).
По умолчанию - числа используются со знаком. Если нам необходимо работать с беззнаковими числами, то мы это должны указать явно.


Если знаковое число +1 в двоичном формате прибавить к -1, то должен получиться ноль (результат будет с переполнением)

+ +/- знак числа
0 0 0 1 110
1 1 1 1 -110
1 0 0 0 0 010


Еще пример

+ +/- знак числа
0 0 1 1 310
1 1 0 1 -310
1 0 0 0 0 010


И еще один пример

+ +/- знак числа
0 1 0 1 510
1 0 1 1 -510
1 0 0 0 0 010


Ознакомиться с полной новостью на www.tryobj.com


В избранное