Pull to refresh

Comments 20

А у вас будет возможность конвертировать ваш проект в wasm ?

Я не думаю, что wasm - это одна из целей проекта. Есть и делать какое-то web API по аналогу с веб-интерфейсом беспородных девайсов, то вряд ли это необходимо. Текущая библиотека, на которую пал выбор, ориентировать на usb-подключаемые устройства с возможностью перевода в DFU режим (DFU Mode). Для лучшего понимания, это может быть внешняя камера, клавиатура, мышь или палочка из Гарри Поттера, которая линкуется через приёмник в usb порте компьютера.

Имхо, вводные части в виде отдельных статей не нужны. Если хотите начать цикл, то начинайте его сразу с первой части/темы, в которую и включайте введение. А то я зашёл и кроме введения ничего не увидел, т.е. ничего нового не узнал и потратил время зря.

Спасибо за прочтение и подсказку.
Подсмотрел Вашу статью по crackme (часть 1) и сразу понял, почему Вы потеряли время на моей статье. :)
Действительно, в этой статье в основном философская тематика. Нужно будет скорректировать теги, чтобы содержимое было более предсказуемым.
В следующих публикациях обязательно исправлюсь и постараюсь порадовать технического читателя.

Подсмотрел Вашу статью по crackme (часть 1) и сразу понял, почему Вы потеряли время на моей статье. :)

Тут дело только в том, что это не статья, а введение к статье. Может быть я и узнал бы что-то новое, может быть и нет, это не столь важно. Я просто иногда вижу, что некоторые начинают цикл статьёй, в которой есть только введение, вот и решил написать, что так делать не стоит. Представьте, вам пришёл журнал "Наука и техника", в нём вы увидели заголовок "Создаём модель ракеты в домашних условиях", а под ним только введение и слова "продолжение следует". Будет немного обидно.

Вспомнилась история о журнале «Юный техник» во времена СССР. За неимением патентной практики в Советском Союзе мало кто заботился о каких-то авторский правах, а технари из Японии читали этот журнал и патентовали практически всё подряд :D

Вот интересно... Почему эта статья прошла, а меня, со статьей такого типа, загнобили и не пропустили?

Так и запишем.. "поток мыслей"

Вообщем-то читается легко, жаль не совсем ясно какую задачу ставил автор и какой ответ дал. Может в следующей статье прояснится

Мало библ под плюсы, вопль души!

Лайк этому господину. Он разделяет мою боль!

здесь я опешу

От чего Вы опЕшите, если не секрет?

найдёте только мой код, и здесь я опешу и попрошу его смотреть

ОПЕ́ШИТЬ, -шу, -шишьсов. Разг. Прийти в замешательство, растеряться от неожиданности, удивления и т. п.

Я опешил в том, что каждый может найти мой старый код. Он буквально первой ссылкой вылез по запросу, но надеюсь, что это просто персонализация.

Как будто более употребительна конструкция "опешил от того, что..."

/* Случайно, шла мимо, извините :) */

Справедливо :)

Ничего не понятно, но очень интересно )

Что там за глобальная переменная _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 из документации.

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

Я обязательно сделаю себе заметку и в будущем пересмотрю расчетную часть парсинга пакетов.

Мне жаль, что ставить больше одного лайка на комментарий нельзя, иначе был я влил весь предел в Ваш комментарий. Вы прекрасны, спасибо. :)

На моей памяти никто даже не думал проверять код, видя его результат

shellshock в bash жил 10 лет, и никто не видел.

Sign up to leave a comment.

Articles