Преобразовать 0xffffff в три восьмибитных

Junior1980
Offline
Зарегистрирован: 27.03.2015

Всем привет, возник вопрос преобразования 3-х битного шестнадцатиричного числа в три восьмибитных шестнадцатиричных, т.е. например из 0xffffff нужно разложить на 0xff 0xff 0xff. Посоветуйте кто делал?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Junior1980 пишет:

3-х битного шестнадцатиричного числа

Это что? Описка, глупость или что-то имелось в виду?

Junior1980
Offline
Зарегистрирован: 27.03.2015

да, описка, извините, 24-х битного

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Ладно... из жалости сделаю вид, что догадался о том, что число не "3-х битовое", а, все-таки, трех БАЙТОВОЕ.

1. нет такого типа, есть uint16_t и uint32_t в 2 и 4 байта, соответственно.

2. Значит преобразовывать нужно uint32_t.

Проще всего использовать "расово верное" преобразование через  union, оно работает на всех платформах, следовательно переносимо и является гуд-стайлом программирования. Можно сдвигами и масками, только дольше.

 

union {
  uint8_t BytesArray[4];
  uint32_t UlungNumber;
} ToConvert;

ToConvert.UlongNumber = MyLongHex;

My0Byte = ToConvert.BytesArray[0];
My1Byte = ToConvert.BytesArray[1];
My2Byte = ToConvert.BytesArray[2];
My3Byte = ToConvert.BytesArray[3];

Как я понял, тебе нужны только первые три байта.

negavoid
Offline
Зарегистрирован: 09.07.2016
long color = 0xffffff;

byte r = (color & 0x00ff0000UL) >> 16;
byte g = (color & 0x0000ff00UL) >>  8;
byte b = (color & 0x000000ffUL)      ;
wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Сдвиги и маски:

uint32_t Mytemp=MyUlong;

byte0 = Mytemp & 0xff;
Mytemp = Mytemp >> 8;

byte1 = Mytemp & 0xff;
Mytemp = Mytemp >> 8;

byte2 = Mytemp & 0xff;
Mytemp = Mytemp >> 8;

byte3 = Mytemp & 0xff;

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Еще раз сдвиги и маски - суть говнокод. так можно, но не стоит программировать.

Как говорил мой старый учитель:

Старайся делать хорошо, ибо плохо - оно само получится.

Junior1980
Offline
Зарегистрирован: 27.03.2015

Ок парни, спасибо за быстрые ответы, попробую оба варианта, нужна именно скорость преобразования

negavoid
Offline
Зарегистрирован: 09.07.2016

А сдвиги, кончно же, говнокод, то-то под него говноинженеры предусмотрели аппаратные говноинструкции shr и shl, ror и rol и прочие :)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Да! Добавлю:

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

Код будет короче (и быстрее) для контроллера и читаемее в исходнике.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

negavoid пишет:

А сдвиги, кончно же, говнокод, то-то под него говноинженеры предусмотрели аппаратные говноинструкции shr и shl, ror и rol и прочие :)

Дурака из себя строешь? Получается....

=================

Штоп не думал, что обзываюсь, поясню:

сдвиг на 8 в 8-ми битном контроллере, это взятие байта по другому адресу. Просто смысла не имеет.

Еще раз, для тех, кто в танке - СДВИГ НА 8. Ничего не ёрзает? Не на 3 и не на 5, а на 8

Единственная надежда, что компилятор оптимизирует - иначе код будет просто пи..ец какой кривой.

--- В ARM-e  хоть какой-то смысл есть, там важно выравнивание лонга по адресу, делящемуся на 4, но в AVR Mega - вообще никакого смысла не имеет.

Junior1980
Offline
Зарегистрирован: 27.03.2015

Парни, код будет применяться на Maple mini - STM32F103CBT6 под Arduino Ide 1.6.5

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

Можно переделать под себя такой пример:

typedef union _MYDATETIME {
    
    struct 
    {
        uint32_t mday   : 5; // 0 - 31
        uint32_t mon    : 4; // 0 - 15
        uint32_t year   : 6; // 0 - 63
        uint32_t hour   : 5; // 0 - 31
        uint32_t min    : 6; // 0 - 63
        uint32_t sec    : 6; // 0 - 63       
    } fields;
    
    uint32_t time;
    
} * PMYDATETIME, MYDATETIME;

const MYDATETIME dt[] PROGMEM = 
{
// d - день месяца - [ 1 to 31 ]
// m - месяц, начиная с Января - [ 0 to 11 ]
// y - год, начиная с 2000

// H - часы - [ 0 to 23 ]
// M - минуты - [ 0 to 59 ]
// S - секунды - [ 0 to 59 ]

//               d   m   y   H   M   S 
    { fields: { 14, 10, 16, 00, 00, 00 } }, // 0
    { fields: { 14, 10, 16, 01, 00, 00 } }, // 1
    { fields: { 14, 10, 16, 02, 00, 00 } }, // 2
    { fields: { 14, 10, 16, 03, 00, 00 } }, // 3
    { fields: { 14, 10, 16, 04, 00, 00 } }, // 4
    { fields: { 14, 10, 16, 05, 00, 00 } }, // 5
    { fields: { 14, 10, 16, 06, 00, 00 } }, // 6
};

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

wdrakula пишет:

1. нет такого типа, есть uint16_t и uint32_t в 2 и 4 байта, соответственно.

Нет, то оно нет, но если сильно хочется. то сделать можно :)

https://gist.github.com/mntone/25d591ff5db04de26e95

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ЕвгенийП пишет:

wdrakula пишет:

1. нет такого типа, есть uint16_t и uint32_t в 2 и 4 байта, соответственно.

Нет, то оно нет, но если сильно хочется. то сделать можно :)

https://gist.github.com/mntone/25d591ff5db04de26e95

Супер!!! Очень забавно. Поправили мне поганое, с утра, настроение. Спасибо!

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

ЕвгенийП пишет:

wdrakula пишет:

1. нет такого типа, есть uint16_t и uint32_t в 2 и 4 байта, соответственно.

Нет, то оно нет, но если сильно хочется. то сделать можно :)

https://gist.github.com/mntone/25d591ff5db04de26e95

Скажу больше, делать ничего не надо, есть __uint24 и __int24.

https://gcc.gnu.org/wiki/avr-gcc

Хоть и описано в Extensions, но есть. Товарищь с ником ptr сделал для меня открытие недавно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

xDriver пишет:

Скажу больше, делать ничего не надо, есть __uint24 и __int24.

Про то, что в GNU это есть я знал, но думал, что с теми опциями компилятора, что стоят в IDE по умолчанию, этого типа нет. А я уж давно зарёкся кому-либо здесь говорить про фичи, которых нет в умолчательных опциях.

Но, сейчас проверил в своём IDE - есть! Так что, спасибо, что напомнили.

Правда, я не уверен, что у меня в IDE опции "по умолчанию". У меня и auto есть, и типизированные enum, но что-то мне кажется, что раньше их не было. Может я таки поменял опции, не помню. Не мог бы кто-нибудь, у кого точно опции стоят "из коробки" проверить?

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Дык, я из коробки и иммел ввиду. Сам очень долго удивлялся.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Спасибо, xDriver.