Помогите пожалуйста, объяснял ребенку побитовые операторы, понял, что сам ничего не понимаю, вынужден просить помощи. Для практики решили воссоздать функцию bitRead (оригинального кода ее в глаза не видел, основывались чисто на ее задачах) Вот что у нас получилось, а точнее не получилось. Внедрил в функцию переменную для проверки, и заморочки у нас с функцией pow она упорно не возвращает нам значения которые должна. При передаче в order = 0 отрабатывает как положено в power лежит 1; при order = 1 в power = 2; а вот при order = 2 в power = 3 !!! Что за хрень понять не могу, может где с типами напортачил? ибо pow возвращает значение в double, а я вроде как их пытаюсь запихать в int? Код (C++): int test =0; // для проверки переменных byte bitReadMode(byte num, float order){ int power = pow(2, order); byte a = num & power; test = power; // для проверки переменных return a; } bitReadMode(value, 2); Serial.println (test);
Как-то вы мудрёно объясняете ребёнку битовые операции Вы лучше подойдите с другого боку - объясните, что каждая позиция бита в байте - это степень двойки: Код (C++): 0 0 0 0 0 0 0 0 - пустой байт теперь представьте, что мы будем двигать единичку справа (от самого младшего бита) налево - к самому старшему. Битов всего 8, нумеруются от 0 до 7. И вот тут как раз для понимания и нужна степень двойки, т.к. мы оперируем двоичной системой. И получается, что: если первый бит установлен, то это число "2 в степени позиции бита" (т.е. 2 в нулевой степени), если второй бит установлен - это число "2 в первой степени" и т.д. На примере: Код (C++): 0 0 0 0 0 0 0 1 - число 1 (2^0) 0 0 0 0 0 0 1 0 - число 2 (2^1) 0 0 0 0 0 1 0 0 - число 4 (2^2) 0 0 0 0 1 0 0 0 - число 8 (2^3) и т.д. После понимания этой закономерности очень просто оперировать снятием/постановкой бита: достаточно знать, на сколько позиций влево сдвинуть единичку, чтобы получить нужную позицию бита в байте: Код (C++): byte |= (1 << 0) - устанавливаем первый бит в байте byte |= (1 << 1) - устанавливаем второй бит в байте byte |= (1 << 2) - устанавливаем третий бит в байте и т.д. или - так: Код (C++): byte |= 1 - устанавливаем первый бит в байте byte |= 2 - устанавливаем второй бит в байте byte |= 4 - устанавливаем третий бит в байте и т.д. Снимаем биты: Код (C++): byte &= ~(1 << 0) - снимаем первый бит в байте byte &= ~(1 << 1) - снимаем второй бит в байте byte &= ~(1 << 2) - снимаем третий бит в байте и т.д. Ну и битовые маски - например, надо установить первый и третий бит в байте. Битовая маска будет "2 в степени 0 И два в степени 2", т.е. 1 | 4 или, что то же самое, Код (C++): (1 << 0) | (1 << 2) Если сдвиги для вас непонятны - просто оперируйте десятичными числами степеней двойки 1 - первый бит 2 - второй бит 4 - третий бит 8 - четвёртый бит 16 - пятый бит 32 - шестой бит 64 - седьмой бит 128 - восьмой бит Т.е., опять же, чтобы установить второй и четвёртый бит в байте, надо взять маску "2 И 8", т.е. Код (C++): byte |= (2 | 8); // устанавливаем byte &= ~(2 | 8); // снимаем И не надо никаких bitRead и прочей ардуиновской мути.
Еще проще: рисуем таблицу 8 столбиков (для случая байта) 2 ряда, в верхнем ряду пишем числа "128, 64, 32, 16, 8, 4, 2, 1", в нижний вписываем двоичное число по биту в клетку. Складываем те числа из верхнего ряда, под которыми стоит единичка, получаем результат. Это наглядно. А если вычислять 1 или 0 в заданной позиции числа, то лучше воспользоваться маской. Тогда функция будет выглядеть так: Код (C++): bool bitReadMode(byte num, int order) { return (order & (1 << num)); } Однако, для разбора числа типа float этот способ не подойдет, там придется работать с указателями.
Ребят, вы не на тот вопрос отвечаете! Я спрашиваю про непонятно почему возникающие отклонения в работе функции pow() ! Сдвиговые операторы эт попозжа, сейчас именно &, и как раз 0 1 2 4 8 16, являются степенями числа 2, для этого мне и нужна эта функция, а она не работает как ей положено. Если бы меня интересовали альтернативы я обязательно бы спросил, я прошу чтобы мне указали на ошибку почему у меня если передать в order = 2 в power оказывается 3 ?!
Вангую: всё из-за представления чисел с плавающей точкой. Подтверждение: http://forum.arduino.cc/index.php?topic=26152.0 Если надо в целочисленные степени возводить - пишите свою pow, быстрее и проще. Если надо возводить двойку в степень - ещё проще, битовый сдвиг и всё. З.Ы. Ещё ссылок на проблему: https://www.google.ru/search?q=ardu...arduino+pow+site:forum.arduino.cc&newwindow=1
Спасибо, я думаю так и сделаем сначала через цикл, а потом и до сдвигов дойдем. За ссылочки тоже спасибо, попробую еще поколдовать с преобразованием чисел