Преобразование «shr» языка Pascal в «>>» языка C.

#c #bit-manipulation #pascal #bit-shift #shift

#c #манипулирование битами #паскаль #битовый сдвиг #сдвиг

Вопрос:

У меня возникла проблема с переводом некоторого кода на языке Pascal в C. По сути, у меня есть вложенные циклы, где цикл, увеличивающий «k», находится внутри цикла, увеличивающего «i». В обоих случаях я хочу выполнить команду «если i (сдвинут вправо на) k И 1 = 1, то выполните следующее {code}». В Pascal у меня есть:

 {Pascal Code}
...
for i:=0 to N-1 do begin j:=0; temp:=N/2;
for k:=0 to P-1 do begin if ((i shr k) and 1)=1 then...
  

Я знаю, что это работает. Я вывел данные из кода Pascal, и они верны, поэтому я предполагаю, что этот алгоритм — это то, что я хочу воспроизвести в C. В C у меня есть:

 /*C code*/
...
int i;
unsigned int k;
for(i=0;i<N;i  ){
   j=0;
   temp=N/2;
   for(k=0;k<P;k  ){
      if((unsigned int)i)>>kamp;amp;1==1){
          /*do code*/
      }
  

При отладке этих строк я записываю в файлы, которые показывают, каковы значения для Pascal «i shr k» и C «i>> k». Первые несколько строк этих файлов для каждого из них следующие:

 Pascal's "i shr k":
0
0
0
0
0
0
0
0
0
1...
  

Мои результаты C для «i>> k» таковы:

 C's "i>>k":
1
2
1
3
1
4
2
1
5
2...
  

Я также обнаружил, что в версии Pascal гораздо больше посещений внутренней части оператора «if» для заданного значения для i. Есть идеи о том, что здесь происходит? Я знаю, что «shr» в Паскале — это логический сдвиг, а «>>» в C — это арифметический сдвиг, но я подумал, что приведение типа (unsigned int) перед левым операндом «>>» исправит это? У кого-нибудь есть какие-либо советы о том, как сделать мой оператор C эквивалентным оператору Pascal? Это было бы очень оценено!

Спасибо за чтение!

Комментарии:

1. Почему вы выполняете приведение типов из int i в unsigned int i, когда вы можете просто преобразовать i в uint в первую очередь?

2.Подсказка: amp;amp; это логическая and операция. amp; является побитовым and .

3. Да, я это видел, но поскольку «и» в Паскале является логическим оператором, разве я не хотел бы использовать «amp;amp;» в C? И я знаю, что глупо набирать тип, мне это нравится, поэтому я просто собираюсь пойти дальше и изменить это сейчас … спасибо 🙂

4. вы упускаете из виду, что and в Pascal есть как логические, так и побитовые операторы

5. Я не вижу одинаковых отпечатков в моем тесте i>> k, я не уверен, как вы сгенерировали 1,2,1,3 … из i>> k.

Ответ №1:

Похоже, ваша проблема связана с прецедентом оператора.

В версии Pascal ваше условие таково:

 ((i shr k) and 1)=1
  

В версии C ваше условие таково (с добавлением некоторых скобок для отображения прецедента):

 (i >> k) amp;amp; (1==1)
  

Кроме того, amp;amp; это логический оператор, а не побитовый оператор. Эквивалентный побитовый оператор равен amp; . Если вы добавите несколько скобок и переключите операторы, вы должны получить то, что хотите:

 ((i >> k ) amp; 1) == 1
  

Комментарии:

1. 1 для разницы в приоритете операторов

2. Конечно, == 1 это тоже не обязательно.

3. Нет, но это довольно распространенное явление, потому что многие люди предпочитают явные, а не неявные преобразования в логическое значение по стилистическим соображениям.

4. Спасибо за совет! Имеет смысл. Однако код по-прежнему не работает, есть ли способ подтвердить, что этот код дает мне желаемые результаты по сравнению с моим кодом на языке Pascal? Используя тот же критерий, что и выше, когда я оцениваю «i>> k» в цикле, я получаю «1 1 3 1 1 5 1 3 1 7»

5. Сколько это P ? если вы сдвинулись на ширину i, то результат не определен msdn.microsoft.com/en-us/library/f96c63ed.aspx Другой возможной причиной может быть разница в размерах типов, если код Pascal взят из древнего DOS, тогда целое число равно 2 байтам, в то время как в большинстве современных операционных систем ПК оно составляет 4 байта. Поскольку я больше ничего не знаю о вашем коде, я не могу делать больше предположений