Арифметический сдвиг влево: Арифметические операции с фиксированной точкой: Операции сдвига

Арифметические операции с фиксированной точкой: Операции сдвига

Операции сдвигов появились вместе с компьютерами. Они легко реализовываются на цифровых схемах и существуют практически на всех типах процессоров. В математике они заменяются операциями умножения и деления. Операции сдвигов удобно рассматривать на битовом представлении числа. При сдвиге все биты числа сдвигаются либо влево, либо вправо. Сдвиг на один бит влево равнозначен умножению на 2, сдвиг на один бит вправо равнозначен делению на 2. Есть отличия при операциях с беззнаковыми целыми числами и с целыми числами со знаком.

Логический (или беззнаковый) сдвиг влево

Логический сдвиг влево применяется при операциях над беззнаковыми целыми числами. При сдвиге влево все биты сдвигаются влево на один бит, старший бит отбрасывается, а в младший бит записывается 0. Если до операции в старшем бите была единица, то число после операции становится меньше исходного. В случае отбрасывания старшей единицы устанавливается флаг Carry.

Логический (беззнаковый) сдвиг вправо

Логический сдвиг вправо применяется при операциях над беззнаковыми целыми числами. При сдвиге вправо все биты сдвигаются вправо, отбрасывается младший бит, а в старший записывается 0. Если в младшем бите до операции была 1, то устанавливается флаг Carry.

Арифметический (для чисел со знаком) сдвиг вправо

Арифметический сдвиг вправо применяется при операциях со знаковыми целыми числами. При сдвиге вправо все биты сдвигаются вправо, отбрасывается младший бит, а старший бит дублируется, тем самым сохраняя знак. Арифметический сдвиг вправо равнозначен выполнению операции деления на 2.

Арифметический (для чисел со знаком) сдвиг влево

Арифметический сдвиг влево применяется при операциях со знаковыми целыми числами. При сдвиге влево все биты сдвигаются влево на один бит, старший бит отбрасывается, а в младший бит записывается 0. Если при сдвиге влево изменяется знаковый бит (с 1 на 0 или с 0 на 1), то происходит ситуация насыщение — устанавливается флаг Overflow и значение результата заменяется на максимальное целое число в случае, если до начала операции число было положительное или на минимальное целое, если до начала операции число было отрицательным. Арифметический сдвиг влево равнозначен выполнению операции умножения на 2.

Примеры

Рассмотрим использование арифметических и логических сдвигов. Для рассмотрения примеров выберем формат представления fractional данных.

Формат данных (Qm.n)
Общее количество бит (b) 8 16 24
Количество бит для целой части (m)
Количество бит для дробной части (n)

Введем произвольное значение вещественного числа в формате float-point. После введения, число автоматически конвертируется в формат fractional и его бинарное представления. Если исходное вещественное число выходит за пределы допустимого представления в формате fractional, то оно будет автоматически приведено к допустимым пределам. Например, попробуйте ввести 1 при выбранном формате Q1.15.

Сдвиги
Арифметический сдвиг
Логический сдвиг
Float-Point
Fractional16
Fractional2
Флаги
OverflowCarry

§28.

Операции с целыми числами

Планирование уроков на учебный год (по учебнику К.Ю. Полякова, Е.А. Еремина, полный углубленный курс, 4 часа в неделю)

Главная | Информатика и информационно-коммуникационные технологии | Планирование уроков и материалы к урокам | 10 классы | Планирование уроков на учебный год (по учебнику К.Ю. Полякова, Е.А. Еремина, полный углубленный курс, 4 часа в неделю) | Арифметические и логические (битовые) операции. Маски







Содержание урока

§26. Особенности представления чисел в компьютере
§27. Хранение в памяти целых чисел
§28. Операции с целыми числами

Сложение и вычитание

Умножение и деление

Сравнение

Поразрядные логические операции

Сдвиги

Вопросы и задания

Задачи

§29. Хранение в памяти вещественных чисел

Сдвиги

Об операции сдвига вспоминают гораздо реже, чем она того заслуживает. Перечитайте ещё раз алгоритм умножения, описанный выше, и вы убедитесь, что он весь построен на сдвигах. Сдвиги незаменимы тогда, когда требуется проделать ту или иную обработку каждого бита, входящего в число. Наконец, сдвиги двоичного числа позволяют быстро умножить или разделить число на степени двойки: 2, 4, 8 и т. д. Поэтому программисты очень ценят и широко применяют всевозможные разновидности сдвигов.

Идея операции сдвига довольно проста: все биты кода одновременно сдвигаются в соседние разряды

1 влево или вправо (рис. 4.16).


1 Аппаратно сдвиг реализуется необычайно просто и изящно: регистр, содержащий число, сбрасывается в ноль, при этом из тех разрядов, где исчезла единица, электрический импульс проходит в соседние и устанавливает их в единицу. При этом важно, что все разряды обрабатываются одновременно.


Рис. 4.16

Отдельно надо поговорить о двух крайних битах, у которых «нет соседей». Для определённости обсудим сдвиг влево. Для самого младшего бита (на рис. 4.16 он крайний справа) данные взять неоткуда, поэтому в него просто заносится ноль. Самый старший (крайний слева) бит должен потеряться, так как его некуда сохранить. Чтобы данные не пропали, содержимое этого разряда копируется в специальную ячейку процессора — бит переноса

2 С (от англ, carry — перенос), с которым может работать процессор.


2 При программировании на языках высокого уровня бит переноса недоступен.


Рассмотренный тип сдвига обычно называется логическим сдвигом. Его можно использовать для быстрого умножения и деления. Рассмотрим, например, 8-разрядный двоичный код 0000 1100, который представляет число 1210. Выполнив логический сдвиг влево, получим 0001 1000, т. е. число 2410, которое вдвое больше! Это не случайность: вспомните, что происходит, если к десятичному числу справа приписать дополнительный ноль, например 34 -> 340.

При сдвиге вправо любое чётное число уменьшается ровно в 2 раза. В случае нечётного значения происходит деление нацело, при котором остаток отбрасывается. Например, из 0001 0001 = 17

10 при сдвиге вправо получается 0000 1000 = 810.

Логический сдвиг влево на 1 разряд увеличивает целое положительное число вдвое, а сдвиг вправо делит на 2 нацело.

Пример. Для умножения числа, находящегося в ячейке Z, на 10 можно использовать такой алгоритм:

1. Сдвиг влево Z (в ячейке Z получаем 2Z0, где Z0 — исходное число).

2. X = Z (сохраним 2Z0).

3. Сдвиг на 2 бита влево X (вычислили 8Z0).

4. X = X + Z (X = 8Z0 + 2Z0 = 10Z0).

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

Посмотрим, что получится для отрицательных чисел. Сдвинем влево код 1111 1000 (8-разрядное представление числа —8):

получится 1111 0000. Легко проверить, что это дополнительный код числа -16, т. е. значение удвоилось! Но со сдвигом вправо ничего не получается: из 1111 1000 получаем 0111 1100 — это код положительного числа! Дело в том, что при сдвиге вправо отрицательных чисел, в отличие от положительных, старший разряд надо заполнять не нулём, а единицей! Чтобы исправить положение, вводится ещё одна разновидность сдвига — арифметический сдвиг. Его единственное отличие от логического состоит в том, что старший (знаковый) бит не меняется, т. е. знак числа остаётся прежним (рис. 4.17).

Рис. 4.17

Если применить арифметический сдвиг к коду 1111 1000, получается 1111 1100 — дополнительный код числа -4, т. е. произошло деление на 2. В качестве упражнения проверьте, как ведёт себя отрицательное нечётное число при арифметическом сдвиге вправо.

Арифметический сдвиг влево не требуется, поскольку он ничем не отличается от обычного логического сдвига.

То, что в результате логических сдвигов содержимое крайних разрядов теряется, не всегда удобно. Поэтому в компьютере предусмотрен циклический сдвиг, при котором бит из одного крайнего разряда переносится в другой («по циклу», рис. 4.18).

Рис. 4.18

Циклический сдвиг позволяет «просмотреть» все биты и вернуться к исходному значению. Если сделать последовательно 8 циклических сдвигов 8-битного числа, каждый его бит на каком-то шаге окажется на месте младшего разряда, где его можно выделить с помощью логической операции «И» с маской 1. Так можно «просматривать» не только младший, но и любой другой разряд (например, для выделения старшего разряда нужно использовать маску 8016).

Следующая страница Вопросы и задания

Cкачать материалы урока





java — Что такое арифметический сдвиг влево 01001001?

спросил

Изменено 1 год, 11 месяцев назад

Просмотрено 25 тысяч раз

Я думаю, что это 00010010 то есть он пытается сохранить бит знака как

С другой стороны, логический сдвиг влево на 1 позицию будет 10010010

Это правильно?

  • java
  • бит-манипуляция
  • бит-сдвиг
2

Для сдвига влево арифметический и логический сдвиг одинаковы.

Различие только для сдвига вправо, где арифметический сдвиг вправо скопирует старый старший бит в новый старший бит после сдвига, тем самым предотвращая преобразование отрицательного числа в положительное при сдвиге.

В Википедии есть более подробное объяснение.

В Java << — это логический сдвиг влево. 0 всегда добавляется как LSB. " 1".)

Однако в статье Википедии об арифметическом сдвиге указано, что арифметический сдвиг влево может привести к ошибке переполнения:

... 9п) . Итак, в вашем примере ar-left-shift 01001001 на 1 место равно 10010010 (73 * 2¹ = 146).

Вы правы, когда смещаете влево на 1 бит. Это равно 10010010.

, когда вы сдвинете 4 бита влево следующим образом, вы получите следующий ответ.

 01001001 << 4 = 10010000
 

при сдвиге на 4 бита вправо следующим образом вы получите следующий ответ.

 01001001 >> 4 = 00000100
 

Биты, оставшиеся пустыми в результате сдвига, заполняются нулями.

0

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.

Вопрос по арифметическому оператору сдвига вправо

спросил

Изменено 2 года, 6 месяцев назад

Просмотрено 121 раз

У меня небольшие проблемы с обдумыванием этой конкретной операции-
0x44 >> 3
Где >> — арифметический оператор сдвига вправо.
Теперь учебник, на который я ссылаюсь, дает ответ как 1110 1000
Однако я сделал это следующим образом:
0x44 => 0100 0100
Теперь, поскольку первый бит равен нулю, я вычислил результат арифметического сдвига вправо как

0000 1000 (шестнадцатеричное значение 0x08)
Но книга дает ответ как 1110 1000 (шестнадцатеричное значение 0xE9 )
Что я здесь делаю не так? (Книга CS:APP, практическая задача 2.16 для желающих).

  • операторы
  • побитовые операторы
  • битовый сдвиг

Насколько я могу судить, это практическая задача 2.16 из глобального издания Computer Science: A Programmer's Perspective (3-е издание), которое согласно оригинальные авторы полны ошибок.

Прямая цитата со страницы с ошибками:

Примечание к Global Edition: К сожалению, издатель устроил генерацию другого набора практики и домашних заданий проблемы в глобальном издании. Человек, делающий это, не очень хорошая работа, и поэтому эти проблемы и их решения имеют много ошибок. Мы не создавали опечатки для этого издания.

Судя по всему, в сети можно найти североамериканское издание, если вы заинтересованы в выполнении практических и домашних заданий.

Ваш ответ действительно правильный:

 0x44 >> 3 == 0x08
 
3

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Обязательно, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *