Проверка битовой маски
- Войдите на сайт для отправки комментариев
Добрый день. Нужна помощь в решении следующей проблемы:
В данном коде есть битовая маска размером 32. Я написал три простых функции, которые выставляют бит, убивают бит и проверяет его состояние. Маска в функции передается по указателю, а не по значению, так как масок может быть более одной. Нужно осуществлять контроль бита до его записи или уничтожения. Никак получается это реализовать если я вызываю функцию проверки в функциях записи или уничтожения... Думаю дело в том, что я не правильно передаю указатель на битовую маску. Если проводить проверку отдельно - то все получается. Но это извращение...
Пример кода с проверкой проводимой отдельно (где все срабатывает):
Биты выставляются и убиваются через передачу в сиреал нажатия кнопок (см test()), проверка проводится в функции test().
uint32_t flags_list=0;
void setup(){
Serial.begin(9600);
};
void loop(){
Serial.println(flags_list, BIN);
test();
delay(1000);
};
void SetFlag(uint32_t *flags_list, uint32_t flag){
// if (!CheckFlag(* flags_list , flag))
*flags_list = *flags_list + flag;
};
void DropFlag(uint32_t * flags_list, uint32_t flag){
// if (CheckFlag(* flags_list , flag))
*flags_list = *flags_list - flag;
};
uint8_t CheckFlag(uint32_t * flags_list, uint32_t flag){
Serial.print(F("* flags_list = "));
Serial.println (*flags_list);
if (* flags_list & flag) return 1;
else
return 0;
};
void test(){
if (Serial.available()){
byte symbol = Serial.read();
if (symbol == '6'){
Serial.println("6 pressed");
if(!CheckFlag(&flags_list, 2))
SetFlag(&flags_list, 2);
}
else if (symbol == '7'){
Serial.println("7 pressed");
if(CheckFlag(&flags_list, 2))
DropFlag(&flags_list, 2);
}
else if (symbol == '8'){
Serial.println("8 pressed");
if(!CheckFlag(&flags_list, 4))
SetFlag(&flags_list, 4);
}
else if (symbol == '9'){
Serial.println("9 pressed");
if(CheckFlag(&flags_list, 4))
DropFlag(&flags_list, 4);
}
}
}
Пример кода где возникают глюки, это видно при выводе в сиреал.
Биты выставляются и убиваются через передачу в сиреал нажатия кнопок (см test()), проверка проводится в функциях SetFlag() и DropFlag(), как это и должно быть, но не работает ;(((.
uint32_t flags_list=0;
void setup(){
Serial.begin(9600);
};
void loop(){
Serial.println(flags_list, BIN);
test();
delay(1000);
};
void SetFlag(uint32_t *flags_list, uint32_t flag){
if (!CheckFlag(* flags_list , flag)) // думаю ошибка где-то здесь
*flags_list = *flags_list + flag;
};
void DropFlag(uint32_t * flags_list, uint32_t flag){
if (CheckFlag(* flags_list , flag))// думаю ошибка где-то здесь
*flags_list = *flags_list - flag;
};
uint8_t CheckFlag(uint32_t * flags_list, uint32_t flag){
Serial.print(F("* flags_list = "));
Serial.println (*flags_list);
if (* flags_list & flag) return 1;
else
return 0;
};
void test(){
if (Serial.available()){
byte symbol = Serial.read();
if (symbol == '6'){
Serial.println("6 pressed");
// if(!CheckFlag(&flags_list, 2))
SetFlag(&flags_list, 2);
}
else if (symbol == '7'){
Serial.println("7 pressed");
// if(CheckFlag(&flags_list, 2))
DropFlag(&flags_list, 2);
}
else if (symbol == '8'){
Serial.println("8 pressed");
// if(!CheckFlag(&flags_list, 4))
SetFlag(&flags_list, 4);
}
else if (symbol == '9'){
Serial.println("9 pressed");
// if(CheckFlag(&flags_list, 4))
DropFlag(&flags_list, 4);
}
}
}
А че это за х**ня
14*flags_list = *flags_list + flag;/**/ uint32_t num = 0; /*некая переменая*/ uint32_t mask1 = 0x0F0F0F0F; /*некая маска*/ /*Взвести биты*/ void setMask(uint32_t *num, uint32_t mask ) { *num |=mask; } /*сбросить биты*/ void resetMask(uint32_t *num, uint32_t mask ) { *num &=mask; } void setup() { } void loop() { }Мне нужна возможность управлять каждым битом в отдельности, да еще в зависимости от других битов.
То, что вы назвали х**ней, это изменение значения переменной в функции, переданной по указателю.
Если зачение переменной
flags_listнапример 4 что есть 100 BIN, то для того чтобы установить бит 2ки (получить 110 BIN) нужно к 4 прибавить 2, что будет равно 6ти.Надеюсь ответил на Ваш вопрос. По существу моей проблемы можете что-то добавить?
flags_listнапример 4 что есть 100 BIN, то для того чтобы установить бит 2ки (получить 110 BIN) нужно к 4 прибавить 2, что будет равно 6ти.ПС:https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B_%D0%B2_C_%D0%B8_C%2B%2B
flags_listнапример 4 что есть 100 BIN, то для того чтобы установить бит 2ки (получить 110 BIN) нужно к 4 прибавить 2, что будет равно 6ти.ПС:https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B_%D0%B2_C_%D0%B8_C%2B%2B
Я прекрасно все отличаю. И умею переводить из десятичной системы в любую. Я знаю сколько нужно прибавить к нулю в десятичной системе стобы получить любую маску. Переполнения не будет, так как более 2 в степени 31 я записывать не буду. Вы по моей проблеме можете что-то дельное сказать?
Не думайте что вы самый умный. Вы по моей проблеме можете что-то дельное сказать?
да он уже подсказал, а вы ему в ответ "не умничайте"
Хотя Квон прав - вы явно не понимаете, что "установить второй бит" и "прибавить к числу 2" - это совершенно разные операции. дающие разные результаты. И поэтому в той вашей строке написана именно х..ня и никак иначе.
И это ответ на вопрос - "почему мои битовые маски не работают".
У вас первый код - "где все срабатывает" - уже неверный.
Теперь по второму коду. Ошибки именно в тех строках, где вы предполагаете. Смотрите внимательно, ошибка очевидная... странно вообще, что компилятор не ругается. У вас наверно предупреждения компилятора выключены...
Но это не отменяет того, что первый код надо переписывать.
/*сбросить биты*/ void resetMask(uint32_t *num, uint32_t mask ) { *num &=mask;Так сброс вообще не работает.
Пример:
Включаем биты
1001 число
или
0110 биты
1111 итого
Выключаем биты (по-вашему)
1111 итого
и
0110 маска
0110 !число
ну если сами не можете догадаться - набрали в гугле вопрос "как сбросить бит" и получили ответ в первой же ссылке...
Заметьте - никакого сложения тут и рядом не лежало.
/*сбросить биты*/ void resetMask(uint32_t *num, uint32_t mask ) { *num &= ~mask; // потерял ~ }Хорошо давайте вернемся к истокам...
Представим DEC число до 15 в BIN виде:
(2^0)*x+(2^1)*x+(2^2)*x+(2^3)*x с этим будем спорить?
Теперь мне нужно включить второй бит
(2^0)*0+(2^1)*1+(2^2)*0+(2^3)*0 так? что есть 0+2
Теперь мне нужно включить четвертый бит
(2^0)*0+(2^1)*0+(2^2)*0+(2^3)*1 что есть 0+8
С учетом включеного 2го бита - 8+2=10
(2^0)*0+(2^1)*1+(2^2)*0+(2^3)*1 = 10 DEC
Теперь мне нужно выключить 4 бит:
10 - 8 = 2
(2^0)*0+(2^1)*1+(2^2)*0+(2^3)*0
Докажите что я не прав!
Подскажите пожалуйста где ошибка?
Теперь по второму коду. Ошибки именно в тех строках, где вы предполагаете. Смотрите внимательно, ошибка очевидная... странно вообще, что компилятор не ругается. У вас наверно предупреждения компилятора выключены...
Но это не отменяет того, что первый код надо переписывать.
Подскажите пожалуйста где ошибка
возьмите десятичное число 14 и включите в нем четвертый бит прибавлением восьми, ага...
Ну сколько можно тупить.
Докажите что я не прав!
Оно нам надо? Что-то Вам доказывать? Вам ардуина уже доказал, что Вы не правы. Если Вы этого доказательства не поняли - это Ваша проблема. Можете доказывать свою правоту Ардуине, возможно, она с Вами согласится.
Ткнуть носом в то, что прибавить два - это вовсе не тоже самое, что взвести второй бит - это пожалуйста.
Допустим есть число в котором уже взведён второй бит. Очевидно, что если взвести его ещё раз, ничего поменяться не должно. Прекрасно. Число со взведённым вторым битом - это 4 (0100). Прибавьте к нему 2 - получите 6 (0110). Что-то пошло не так?
Даже если бы Вы правильно считали биты (справа налево, с нулевого) и прибавяли бы не 2, а 4, всё равно бред. Опять же, берём число с уже взведённым вторым битом - 4 (0100), прибавляем к нему 4, получаем 8 (1000). Опять не слава Богу?
Вот как-то так.
Подскажите пожалуйста где ошибка
я вам уже строчку указал - думайте.
Подсказка - проверьте, что именно за параметры (тип данных) вы передаете в каждую из трех своих функций.
Докажите что я не прав!
Оно нам надо? Что-то Вам доказывать? Вам ардуина уже доказал, что Вы не правы. Если Вы этого доказательства не поняли - это Ваша проблема. Можете доказывать свою правоту Ардуине, возможно, она с Вами согласится.
Ткнуть носом в то, что прибавить два - это вовсе не тоже самое, что взвести второй бит - это пожалуйста.
Допустим есть число в котором уже взведён второй бит. Очевидно, что если взвести его ещё раз, ничего поменяться не должно. Прекрасно. Число со взведённым вторым битом - это 4 (0100). Прибавьте к нему 2 - получите 6 (0110). Что-то пошло не так?
Даже если бы Вы правильно считали биты (справа налево, с нулевого) и прибавяли бы не 2, а 4, всё равно бред. Опять же, берём число с уже взведённым вторым битом - 4 (0100), прибавляем к нему 4, получаем 8 (1000). Опять не слава Богу?
Вот как-то так.
Так для этого проверка и пишется!!!!!!!!!!!!!
Никто не собирается прибавлять два если второй бит возведен или 8 если возведен 4
Подскажите пожалуйста где ошибка
я вам уже строчку указал - думайте.
Подсказка - проверьте, что именно за параметры (тип данных) вы передаете в каждую из трех своих функций.
Я ее сам себе указал, и это прекласно видно в сериале.
Первый код работает прекрасно. Проблема во втором. Что-то не првильно я передаю.
Так для этого проверка и пишется!!!!!!!!!!!!!
Никто не собирается прибавлять два если второй бит возведен или 8 если возведен 4
вы идиот? Установка бита делается в одно действие без всякой проверки....
Первый код работает прекрасно. Проблема во втором. Что-то не првильно я передаю.
я вижу. что вы все лучше нас знаете. Нафига тогда на форум пришли?
Так для этого проверка и пишется!!!!!!!!!!!!!
Никто не собирается прибавлять два если второй бит возведен или 8 если возведен 4
вы идиот? Это делается в одно действие без всякой проверки....
От идиота слышу. Обоснования закончились перешли к оскорблениям? Не можете / не знаете/ не хотите помочь - так и скажите. Я не обижусь. Оскорбления вас не красят.
Первый код работает прекрасно. Проблема во втором. Что-то не првильно я передаю.
я вижу. что вы все лучше нас знаете. Нафига тогда на форум пришли?
Ну вы-то наверное все знаете)))
Вполне возможно. Учусь. Я не претендую на роль великого программиста.
Так для этого проверка и пишется!!!!!!!!!!!!!
Никто не собирается прибавлять два если второй бит возведен или 8 если возведен 4
Вы не поняли! Если бы Вы правильно выставляли бит, то не была бы нужна никакая проверка - выставлен, ну ещё раз выставим (ещё "единичнее" станет). А коль скоро Вам потребовалась проверка, значит Вы просто неправильно его выставляете.
Впочем, как я уже сказал, что-либо Вам доказывать в мои планы не входит. Если Вы считаете, что я неправ, а Вы делаете всё правильно - в добрый путь, доказывайте это контроллеру.
Разумеется во втором.
Квон, был бы верно написан первый - второй вообще не понадобился бы.
Вы не поняли! Если бы Вы правильно выставляли бит, то не была бы нужна никакая проверка - выставлен, ну ещё раз выставим (ещё "единичнее" станет). А коль скоро Вам потребовалась проверка, значит Вы просто неправильно его выставляете.
По коду я согласен. Через битовые операции проще. Но это не сняло моего вопроса. На будущее нужно знать где ошибка.
Первый код работает прекрасно.
А если Вам надо взвести третий бит, Вы в setFlag 3 передадите? А вот, если нулевой бит? Тогда передаите 0, он прибавится и ... ничего не изменится? Прекрасный код!
Послушайте, Вам пытаются объяснить, что не прекрасно работает Ваш код - он полный бред. Вы доказываете обратное. Кому? Зачем? Попробуйте это контроллеру доказать.
А если Вам надо взвести третий бит, Вы в setFlag 3 передадите? А вот, если нулевой бит? Тогда передаите 0, он прибавится и ... ничего не изменится? Прекрасный код!
Третий бит это два в степень три это 8
Нулевой бит это 2 в степени 0 это единица
Это сложно?)))
Поробуйте это контроллеру доказать.
В первом коде доказал.
Третий бит это два в степень три это 8
Нулевой бит это 2 в степени 0 это единица
Это сложно?)))
Ну, для меня - нет, у меня не возникает проблем я установкой битов.
А для Вас, похоже, сложно. Это же не я написал, а Вы:
А 2^2 вроде, как 4.
Это сложно?)))
конечно сложно. И доказательством тому - твой код. Чтобы обойти все эти твои "несложно" ты напихал туда три лишние процедуры, между которомы не в состоянии правильно передать параметр. А написал бы битовыми операциями в одну строчку - и процедуры не нужны были.
Ты думаешь. программы оптимизирует для красоты? - нет. Меньше строк - меньше мест для ошибок.
В первом коде доказал.
Ну и флаг Вам в руки и попутного ветра! :)
В первом коде доказал.
ты тока свою тупость и упертость доказал
Евгений, не пытайтесь понять зачем я это делаю. Просто подскажите, как правильно передать указатель в функцию check, которая вызывается внутри set и drop.
В первом коде доказал.
ты тока свою тупость и упертость доказал
Опять хамите?
Евгений, не пытайтесь понять зачем я это делаю.
о боже, похоже он остается уверен в своей правоте :)))))))))))))))
это просто ЛОЛ
Опять хамите?
я??? Хамлю???
Где Клапауций? Где Дракула??? Я что, один должен обьяснять этому неучу, кто он есть? :)))
Евгений, не пытайтесь понять зачем я это делаю.
о боже, похоже он остается уверен в своей правоте :)))))))))))))))
это просто ЛОЛ
Вы пытаетесь убедить меня в своей гениальности напрасно. Я уже согласился с тем что, через битовые операции удобнее. Я так и поступлю. А теперь блестните интеллектом и передайте правильно параметр что бы все заработало. Вот это будет доказательством вашей безграничной мудрости)))
/**/ //------------------------------- /*Взвести биты*/ void setMask(uint8_t *num, uint8_t mask ) { *num |= mask; } /*сбросить биты*/ void resetMask(uint8_t *num, uint8_t mask ) { *num &= ~mask; } /*проверить*/ bool testMask(uint8_t *num, uint8_t mask ) { return *num & mask; } /*показать переменную*/ void viev(uint8_t *num) { Serial.println(*num, BIN); } //------------------------------- uint8_t num = 0xFF; /*некая переменая*/ uint8_t mask1 = 0x0F; /*некая маска*/ void test() { if (Serial.available()) { byte symbol = Serial.read(); if (symbol == '6') {/*установить bit 0*/ setMask(&num, 0x01); viev(&num); } else if (symbol == '7') { /*сбросить bit 0*/ resetMask(&num, 0x01); viev(&num); } else if (symbol == '8') { /*вывести число*/ viev(&num); } else if (symbol == '9') { /*сравнить с маской*/ if ( testMask(&num, 0x01)) Serial.println("true"); else Serial.println("false"); } } } //------main------------------------- void setup() { Serial.begin(9600); viev(&num); } void loop() { test(); } /*Скетч использует 1650 байт (5%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 198 байт (9%) динамической памяти, оставляя 1850 байт для локальных переменных. Максимум: 2048 байт. *//**/ //------------------------------- /*Взвести биты*/ void setMask(uint8_t *num, uint8_t mask ) { *num |= mask; } /*сбросить биты*/ void resetMask(uint8_t *num, uint8_t mask ) { *num &= ~mask; } /*проверить*/ bool testMask(uint8_t *num, uint8_t mask ) { return *num & mask; } /*показать переменную*/ void viev(uint8_t *num) { Serial.println(*num, BIN); } //------------------------------- uint8_t num = 0xFF; /*некая переменая*/ uint8_t mask1 = 0x0F; /*некая маска*/ void test() { if (Serial.available()) { byte symbol = Serial.read(); if (symbol == '6') {/*установить bit 0*/ setMask(&num, 0x01); viev(&num); } else if (symbol == '7') { /*сбросить bit 0*/ resetMask(&num, 0x01); viev(&num); } else if (symbol == '8') { /*вывести число*/ viev(&num); } else if (symbol == '9') { /*сравнить с маской*/ if ( testMask(&num, 0x01)) Serial.println("true"); else Serial.println("false"); } } } //------main------------------------- void setup() { Serial.begin(9600); viev(&num); } void loop() { test(); } /*Скетч использует 1650 байт (5%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 198 байт (9%) динамической памяти, оставляя 1850 байт для локальных переменных. Максимум: 2048 байт. */Я согласен с вами. Уважемые! Вы можете понять что мне интересно где ошибка в передаче параметра?
А теперь блестните интеллектом и передайте правильно параметр что бы все заработало. Вот это будет доказательством вашей безграничной мудрости)))
звездочку лишнюю убери в тех строчках, что сам пометил. Я в сообщении #17 уже дал подсказку - но вижу не доходит.
Возьми учебник и прочитай. зачем эта звездочка нужна.
На стенку павесь.
У нас демократия, плюсуем/минусуем
На стенку павесь.
У нас демократия, плюсуем/минусуем
Деда, а смысл? ты думаешь, получив кучу минусов за свои высеры - он что-то поймет?
Думаю, это, как минимум, заставит задумаца.
Не, ну это, есле чел одекватный.
буква л пропущена))) Исправте, компилятор ругается