Comments 20
А у вас будет возможность конвертировать ваш проект в wasm ?
Я не думаю, что wasm - это одна из целей проекта. Есть и делать какое-то web API по аналогу с веб-интерфейсом беспородных девайсов, то вряд ли это необходимо. Текущая библиотека, на которую пал выбор, ориентировать на usb-подключаемые устройства с возможностью перевода в DFU режим (DFU Mode). Для лучшего понимания, это может быть внешняя камера, клавиатура, мышь или палочка из Гарри Поттера, которая линкуется через приёмник в usb порте компьютера.
Имхо, вводные части в виде отдельных статей не нужны. Если хотите начать цикл, то начинайте его сразу с первой части/темы, в которую и включайте введение. А то я зашёл и кроме введения ничего не увидел, т.е. ничего нового не узнал и потратил время зря.
Спасибо за прочтение и подсказку.
Подсмотрел Вашу статью по crackme (часть 1) и сразу понял, почему Вы потеряли время на моей статье. :)
Действительно, в этой статье в основном философская тематика. Нужно будет скорректировать теги, чтобы содержимое было более предсказуемым.
В следующих публикациях обязательно исправлюсь и постараюсь порадовать технического читателя.
Подсмотрел Вашу статью по crackme (часть 1) и сразу понял, почему Вы потеряли время на моей статье. :)
Тут дело только в том, что это не статья, а введение к статье. Может быть я и узнал бы что-то новое, может быть и нет, это не столь важно. Я просто иногда вижу, что некоторые начинают цикл статьёй, в которой есть только введение, вот и решил написать, что так делать не стоит. Представьте, вам пришёл журнал "Наука и техника", в нём вы увидели заголовок "Создаём модель ракеты в домашних условиях", а под ним только введение и слова "продолжение следует". Будет немного обидно.
Вот интересно... Почему эта статья прошла, а меня, со статьей такого типа, загнобили и не пропустили?
Пожалуйста, проверьте список советов и общие правила для публикаций. В случае чего свяжитесь с модерацией Хабра для выяснения причин отклонения. :)
Так и запишем.. "поток мыслей"
Вообщем-то читается легко, жаль не совсем ясно какую задачу ставил автор и какой ответ дал. Может в следующей статье прояснится
здесь я опешу
От чего Вы опЕшите, если не секрет?
найдёте только мой код, и здесь я опешу и попрошу его смотреть
ОПЕ́ШИТЬ, -шу, -шишь; сов. Разг. Прийти в замешательство, растеряться от неожиданности, удивления и т. п.
Я опешил в том, что каждый может найти мой старый код. Он буквально первой ссылкой вылез по запросу, но надеюсь, что это просто персонализация.
Ничего не понятно, но очень интересно )
Что там за глобальная переменная _isWithFracture?
Либо две функции делать:
public double ParseLengthValue(byte a, byte b, byte c)
{
double val;
bool negativeSign = (a & 0b10000000) > 0;
int tmp = ((((a & 0b01111111) << 16) | (b << 8) | c) & 0b011111111111111111111111);
if (negativeSign)
{
tmp = (~tmp) & 0b011111111111111111111111;
}
val = tmp / 64.0;
return negativeSign ? -val : val;
}
public double ParseLengthValueWithFracturee(byte a, byte b, byte c)
{
double val;
bool negativeSign = (a & 0b10000000) > 0;
int intPart = 0;
double fracPart = 0;
//val = intPart + fracPart;
if (negativeSign)
{
intPart = ((~a & 0b01111111) << 10) | ((~b & 0b11111111) << 2) | ((~c & 0b11000000) >> 2);
fracPart = (c & 0b00111111) / (double)0b00111111;
fracPart = 1 - fracPart;
}
else
{
intPart = ((a & 0b01111111) << 10) | ((b & 0b11111111) << 2) | ((c & 0b11000000) >> 2);
fracPart = (c & 0b00111111) / (double)0b00111111;
}
val = intPart + fracPart;
return negativeSign ? -val : val;
}
Либо условную компиляцию:
public double ParseLengthValue(byte a, byte b, byte c)
{
double val;
bool negativeSign = (a & 0b10000000) > 0;
#ifdef IS_FRACTURE
int intPart = 0;
double fracPart = 0;
//val = intPart + fracPart;
if (negativeSign)
{
intPart = ((~a & 0b01111111) << 10) | ((~b & 0b11111111) << 2) | ((~c & 0b11000000) >> 2);
fracPart = (c & 0b00111111) / (double)0b00111111;
fracPart = 1 - fracPart;
}
else
{
intPart = ((a & 0b01111111) << 10) | ((b & 0b11111111) << 2) | ((c & 0b11000000) >> 2);
fracPart = (c & 0b00111111) / (double)0b00111111;
}
val = intPart + fracPart;
#else
int tmp = ((((a & 0b01111111) << 16) | (b << 8) | c) & 0b011111111111111111111111);
if (negativeSign)
{
tmp = (~tmp) & 0b011111111111111111111111;
}
val = tmp / 64.0;
#endif
return negativeSign ? -val : val;
}
В этой функции все прекрасно... примерно такие шедевры получаются, если писать код, не приходя в сознание (как оно и рассказано в статье):
(b << 2) | (c & 0xC0) >> 2 -- явная ошибка со сдвигом >>2, должно быть >>6, иначе биты друг на друга накладываются.
А если это исправить, то получается, что a b c суть части 24-битного значения, которое делится на 18-битную целую и 6-битную дробную часть (в обеих ветках кода, ибо / 64.0 суть intPart + fracPart/64.0
Под вопросом деление fracPart/63.0 в _isFracture части. Может и так быть, конечно, ибо мы не знаем спецификацию входных данных, но я не вижу смысла в таком представлении данных (получается, что целые значения в таком варианте представлены двумя различными вариантами с 0 и 63 в fracPart, и это еще и приводит к уменьшению разрешения представимых данных)
Чую, что что-то не так и с negativeSign. Опять же, без спецификации не понятно, но сочетание ~ и - меня сильно смущает (с учетом того, что такое binary complement), и отдельные танцы с бубнами с fracPart. Я бы в такой функции обязательно оставил комментарий о том, как именно выглядят исходные данные, чтобы можно было разобраться потом.
EDIT: заморочился нашел документацию на FreeD. Видимо, это парсинг вот этого:
"The value is expressed in millimetres as a 24-bit twos-complement signed number, where the most-significant bit (bit 23) is the sign bit, the next 17 bits (bits 22 to 6) are the integer part and the remaining bits (bits 5 to 0) are the fractional part; alternatively, this may be thought of as a signed integer value in units of 1/64 mm. The range of values is from -131,072.0 mm (800000 hex) to nearly +131,072.0 mm (7FFFFF hex)"
То есть авто заморочился и написал оба подхода к решению одной и той же задачи и обе ветки кода должны всегда возвращать одинаковый результат. По факту - в ветке с fracPart - баг с делением на 63 (привносится небольшая ошибка на практически всех значениях) и случайно правильный результат на отрицательных значениях (из серии "ответ правильный, а решение нет"), а в "целочисленной" ветке - ошибка на 1/64 мм на всей отрицательной половине входных значений, включая даже и 0x800000 из документации.
На моей памяти никто даже не думал проверять код, видя его результат, а отрабатывал он много лет весьма стабильно, передавая с незаметной погрешностью параметры зума и фокуса с енкодеров на объективе.
Я обязательно сделаю себе заметку и в будущем пересмотрю расчетную часть парсинга пакетов.
Мне жаль, что ставить больше одного лайка на комментарий нельзя, иначе был я влил весь предел в Ваш комментарий. Вы прекрасны, спасибо. :)
Дневник альтруиста. Причины