Страница 1 из 2
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 10:40
ElectroMechaniC
Привет! Есть задача! есть входная последовательность HEX => 7F 22 12
мне нужно применить к ней формулу
(1.0*(10*((A*16777216+B*65536+C*256+D)&268435455)))/1000
Научите как это сделать? Желательно блоком, с возможностью подмены входного значения и изменения формулы расчёта...
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 11:23
Sancho
ElectroMechaniC писал(а): 05 окт 2018, 10:40есть входная последовательность HEX => 7F 22 12
Это число или поток из uart?
Если число, long, то :
long_to_4_byte_(CODE).ubi
Отправлено спустя 3 минуты 22 секунды:
Кстати, в формуле четыре байта, A-D, а во входной последовательности - три байта.... Или это как пример?
Если определиться, где какой байт - блок запросто сделает любой.
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 11:48
ElectroMechaniC
[ref=#ff8000]Sancho[/ref], Да я тоже заметил, скорее всего последний байт просто 00,
Это ответ полученный через UART. последовательность такова A-7F: B-22: C-12: D-(предположительно) 00.
Эта последовательность в качестве примера, она постоянно будет обновляться, должна проходить через формулу и выдавать конечный результат в виде десятичного числа...
Отправлено спустя 3 минуты 18 секунд:
Всё правильно - поток)
Отправлено спустя 2 минуты 32 секунды:
Так! Разбили на 4е байта, потом каждый по формуле "переарифметили"
А вот как быть вот с этим : ...)&268435455- это побитовое "и " , как его применить?
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 11:49
Labu559
ElectroMechaniC писал(а): 05 окт 2018, 10:40 есть входная последовательность HEX => 7F 22 12
Если я правильно Вас пронял, и "7F" это "А" в Вашей формуле; B==0x22 ; C==0x12, то в таком случае легче нам будет, если мы представим все числовые константы как бинарные числа и вспомним что AVR, в принципе своём умеют из математических простых операций только сложение и вычитание и битовый сдвиг. Для умножения/деления применяются сложные функции, которые спрятаны в библиотеках.
в таком случае Ваша формула
(1.0*(10*((A*16777216+B*65536+C*256+D)&268435455)))/1000
принимает вид
(1.0*(10*((((A<<24)+(B<<16)+(C<<8)+D)&268435455))/1000, убираем совершенно лишнюю операцию- &B1111111111111111111111111111
сокращаем лишние нолики в знаменателе и числителе
(((A<<24)+(B<<16)+(C<<8)+D))/100.0
и если я нигде не ошибся (п.ж. исправте, я только учусь)
дальше, засовываем формулу в Пользовательский Блок и... вспоминаем, что Ув.Автор, анонсировав включение поддержки переменных word и double не включил их в Пользовательские блоки. Удачи!
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 11:52
ElectroMechaniC
А! Совсем забыл! Я буду работать с каждым байтом отдельно!!!!!
с помощью :
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 11:57
ElectroMechaniC
Labu559 писал(а): 05 окт 2018, 11:49лишнюю операцию- &B1111111111111111111111111111
с
То есть это нужно всего лишь для того, что бы убрать лишние ноли? это 2й операндр, что ли?
и да! мне нужно как то этот процесс автоматизировать. в буках хорошо но как на деле не понятно))) уж извините не программист))))
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 12:05
Labu559
это Ваше DEC268435455 == 0b1111111111111111111111111111 в бинарном представлении, которое делает
операцию побитового И совершенно лишней.
Изв. не посчитал знаки, в блоке всё правильно кажется.
Сейчас [spoiler title=накидал ПБлок]
ElMechaniC.flp
[/spoiler] в проекте, только мат. действие /100,0 вынес за пределы блока.
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 12:33
Sancho
[ref]Labu559[/ref], Не соглашусь. Эта операция уберёт четыре старших бита в числе, 32 битном.
Отправлено спустя 10 минут 50 секунд:
Собираем long из байтов:
4_byte_to_long_(CODE).ubi
Если что, в конце дописать:
out = (out & 268435455) / 100.0;
Отправлено спустя 4 минуты 56 секунд:
Labu559 писал(а): 05 окт 2018, 11:49(((A<<24)+(B<<16)+(C<<8)+D))/100.0
При операции (A<<24) и остальным подобным, где "А" - тип байт, имеем всего 8 байт!!!
Соответственно, при смещении более 8 получим нули.
Необходимо приводить "А" перед преобразованием к другому типу данных.
Можете проверить.
Уже писал где-то на
форуме...
Отправлено спустя 6 минут 46 секунд:
[ref]ElectroMechaniC[/ref], Обновил, была очепятка при копипасту...
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 12:53
AlexCrane
viewtopic.php?f=87&t=3122&p=55223#p55223
Здесь выкладывал данные функции, и в новой версии FLProg они есть в числе стандартных
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 12:55
Labu559
Sancho писал(а): 05 окт 2018, 12:33Не соглашусь.
И правильно делаете, исправился выше. А по сдвигам, я в курсе, попадал на то, что компилятор предупреждает и пропускает такое безобразие. Надо делать так- value = (((A|0UL)<<24)+((B|0UL)<<16)+((C|0UL)<<8)+D);
На заметку, не поставил в ПБлоке точку с запятой в конце действия, "никто" не ругался на некорректность блока, и при вызове компиляции в IDE FLProg каждый раз [spoiler title=вылетает с логом]
error.log
[/spoiler]
Ув. [ref]AlexCrane[/ref], Вы ошибаетесь в блоке "4byte_to_long_(CODE).ubi" к сожалению , и [spoiler title=делаете то о чём предупредил Ув.Sancho]C:\Users\SL\AppData\Local\Temp\flprog\pr10\pr10.ino: In function 'void loop()':
C:\Users\SL\AppData\Local\Temp\flprog\pr10\pr10.ino:32:113: warning: left shift count >= width of type
out_100076728_1 = ((four_100076728_1 << 0) & 0xFF) + ((three_100076728_1 << 8) & 0xFFFF) + ((two_100076728_1 << 16) & 0xFFFFFF) + ((one_100076728_1 << 24) & 0xFFFFFFFF);
^
C:\Users\SL\AppData\Local\Temp\flprog\pr10\pr10.ino:32:152: warning: left shift count >= width of type
out_100076728_1 = ((four_100076728_1 << 0) & 0xFF) + ((three_100076728_1 << 8) & 0xFFFF) + ((two_100076728_1 << 16) & 0xFFFFFF) + ((one_100076728_1 << 24) & 0xFFFFFFFF);
[/spoiler]
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 13:26
ElectroMechaniC
тоесть моя последовательность это и есть преобразование в десятичное число / на 100 ?
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 14:33
Sancho
ElectroMechaniC писал(а): 05 окт 2018, 13:26тоесть моя последовательность это и есть преобразование в десятичное число / на 100 ?
Да, с предварительным отбрасыванием четырёх старших битов. Почему они лишние - не знаю...
Отправлено спустя 35 минут 50 секунд:
А вот мой любимый "режим" сложения/собирания байтов. При этом сама переменная "out" не используется

Использую его при передаче/приёме по I2C, при работе с внешней памятью при размере переменной более одного байта, флоат в том числе.
Разборка почти аналогично.
Код: Выделить всё
byte* ptrin_x;
ptrin_x = (byte*)(& out );
*ptrin_x = in_H_byte;
*(ptrin_x+1) = in_h_byte;
*(ptrin_x+2) = in_l_byte;
*(ptrin_x+3) = in_L_byte;
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 19:53
Labu559
Sancho писал(а): 05 окт 2018, 12:33Если что, в конце дописать:
out = (out & 268435455) / 100.0;
Теперь разрешите мне
усомниться. 
и сменить тип данных выхода на...?
Sancho писал(а): 05 окт 2018, 14:33Почему они лишние - не знаю...
Может потому, что не влезут во float? Я потому и писал о double и вынес деление на 100,0 из блока.
[spoiler title=Числа с плавающей точкой ]Типы данных с плавающей точкой хранятся в памяти иначе, чем целочисленные. Внутреннее представление вещественного числа состоит из двух частей — мантиссы и порядка. Величины типа float занимают 4 байта, из которых один двоичный разряд отводится под знак мантиссы, 8 разрядов под порядок и 23 под мантиссу. Мантисса — это число, большее 1.0, но меньшее 2.0. Поскольку старшая цифра мантиссы всегда равна 1, она не хранится.[/spoiler]
Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 20:07
Sancho
Labu559 писал(а): 05 окт 2018, 19:53Может потому, что не влезут во float?
Показания одометра не влезли во флоат...

Как применить формулу к последовательности байт?
Добавлено: 05 окт 2018, 20:17
Labu559
Sancho писал(а): 05 окт 2018, 20:07Показания одометра не влезли во флоат
Александр, ну так не честно. Откуда мне знать и зачем, что речь идёт об одометре? Это первый раз упомянулось в предыдущем 14-м сообщении. Для меня показатель - калькулятор программиста и 32-х или ставшее уже 28-и битное слово разделённое на 100.0. И ещё,
Sancho писал(а): 05 окт 2018, 12:33Эта операция уберёт четыре старших бита в числе, 32 битном.
которые всегда, при любом значении А будут == 0, и после чего не влезают ещё 4 старших бита этого же А при значениях больше 127 (0xF). Может тогда есть смысл облегчить страдания Arduino и вставить строку if (A>0xF) A=0xF;
Пожалуй лучше объяснит проект ниже с максимальными значениями, которые могут принимать байтовые B,C,D и переключением значения A с 255(0xFF) к 127(0x0F). Включать компиляцию плат при проверке.
Как применить формулу к последовательности байт?
Добавлено: 06 окт 2018, 09:56
Sancho
Labu559 писал(а): 05 окт 2018, 20:17которые всегда, при любом значении А будут == 0, и после чего не влезают ещё 4 старших бита этого же А при значениях больше 127 (0xF). Может тогда есть смысл облегчить страдания Arduino и вставить строку if (A>0xF) A=0xF;
Пожалуй лучше объяснит проект ниже с максимальными значениями, которые могут принимать байтовые B,C,D и переключением значения A с 255(0xFF) к 127(0x0F).
Может я и не сильно шарю в С++, но как 127 == 0xF, 0x0F ???? Я всегда считал F==15.....

Пойду учится...
Как применить формулу к последовательности байт?
Добавлено: 06 окт 2018, 12:09
Labu559
Sancho писал(а): 06 окт 2018, 09:56Может я и не сильно шарю в С++, но как 127 == 0xF, 0x0F ????
Александр, ну елки-палки, никто не сомневается в тебе, даже более того, я уверен что ты прекрасно понял, что я имел ввиду под "A с 255(0xFF) к 127(0x0F)", хотя должен был написать 0x000000FF и 0x0000000F , и как это [spoiler title=выглядит на калькуляторе где гасятся незначащие нули]
Calc.png
[/spoiler]. Хорошо если это поможет нашему взаимопониманию и решению проблемы /задачи ТС, - у меня с этим произошла субботница. Давай перейдём к помощи человеку, ведь там явно что-то не так. Я вчера попробовал обсчитать сколько-же влезает в Флоат с одним знаком после запятой, задавшись вопросом, неужели у меня так всё плохо с Си, хотя и никогда не утверждал обратное. У меня получилось 4194672,0 и с двумя знаками- 42945376,00. В проекте TestFloat.flp, после всех действий, максимальное число получается- 2684354,5. Это хоть с твоим (исправленным) блоком, хоть с моим. Наверное я тоже
Sancho писал(а): 06 окт 2018, 09:56Пойду учиться...

Как применить формулу к последовательности байт?
Добавлено: 06 окт 2018, 13:14
Sancho
[ref]Labu559[/ref], Василий, hex 0xF или 0x0F - это dec 15, а 127 - всего на 1 бит(старший) меньше 255, и это уже 0x7F.
Это и ввело меня в заблуждение.
Субботница у меня будет сегодня к вечеру, а
теста, результатов потока наших мыслей/идей [ref]ElectroMechaniC[/ref] пока не провёл/выложил.
Отправлено спустя 8 минут 26 секунд:
Labu559 писал(а): 05 окт 2018, 20:17И ещё,
Sancho писал(а): ↑Вчера [12:33]
Эта операция уберёт четыре старших бита в числе, 32 битном.
которые всегда, при любом значении А будут == 0, и после чего не влезают ещё 4 старших бита этого же А при значениях больше
127 15
Не могу согласится.
16777216 - это единица в старшем байте слова. Почему я не могу умножить её на любой байт?
О преобразовании во флоат пока молчу.
Как применить формулу к последовательности байт?
Добавлено: 06 окт 2018, 13:44
Labu559
Да и я как-то не очень и придаю словам значение при тех.обсуждениях (у многих языковые барьеры), мне со схемами и диаграмами и т.п. проще, потому и в связи с озвученными намерениями по субботнице
Sancho писал(а): 06 окт 2018, 13:14Субботница у меня будет сегодня к вечеру
Саша, посмотри, пожалуйста, методы и результаты в этом проекте. С 4-й платой- понятно и так, выше писали уже. Я же понимаю, что Флоат- тип данных одинарной точности, но чтобы старших 4бита так мизерно влияли на показания в 3-й плате (если я правильно понял озвученный тобою алгоритм) и вообще не влияли на 1и2-й плате. Вот о чём я, чем больше пытаюсь объясниться словами- тем больше сам запутываюсь. И ещё мне жаль, что ушёл из обсуждения ув.[ref]AlexCrane[/ref]. Спасибо!
Как применить формулу к последовательности байт?
Добавлено: 06 окт 2018, 14:04
Sancho
Labu559 писал(а): 06 окт 2018, 13:44но чтобы старших 4бита так мизерно влияли на показания в 3-й плате (если я правильно понял озвученный тобою алгоритм) и вообще не влияли на 1и2-й плате. Вот о чём я. Спасибо!
[ref]Labu559[/ref], Василий, ты подал не в том порядке - сверху младшие, снизу старшие...