#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 байта. Поскольку я больше ничего не знаю о вашем коде, я не могу делать больше предположений