Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Анатомия регистра.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Злодей
cranky.gif Где у числа голова, какой байт в слове верхний, и как определять возраст разряда?

Большое спасибо.
demiurg_spb
Чтоб немного облегчить себе и другим жизнь для проверки, установки или очистки бит в байте (слове и т.д.) очень наглядно пользоваться масками, но не такими как 0х80, а допустим как (1<<7). Порядок следования бит в языке СИ и С++, да и наверное и во всех прочих языках высокого уровня (???), всегда одинаков: самый правый бит №0 (LSB) - младший, самый левый бит (MSB) - старший. И это позволяет в немалой степени абстрагироваться от аппаратной особенности распределения бит и байт на той или иной платформе.
Код
uint16_t x = 0;
x |= (1<<0);     // установить бит номер 0
x ^= (1<<0);    // инвертировать  бит номер 0
if (x&(1<<13)) {..}  // проверить установлен ли бит номер 13
Естественно, никто не мешает пойти и ещё дальше и обернуть всё это в макросы.
А для вычленения байт я использую такие макросы (они на мой взгляд самые удобные и не запутанные):
Код
#define BYTE0(X)            ((unsigned char)((X)>>0U))
#define BYTE1(X)            ((unsigned char)((X)>>8U))
#define BYTE2(X)            ((unsigned char)((X)>>16U))
#define BYTE3(X)            ((unsigned char)((X)>>24U))
Злодей
Тогда определить MSB можно так:
#define MSB( X ) ( ( X & ( 1 << ( 8 * sizeof( X ) ) ) ) ? 1 : 0 )

если мы используем
#define MSB( X ) ( X & ( 1 << ( 8 * sizeof( X ) ) ) )
для какого-нибудь very long X с единицей в самом значащим бите, получим число из 1 и very long хвоста нулей. Хранить его не стоит, но можно использовать в логическом выражении.

Обращаю внимание (сам долго смотрел на пример и не замечал), как demiurg_spb отрезает переднюю часть несколько-байтового числа приведением к типу (unsigned char):

Цитата(demiurg_spb @ Feb 15 2009, 16:40) *
Код
#define BYTE0(X)            ((unsigned char)((X)>>0U))
#define BYTE1(X)            ((unsigned char)((X)>>8U))
#define BYTE2(X)            ((unsigned char)((X)>>16U))
#define BYTE3(X)            ((unsigned char)((X)>>24U))


Окончания U ... это ... помощь компилятору?
demiurg_spb
Цитата(Злодей @ Feb 15 2009, 20:41) *
Окончания U ... это ... помощь компилятору?
В данном конкретном случае этого можно было и не делать (явно не указывать тип и размерность констант). Я просто привык (пару раз наступил на грабли) и считаю, что если ты знаешь тип и размерность константы (а знаешь ты это почти всегда) и она отлична от int или эта константа участвует в формуле, в которой возможен выход за диапазон типа int, то использование суффиксов U L UL f обязательно!
Цитата
Тогда определить MSB можно так:
#define MSB( X ) ( ( X & ( 1 << ( 8 * sizeof( X ) ) ) ) ? 1 : 0 )
так короче
Код
#define MSB(X) (((X)  &  (1 << (8*sizeof(X)))) != 0)
Поясню: результатом любой логической операции уже является числом 0 или 1. И также справедливо утверждение, что любое выражение само может быть объектом логической операции.
Поэтому, совершенно нормально и адекватно писать так:
Код
n = a + b - (y==x);
или даже так
Код
if ((a=b)) {...}
- тут происходит присвоение 'а' к 'б', а потом проверка на неравенство нулю результата выражения, т.е. (a!=0) (скобочки двойные, чтоб указать, что тут не опечатка и тут не имелось в виду а==b ).
Цитата
Обращаю внимание (сам долго смотрел на пример и не замечал)...

Вы бы лучше обратили внимание, на то, что аргументы передаваемые в макрос должны быть взяты в скобки в теле макроса.
Об этом во всех учебниках толдычат и не зря.
Почувствуйте разницу:
Код
#define GOOD_MACRO(X)  ((X)*(X))
#define BAD_MACRO(X)     (X*X)

static const int A = 1;
int a = GOOD_MACRO(A+1);   // результат = (A+1)*(A+1) = 2*2 = 4
int b = BAD_MACRO(A+1);    // результат = A+1*A+1 = 1+1+1 = 3
Злодей
Оправдаюсь, я не один такой: вот пример плохого макроса нашелся в аппноуте atmel:
#define _SET_LOCK_BITS(data) boot_lock_bits_set(~data)

Естественно, в контексте он не представляет опасности.
demiurg_spb
Нет в мире совершенства...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.