реклама на сайте
подробности

 
 
> Последовательность действий - побитовая инверсия и сдвиг, (~PIND) >> 4 == ~(PIND >> 4) ???
Dx!
сообщение Sep 28 2010, 16:15
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Компилятор WinAVR-20090313

Неужели ((~PIND) >> 4) и (~(PIND >> 4)) должны давать одинаковый результат?

PIND у меня равен 0b1110????

~(PIND >> 4) получается 0b11110001 как и должно быть.

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

Я ошибаюсь?
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 14)
IgorKossak
сообщение Sep 28 2010, 16:20
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Как определён Ваш PIND?
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 28 2010, 16:53
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Dx! @ Sep 28 2010, 20:15) *
PIND у меня равен 0b1110????

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

PIND равен 00001110. После инвертирования получится 11110001. А если учесть, что компилятор в выражениях расширяет операнды до int, то единиц будет еще больше. Ну и сдвиг на 4 с расширением знака даст все единицы, причем в обоих случаях. Как у тебя получилось что-то другое - хз
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 28 2010, 17:35
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Под ???? подразумевались недостающие четыре бита?
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 28 2010, 17:35
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Нормальные компиляторы на такой оператор выдают предупреждение или ремарку. Например, IAR "ругается" таким образом
Цитата
Remark[Pa091]: operator operates on value promoted to int (with possibly unexpected result)

Если уж приспичило писать именно так, а не другим способом инвертировать биты, то наложите байтовую маску после инвертирования, но до сдвига.
Go to the top of the page
 
+Quote Post
Dx!
сообщение Sep 28 2010, 18:10
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Цитата(IgorKossak @ Sep 28 2010, 20:20) *
Как определён Ваш PIND?

Он не мой - это регистр ввода с порта.

Цитата(777777 @ Sep 28 2010, 20:53) *
PIND равен 00001110. После инвертирования получится 11110001. А если учесть, что компилятор в выражениях расширяет операнды до int, то единиц будет еще больше. Ну и сдвиг на 4 с расширением знака даст все единицы, причем в обоих случаях. Как у тебя получилось что-то другое - хз

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

Код
temp = PIND;
temp = ~temp;
SomeVar = temp >> 4;

Работает адекватно.

Цитата(IgorKossak @ Sep 28 2010, 21:35) *
Под ???? подразумевались недостающие четыре бита?

Любые биты, в данном случае не имеющие значения и ничего не меняющие.

Цитата(rezident @ Sep 28 2010, 21:35) *
Нормальные компиляторы на такой оператор выдают предупреждение или ремарку. Например, IAR "ругается" таким образом

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

И что мне это даст?
Гораздо проще
Код
((~PIND) >> 4) & 0xf;

Но вопрос в другом - мне казалось что сначала должна была быть инверсия, потом сдвиг. Я не прав? Или данная конструкция что-то нарушает и не может быть применена?
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 28 2010, 18:54
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Dx! @ Sep 29 2010, 00:10) *
И что мне это даст?
Гораздо проще
Код
((~PIND) >> 4) & 0xf;
У вас то же самое, что я предлагаю, но по-моему более корректно будет
Код
(((~PIND)&0xFF)>>4)

Цитата(Dx! @ Sep 29 2010, 00:10) *
Но вопрос в другом - мне казалось что сначала должна была быть инверсия, потом сдвиг. Я не прав? Или данная конструкция что-то нарушает и не может быть применена?
Все правильно, инверсия, а потом сдвиг. Только перед инверсией беззнаковая переменная типа volatile unsigned char преобразуется в переменную типа signed int и только потом инвертируется и сдвигается сообразно правилам сдвига для знаковой переменной. Если вы хотите работать именно с байтовой переменной, то пишите
Код
((PIND^0xFF) >> 4)
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 28 2010, 19:04
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Dx! @ Sep 28 2010, 20:15) *
Компилятор WinAVR-20090313

Неужели ((~PIND) >> 4) и (~(PIND >> 4)) должны давать одинаковый результат?

PIND у меня равен 0b1110????

~(PIND >> 4) получается 0b11110001 как и должно быть.

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

Я ошибаюсь?

Разбираем по шагам:
PIND = 0b1110**** (PIND это 8 битное число)
результат инвертирования (почему смотри ниже) будет иметь тип int (в avr-gcc тип int это знаковое 16 битное число). поэтому 8 битное беззнаковое число будет расширено до знакового 16 битного
~PIND == ~(0b00000000 1110****) == 0b11111111 0001***
(~PIND) >> 4 с правой стороны этого выражения числовая константа (без явного указания типа), а по стандарту си она должна интерпретироваться как тип int. При операции сдвига меньший операнд по стандарту си должен быть расширен до бОльшего (именно по этой причине компилятор делал инвертирование в 16 битах). т.е. имеем: (~PIND) >> 4 == 0b11111111 0001**** >> 4 == 0b11111111 11110001
итого, если результат приводится к 8ми битному типу то должно получиться 0b11110001.
Если это не так, то надо более точно разбираться.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 28 2010, 19:15
Сообщение #9


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Petka @ Sep 28 2010, 22:04) *
Если это не так, то надо более точно разбираться.

Вот я и пытаюсь добиться определения PIND в WinAVR ибо "Он не мой - это регистр ввода с порта." это не определение на языке C. Отсюда и плясать надо.
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 28 2010, 19:18
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(IgorKossak @ Sep 28 2010, 23:15) *
Вот я и пытаюсь добиться определения PIND в WinAVR ибо "Он не мой - это регистр ввода с порта." это не определение на языке C. Отсюда и плясать надо.

Код
#define PIND    _SFR_IO8(0x09)
Go to the top of the page
 
+Quote Post
Dx!
сообщение Sep 28 2010, 19:21
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Да, всё так, большое спасибо. Теперь всё встало на свои места, всё понятно. Прошу прощения за причинённые неудобства 8)
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 28 2010, 19:24
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Petka @ Sep 28 2010, 23:18) *
Код
#define PIND    _SFR_IO8(0x09)

Если совсем правильно, то
Код
(*(volatile uint8_t *)(mem_addr))

где mem_addr это адрес порта D
таким образом PIND это uint8_t т.е. ровно 8 битное беззнаковое число.
Go to the top of the page
 
+Quote Post
Dx!
сообщение Sep 28 2010, 19:32
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Просто мы же в разделе AVR, мне казалось что особо указывать что есть PIND не нужно. Хотя (*(volatile uint8_t *)(mem_addr)) я не нашёл - оно где?
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 28 2010, 19:33
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Dx! @ Sep 28 2010, 23:32) *
Просто мы же в разделе AVR, мне казалось что особо указывать что есть PIND не нужно. Хотя (*(volatile uint8_t *)(mem_addr)) я не нашёл - оно где?

Код
include/avr/sfr_defs.h
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 28 2010, 19:42
Сообщение #15


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Не прошло и полгода!
И хоть после драки кулаками не машут, но на будущее. Не у всех установлен WinAVR, а получить результирующий ответ можно было уже после ответа на второй пост.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 19:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01495 секунд с 7
ELECTRONIX ©2004-2016