Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.09.2010, 12:48   #1
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию Битовый сдвиг

Вот код:
Код:
Var
   A:Integer;
   B:Integer;
Begin
     A:=-6;
     A:=A shl 1;
     B:=-6;
     B:=B shr 1;
     Writeln('A = ',A);
     Writeln('B = ',B);
     Readln;
End.
При битовом сдвиге числа А выдаёт -6(это правильно), а при битовом сдвиге числа В выдаёт 32567(это неправильно).Почему так?Должно ведь быть -3?
_-Re@l-_ вне форума Ответить с цитированием
Старый 09.09.2010, 12:52   #2
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,555
По умолчанию

Отрицательные числа в дополнительном коде: http://ru.wikipedia.org/wiki/%D0%94%...D0%BB%D0%B0%29
Arigato вне форума Ответить с цитированием
Старый 09.09.2010, 12:52   #3
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Странные резалты. При сдвиге влево должно получится A = -12 (shl 1 - это считай умножение числа на 2). А при сдвиге вправо в числе B должно быть -3 (shr 1 это считай деление на 2).

Код:
A = -12
B = -3
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 09.09.2010, 12:59   #4
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,555
По умолчанию

Получается следующее:
Код:
A = -12
B = 2147483645
Еще раз читаем ссылку, которую я привел:
Цитата:
Один и тот же регистр может хранить как n-битовое положительное число, так и (n−1)-битовое число со знаком, с общими для обоих форматов операциями сложения, вычитания и левого сдвига.
Arigato вне форума Ответить с цитированием
Старый 09.09.2010, 13:10   #5
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от Arigato Посмотреть сообщение
Получается следующее:
Код:
A = -12
B = 2147483645
Еще раз читаем ссылку, которую я привел:
Снимаю шляпу. Просто я все тестирую в Virtual Pascal, а он соответственно все интеджеры хранит в 2 байтах, а при операциях сдвига преобразует до 4 байт. Конечно переполнения по этому не происходит, так как movsx расширяет старшие разряды операнда назначения. Знак не теряется.
Код:
 0FBF059E344000               movsx     eax,w,[00040349E]
 D1E8                         shr       eax,1
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 09.09.2010, 13:30   #6
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Всё равно не получается.Пробовал так:
Код:
Var
   A:Integer;
   B:Integer;
Begin
     A:=-6;
     A:=((not a) or 128) + 1;
     A:=A shl 1;
     B:=((not B) or 128) + 1;
     B:=-6;
     B:=B shr 1;
     Writeln('A = ',A);
     Writeln('B = ',B);
     Readln;
End.
Выдаёт 268 и 32637.
_-Re@l-_ вне форума Ответить с цитированием
Старый 09.09.2010, 13:37   #7
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от _-Re@l-_ Посмотреть сообщение
Всё равно не получается.Пробовал так:
Попробуй как-то так
Код:
Var
   A:Integer;
   B:Integer;
Begin
     A:=-6;
     A:=a shl 1
     B:=-6;
     B:=not((not B) shr 1);
     Writeln('A = ',A);
     Writeln('B = ',B);
     Readln;
End.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 09.09.2010, 13:57   #8
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Работает.
Т.е. Битовый сдвиг влево нормально выполняется, а для битового сдвига вправо нужно так?
_-Re@l-_ вне форума Ответить с цитированием
Старый 09.09.2010, 14:03   #9
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,555
По умолчанию

Цитата:
Сообщение от _-Re@l-_
для битового сдвига вправо нужно так?
Тогда уж лучше так:
Код:
Var
   A:Integer;
   B:Integer;
Begin
     A:=-6;
     A:=a shl 1;
     B:=-6;
     asm
       sar B, 1
     end;
     Writeln('A = ',A);
     Writeln('B = ',B);
     Readln;
End.
Arigato вне форума Ответить с цитированием
Старый 09.09.2010, 14:10   #10
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Жаль, что я не знаю ассемблер.. Просто я пробовал его учить, только я его не понимаю..
_-Re@l-_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
битовый сдвиг WOWka777 Общие вопросы .NET 1 06.08.2010 17:13
сдвиг belii0987 Общие вопросы C/C++ 1 04.02.2010 16:05
Побитовый сдвиг Belii09878 Помощь студентам 10 02.02.2010 14:46
сдвиг по спирали shelest JavaScript, Ajax 0 06.12.2009 22:02
Сдвиг файла OrdJONY Общие вопросы Delphi 13 21.12.2007 22:22