C++, объединить 2 переменных с байтами в одну

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

Разбираюсь с адафрутовскими шрифтами. Хочу записывать шрифт на флеш память, и при необходимости им пользоваться. Шрифт записываю на флеш память двумя частями, структура и сами глифы. Структура адафрутовского шрифта такая

 {   662,   6,  12,   9,    1,  -11 },  
 {   671,   8,  17,   9,    0,  -11 },

Первое число это индекс позиция начала глифа в массиве. 662 и 671 никак целиком не запихнуть во флеш память. Приходится разбивать на два байта 6  62 и 6  71. Задача теперь собрать из двух байт целое число, чтобы прибавить его к адресу начала массива глифов.

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

3.14ЗДЕЦ!

я пас.

b707
Offline
Зарегистрирован: 26.05.2017

Туцик пишет:

 662 и 671 никак целиком не запихнуть во флеш память. Приходится разбивать на два байта 6  62 и 6  71.

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

Нахрена вообще с такими знаниями разбираться со шрифтами? вы никогда ничего хорошего не напишете, а помойного кода в инете и так навалом

b707
Offline
Зарегистрирован: 26.05.2017

еще добавлю, что чтобы записать число 671 в прогмем - его вообще не нужно разбивать. Компилятор это делает сам, если вы описали переменную с ключевым словом PROGMEM

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

Я записываю шрифты HexFrame прямо из перекодированного fontconvertorом файла. Обычным копипастом. HexFrame я никак не перепишу и знаний нет, хочется максимально упростить все. Картинки я уже сделал. Шрифт кое как работает.

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

b707 пишет:

еще добавлю, что чтобы записать число 671 в прогмем - его вообще не нужно разбивать. Компилятор это делает сам, если вы описали переменную с ключевым словом PROGMEM

Я на внешнюю флеш пишу.

b707
Offline
Зарегистрирован: 26.05.2017

Туцик пишет:

Шрифт кое как работает.

именно что кое-как. Зачем такое "кое-как" нужно?

 

Короче, то что вы придумали - дурость и работать не будет.  Число 672 во флеше это совсем не "6" и "72", это (672 >>8) в старшем байте (672 & 0xFF) в младшем.

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

b707 пишет:

Туцик пишет:

Шрифт кое как работает.

именно что кое-как. Зачем такое "кое-как" нужно?

 

Короче, то что вы придумали - дурость и работать не будет.  Число 672 во флеше это совсем не "6" и "72", это (672 >>8) в старшем байте (672 & 0xFF) в младшем.

uint8_t Hi = 2;
uint8_t Lo = 20;

void setup() {
 Serial.begin(115200);

String hibyte = String(Hi, DEC);
String lobyte = String(Lo, DEC);
String var = hibyte + lobyte;

uint16_t Index = var.toInt();

Serial.print("Index =");     
Serial.println(Index);

}
void loop() {


}

Я вижу только такое решение.

b707
Offline
Зарегистрирован: 26.05.2017

Туцик пишет:

Я вижу только такое решение.

потому что ваши знания на нуле

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

Туцик пишет:

Я вижу только такое решение.

да, а что получится при

uint8_t Hi = 66;
uint8_t Lo = 200;

 

b707
Offline
Зарегистрирован: 26.05.2017

xDriver пишет:

да, а что получится при

uint8_t Hi = 66;
uint8_t Lo = 200;

 

66200 !

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

b707 пишет:

xDriver пишет:

да, а что получится при

uint8_t Hi = 66;
uint8_t Lo = 200;

 

66200 !

ну пусть попробует.

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

xDriver пишет:

b707 пишет:

xDriver пишет:

да, а что получится при

uint8_t Hi = 66;
uint8_t Lo = 200;

 

66200 !

ну пусть попробует.

А как оно получится? Для этого нужен очень огромный шрифт.

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

Туцик пишет:

А как оно получится? Для этого нужен очень огромный шрифт.

b707 сделает мне огромную светодиодную панель и он, очень большой шрифт, мне понадобится.

пробуй!

b707
Offline
Зарегистрирован: 26.05.2017

xDriver пишет:

b707 сделает мне огромную светодиодную панель и он, очень большой шрифт, мне понадобится.

это заказ?  :)

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

xDriver пишет:

Туцик пишет:

А как оно получится? Для этого нужен очень огромный шрифт.

b707 сделает мне огромную светодиодную панель и он, очень большой шрифт, мне понадобится.

пробуй!

Дело не в размере панели, а в разрешении экрана. Да и делаю чисто для своего пользования.

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

Туцик пишет:

Дело не в размере панели, а в разрешении экрана. Да и делаю чисто для своего пользования.

ты погляди на него, ты пробовать будешь или нет, просто хочу чтоб у тебя наступило еще одно разочарование.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Туцик пишет:

 

uint8_t Hi = 2;
uint8_t Lo = 20;

void setup() {
 Serial.begin(115200);

String hibyte = String(Hi, DEC);
String lobyte = String(Lo, DEC);
String var = hibyte + lobyte;

uint16_t Index = var.toInt();

Serial.print("Index =");     
Serial.println(Index);

}
void loop() {


}

Я вижу только такое решение.

Ну что ж, такое решение тоже имеет право на существование.

Только обратите внимание, что "склеиваете" Вы не числа а строки.

Хотя бы потому, что числа можно складывать, вычитать, умножать, делить, извлекать корень, но нельзя склеивать. Соответственно, Ваше желание "склеивать числа" - невыполнимо. По крайней мере до тех пор, пока Вы точно не определите, что такое "склеивание".

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

b707 пишет:

xDriver пишет:

b707 сделает мне огромную светодиодную панель и он, очень большой шрифт, мне понадобится.

это заказ?  :)

:)

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

andriano пишет:

Туцик пишет:

 

uint8_t Hi = 2;
uint8_t Lo = 20;

void setup() {
 Serial.begin(115200);

String hibyte = String(Hi, DEC);
String lobyte = String(Lo, DEC);
String var = hibyte + lobyte;

uint16_t Index = var.toInt();

Serial.print("Index =");     
Serial.println(Index);

}
void loop() {


}

Я вижу только такое решение.

Ну что ж, такое решение тоже имеет право на существование.

Только обратите внимание, что "склеиваете" Вы не числа а строки.

Хотя бы потому, что числа можно складывать, вычитать, умножать, делить, извлекать корень, но нельзя склеивать. Соответственно, Ваше желание "склеивать числа" - невыполнимо. По крайней мере до тех пор, пока Вы точно не определите, что такое "склеивание".

Спасибо. Учту. Хоть кто то без оскорблений. ;)

b707
Offline
Зарегистрирован: 26.05.2017

Туцик пишет:

 Хоть кто то без оскорблений. ;)

заслужил

Green
Offline
Зарегистрирован: 01.10.2015

А как тут без оскорблений, если нервов не хватает. Иной раз если матом не покроешь - не дойдёт.( И это печально.

 

b707
Offline
Зарегистрирован: 26.05.2017

Green пишет:

Иной раз если матом не покроешь - не дойдёт.( И это печально.

 

"Волшебный пендель"

Но в данном случае даже он не поможет

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

b707, хорошо что потер, а то я думал ты от него заразился :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

я - пас. 

так праздник жеж сёдня

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Чо за праздник?

«Склеивать» действительно только строки можно. А вот числа (байты) только складывать. 
ЗЫ: По примеру деда со всякими флоатами сейчас, останавливаясь на точности в два знака после запятой, жестко поступаю: умножаю на 100 и в int16_t. Огромнейшее спасибо за совет (хоть он и о температуре тогда писал).

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

BOOM пишет:

ЗЫ: По примеру деда со всякими флоатами сейчас, останавливаясь на точности в два знака после запятой,

В общем случае это весьма сомнительное занятие: одно дело 123456.78 и совсем другое - 0.02.

Цитата:

жестко поступаю: умножаю на 100 и в int16_t.

По науке это называется fixed point в отличие от floating point.

Соответственно "фиксируется" эта десятичная точка не обязательно на втором знаке, а в любом месте удобном для конкретной задачи.

Но более разумный подход - фиксировать количество не десятичных знаков, а двоичных. Т.е. разделитель целой и дробной части помещается после определенного разряда двоичного числа. Например байт b00111111 с двумя знаками после запятой соответствует b001111.11 или десятичному 15.75 (единица младшего разряда 0.25).

b707
Offline
Зарегистрирован: 26.05.2017

andriano пишет:

Но более разумный подход - фиксировать количество не десятичных знаков, а двоичных. Т.е. разделитель целой и дробной части помещается после определенного разряда двоичного числа. Например байт b00111111 с двумя знаками после запятой соответствует b001111.11 или десятичному 15.75 (единица младшего разряда 0.25).

красиво

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну раз так, приведу пример из конкретного проекта (сам проест здесь: http://arduino.ru/forum/proekty/razrabotka-protsessora-zvukovykh-effektov-na-stm32f407vet6 , но описан весьма фрагментарно).

int32_t tFulter_LF2i::iir32(int32_t NewSample) { // БИХ-фильтр, вычисляет один следующий отсчет, вход fixed(1.16), выход fixed(8.16)
union {
  int64_t q;     // присвоение 0.1us, арифм.операция 0.15us, 
  int32_t d[2];  // присв. 8, операций 10 = 0.8+1.5 = 2.3 us
} tmp;
  x_2 = x_1;       // fixed(1.16) сдвигаем предыдущие отсчеты
  y_2 = y_1;       // fixed(8.24) 
  x_1 = x_0;       // fixed(1.16) 
  y_1 = y_0;       // fixed(8.24) 
  x_0 = NewSample; // fixed(1.16)  запоминаем очередное значение
  
// (9.40)  =  (8.24)*(1.16)       (8.24)*(1.16)       (16.16)*(8.24)    (16.16)*(8.24)     (16.16)*(8.24)      <<16
  tmp.q = (AC_0*int64_t(x_0) + AC_1*int64_t(x_1) - BC_1*int64_t(y_1) + AC_0*int64_t(x_2) - BC_2*int64_t(y_2))*65536; // / 65536;
  y_0 = tmp.d[1]; // fixed(8:24) берем ситарщие 32 разряда 64-разрядного слова

  return y_0 >> 8; /// fixed(8.16);
}

здесь как раз указывается формат fixed для каждого из входящих в формулу чисел, чтобы гарантировать, что слагаемые имеют один и тот же формат. В данном случае промежуточный вариант в 64-разрядном числе формата 24.40, т.е. 40 двоичных знаков после запятой.