Задать вопрос
  • На чем и как пишутся протоколы?

    @tomatho
    На бумаге, на английском языке, и раздел называется документация.
    Ответ написан
    Комментировать
  • Не работают точки останова, в чем может крыться причина?

    @tomatho
    Иди в модули, и проверяй подключились ли символы.
    Debugger->Windows->Modules (по памяти пишу, мб не там)
    Суть: там список всех dll с пометками symbols loaded / not found и возможностью посмотреть подробности.

    Если подключились, то они могли подключится не оттуда откуда надо.
    Поэтому рекомендую удалить все файлы символов из папки проекта.
    Затем пересобрать проект.

    Не знаю на счёт CLI но у C++ ещё может быть проблема с rebase.
    Если exe/dll загрузился не по его обычному Base Address, то символы тоже могут не работать,
    это решается добавкой в настройке проекта насильно другого Base Address по умолчанию.
    Для exe не загрузится по обычному Base Address это редкость, а вот для dll обычное дело.

    Так же, у меня была проблема с отладкой обычной C++ dll именно из-за того, что я вместо тулсета самой 2015 студии, выбрал тулсет 2010-й студии. Breakpoint-ы из-за этого не работали.
    В таком случае можно отлаживать под 2015, а собирать Release под нужным вам тулсетом.
    Ответ написан
  • Как посчитать центр тяжести человека используя Kinect?

    @tomatho
    Если требуется приблизительно предположить местоположение центра масс исходя из табличных данных которые мы предполагаем весят данные части тела, то ваша формула для координаты x верна, а для всех остальных координат аналогично.
    Но это только если у всех x одна общая система координат, и эти координаты должны быть центрами масс частей тела, и тогда центр масс тоже будет в этой же системе координат.

    На всякий случай, вдруг пригодится, если вы не знали, простая формула для середины отрезка:
    x = (x1 + x2)/2
    y = (y1 + y2)/2
    z = (z1 + z2)/2

    Применительно к кинекту ничего не знаю. Думаю массы по координатам частей тела тоже можно определить приблизительно, если есть существенная выборка и исходя из гипотезы, что чтобы не упасть человеку нужно удерживать центр масс в некоторой области под собой. Но это слишком сложно, и сомневаюсь в целесообразности этого.
    Ответ написан
    Комментировать
  • Как быстро, но качественно реализовать чат в экосистеме Bitrix?

    @tomatho
    Быстро и качественно с битриксом не совместимо.
    Извините за моё личное мнение.
    Когда мои знакомые (и я тоже) слышат "битрикс" - убегают в ужасе.
    Тут можно даже анекдот придумать:
    - Говори пароль от админки
    - Нет! Я ни за что вам не дам доступ!
    - Парни несите битрикс
    - НЕТ Я ВСЁ СКАЖУ ТОЛЬКО НЕ БИТРИКС.
    Ответ написан
    Комментировать
  • Какие есть актуальные онлайн соревнования по программированию?

    @tomatho
    Не знаю на счёт "актуальности"
    Очень весёлые и увлекательные: codingame.com
    Ещё:
    Google CodeJam
    Russian Code Cup
    Russian AI Cup
    VK Cup
    TopCoder
    Defcon (CTF)
    Это так, как говорят from top of my head.
    Ответ написан
    Комментировать
  • C++. Как происходит возвращение локального объекта функциями?

    @tomatho
    Для локальных переменных всегда вызывается деструктор, поэтому есть техники использования этого свойства для некоторых нужд, типа лока мьютекса в конструкторе, и анлока в деструкторе.

    Обычные указатели хранят адрес. Для обычных указателей деструктор ничего не делает.
    А вот если локальная переменная представляет из себя не указатель, или умный указатель, то в его деструкторе может что-то быть, тем самым объект может высвободить память, либо произвести какие-либо другие манипуляции.

    Умные указатели позволяют более гибко управлять памятью. (shared_ptr, unique_ptr...)
    Они с технической точки зрения ничем не отличаются от обычных классов (структур).
    Им просто заранее ради вашего удобства написали подходящие реализации конструкторов, деструкторов, и других операторов.

    После высвобождения памяти адрес не перестаёт быть адресом, поэтому все манипуляции остаются возможными, кроме чтения и записи. Это уже как повезёт. Другое дело, что это не нормальное поведение - читать / писать высвобожденную память. Она уже может быть занята чем-то другим, либо изменена.

    Поэтому: никогда не возвращайте ни ссылки, ни адреса локальных переменных, за исключением тех, которые по факту глобальные: например те, которые объявлены как static.
    Однако такая static переменная находится в единственном экземпляре, а значит к ней нельзя будет одновременно обратиться из нескольких потоков. Точнее можно, но это не нормально, приведёт к ошибкам.

    Ах да, забыл ответить на заголовок.
    Точно не знаю, сначала опишу как можно это понимать, а потом уже укажу какую точность не знаю.

    Можно это понимать так: вы объявляете в вызывающей функции (caller) локальную переменную, и потом результат вызова присваиваете этой переменной. Эта переменная находится в стеке вызывающей функции (caller).
    В функции которую вы вызываете (callee) тоже есть локальная переменная результата.
    И после того как вызов закончился, caller присваивает результат от callee через оператор копирования.
    То есть
    1. Конструктор переменной в которую будет возвращён результат в функции из которой происходит вызов (caller). Кроме случая когда вызов является одним из параметров конструктора.
    2. Конструктор результата в функции которая вызвана (callee)
    3. Манипуляции с результатом (если есть таковые)
    4. Оператор копирования, кроме случая когда вызов является одним из параметров конструктора.

    Что за конструктор с параметром вызова? Ну например так:
    #include <string>
    int meaning_of_life()
    {
      return 42;
    }
    
    std::string wat()
    {
      return "wat"; // тут будет вызван std::string("wat")
    }
    
    int main()
    {
      int a(meaning_of_life()); // тоже самое, что и int a = meaning_of_life();
      std::string s(wat()); // тоже самое, что и std::string s = wat();
      return 0;
    }

    В таком случае результат используется прямо в конструкторе, поэтому оператор копирования не нужен. В таком случае конструктор называется конструктором копирования.

    По поводу точностей. Не знаю как стандарт регламентирует где должен и как передаваться результат. А так же не знаю, есть ли оптимизации которые пишут из callee прямо в caller.
    На StackOverflow пишут что есть у компиляторов оптимизации которые передают результат по ссылке или указателю, чего-бы это не значило.

    И наконец: ссылки ничем не отличаются от указателей в техническом плане. Это просто синтаксический сахар.

    Поправьте меня если я где-либо не прав. Буду рад.
    Ответ написан
  • Как решить проблему с dll?

    @tomatho
    Дело в том, что у тебя в C++ так называемый unmanaged code.
    Проще всего его вызвать как-то так:
    using System.Runtime.InteropServices;
    
    [DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern int Card();

    При этом Assembly.Load не нужен. Потому что он для managed. Reflection как бы намекает.
    Можно ещё обернуть в C++ так чтобы он стал managed, но это лучше гугл.
    Поля этих ответов слишком узкие чтобы это вместить, да и я не знаю деталей.

    Пока не забыл: битность dll должна совпадать с битностью приложения.

    В MSDN написано, что System.BadImageFormatException может быть если не указан /fixed:no при компиляции.
    Ответ написан
    Комментировать
  • Как систематизировать и структурировать знания?

    @tomatho
    Зачем систематизировать знания?
    Ассоциативные ссылки сами всё нужное вытащат из твоей памяти когда надо будет.
    Если не вытащили - значит не знаешь.

    Хотя... вероятно это может помочь если надо найти пробелы в знаниях.
    Правда чем они плохи? Когда на эти пробелы наткнёшься тогда и черпай.
    По крайней мере я так думаю. Сейчас так думаю. Завтра мб уже не буду так думать, никто не знает.
    Ответ написан
    2 комментария
  • Как подключит стороннюю ,dll в VS?

    @tomatho
    Ваша pragma нужна если вы статически линкуетесь с библиотекой, то есть, dll после этого не понадобится. (кроме нестандартных случаев)
    вместо pragma можно в свойствах проекта, во вкладке C++->Linker->Input->Additional Dependencies прописать путь к .lib

    Важно: если библиотека линкуется статически (через .lib), то LoadLibrary() не нужен!
    LoadLibrary нужен для динамической загрузки .dll
    Однако если LoadLibrary() вызван на уже подгруженной .dll он всё же должен вернуть HMODULE.

    И да, воспользуйтесь CFF Explorer, может подгружаемая вами .dll не может найти свои зависимости.
    Для этого зайдите во вкладку Dependency Walker.
    И как уже верно сказали: 32-битная версия программа не может работать с 64-битными библиотеками, вообще не может. Аналогично 64-битные программы не могут работать с 32-битными библиотеками. Вообще не могут.
    Ответ написан
    Комментировать
  • Unity - клиент | Node.js + Socket.io + Json - сервер == Возможно и как осуществить?

    @tomatho
    Это скорее ответ на ответ.
    Парсинг JSON хорошей либой не затратнее чем чтение обычного текста.
    Просто не все JSON библиотеки хорошо оптимизированы.

    Проблемой может оказаться лишь то, что "пакет" в json больше чем "сырые" байты.
    То есть, это скажется на требование к скорости интернет соединения.
    Однако обычно проблема не в скорости, а в пинге. Но можно приблизительно оценить требуемый bandwidth.
    Кроме того можно использовать JSON на этапе прототипирования.
    Но тут может закрасться "ничто так не вечно как временное решение".

    Ещё один минус JSON - нужно хорошо написать обработку ошибок, и попыток взлома вашего протокола обмена пакетами.
    Могут например на ваш сервер прислать JSON размером в гигабайт, и ваша JSON библиотека упадёт.
    Либо пришлют что-то другое.

    Проблема с сырыми байтами в том, что надо поддерживать их формат с обеих сторон.
    Разные версии клиентов придётся либо блокировать пока они не обновятся до новой версии, либо писать жуткие портянки для обработки сырых байтов. Хотя JSON тут мало чем поможет.

    И ещё, я не уверен, что ваш код парсящий сырые байты с учётом порядка байт, будет быстрее чем JSON.parse из под капота V8 (Node.js)
    Ответ написан
    Комментировать
  • Как оптимально обойти все вершины графа?

    @tomatho
    Для количества вершин порядка 15: (больше 15 вершин будет работать уже сравнимо дольше)
    1. Запускаем флойда чтобы получить матрицу 15х15 путей как из одной вершины быстрее всего попасть в другую. Либо 15 обходов в глубину (та же скорость, тот же эффект).
    2. Перебираем все перестановки чисел от 1 до 15, которых как известно 15! = 1307674368000.
    3. С помощью матрицы полученной на первом шаге, считаем общее количество шагов,
      которые получились бы если бы мы проследовали по вершинам в порядке перестановки.
    Ответ написан
    Комментировать
  • Порядок столбцов табличной переменной в процедуре?

    @tomatho
    В INSERT укажи порядок значений через соответствующий синтакс:
    INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,  
        ModifiedDate)  
    VALUES (N'Square Yards', N'Y2', GETDATE());

    Это пример из MSDN
    Ответ написан
  • Параллельное программирование, на какие операции разбить?

    @tomatho
    В первую очередь параллель это:
    for (int k = 0; k < i; k++)
        temp = temp + U[k, i] * U[k, j];

    Просто разбей диапазон значений j на M ядер.
    Проще всего так. Если у нас есть N операций, и мы хотим разбить на M ядер то это (N+M-1)/M с округлением вниз операций на ядро.
    Update: Не всё так просто как мне казалось, в общем, это не ответ.

    Можно другие попробовать распараллелить, но это это самая ресурсоёмкая часть.
    Вообще хорошо гуглится описание распараллеливания этого алгоритма.
    Ответ написан
    9 комментариев
  • Поиск простых больших чисел на C# BigInteger?

    @tomatho
    Слишком большие числа для таких алгоритмов. Эти алгоритмы слишком медленные.
    Другими словами, мой ответ такой: Этот код работает, просто вам не хватит терпения дождаться его завершения.
    Update: modulo, modulo1. Что в оригинальном алгоритме, что в итоге - несёт какую-то бессмыслицу.

    Чтобы улучшить скорость, используйте вместо BigInteger обычный long.
    Этот тип позволит поддерживать числа до 9223372036854775807.
    А это число существенно больше тех чисел, которые можно проверить на простоту приведёнными выше алгоритмами, за разумное время.

    Что касается скоростных тестов на простоту, то можете реализовать тест Рабина-Миллера.
    Он сравнительно прост, и очень эффективен. Проблема его лишь в том, что он отвечает:
    "Это число простое с вероятностью 99.9999%"
    Зато вероятность эта может быть выбрана произвольно высоко.
    Например, он может ошибаться в среднем в одном случае из миллиона.

    Что касается точных проверок на простоту, такие реализовать сложнее.
    И я не думаю что у вас стоит такая задача.
    Ответ написан
    1 комментарий
  • Атлас спрайтов: как загружать, маппить?

    @tomatho
    Если я правильно понял, охото
    Draw(GREENERY_BUSH)
    При этом иметь возможность в каком-то CSV указать в строке номер тайла.
    Ну так почему бы не сделать:
    const int MAX_ID = 123;          // MAX_ID - первый неиспользуемый номер
                                     // извините не придумал лучше имя массиву
    private string convert[MAX_ID];  // подразумеваю что "настоящий" идентификатор тайла имеет тип string.
    private DrawInternal(string id)
    {
        // тут обычный код для отрисовки
    }
    public void Draw(int id)
    {
        DrawInternal(convert[id]); // подставляем нужный id
    }
    public void loadCSV(/* параметры */)
    {
        // грузим CSV и формируем convert массив
    }
    Ответ написан
    Комментировать
  • Как готовиться к олимпиадам?

    @tomatho
    Не знаю на счёт других областей, так что пишу только про ACM ICPC и смежные (похожие) так:
    Чтоб стать крутым, надо ежедневно по 2-3 часа минимум решать задачи в день.
    На всевозможных сайтах агрегаторах задач типа codeforces.ru, opencup.ru, topcoder.com, google codejam, acm.timus.ru и много много других.
    Участвовать во всех проходящих онлайн соревнованиях.

    Напоминает правило 10 тысяч часов. Есть такое мнение, что люди становятся профессионалами не из-за таланта, а по факту вложения человеко-часов в своё занятие.
    Однако, есть и уникумы, по типу Геннадия Короткевича (загугли, почитай).
    Лучшим в любой области стать почти невозможно. Однако шанс есть.

    Я дальше полуфинала ACM ICPC не проходил, так как был слишком ленив и решал задачи пару раз в месяц.
    Ах, совсем забыл: для чемпионства важен опытный тренер. Чтобы не тратить время на всякую чушь, и эффективнее "качаться".

    Ещё: я бы предпочел обсуждение с матёрым олимпиадником конкретного алгоритма, чем чтение литературы по онному. Очень важно скорость написания алгоритма, и легкая запоминаемость. Какие-то приёмы по его хорошему модифицированию, если в задаче требуется его мелкая модификация. Чтение кода лидеров тоже не повредит, чтобы понять как элегантнее написать.

    Многие простейшие алгоритмы можно написать элегантно и быстро, а можно долго мозговать а тут +1 индекс, или -1. А тут надо сколько прибавить? А условие <= или <. Очень много нюансов.
    Так же не повредит психологическая подготовка, если тренер могёт. Так как например меня трижды клинило на ответственных соревнованиях. Дважды на полуфинале ACM ICPC: сидишь как бревно, ничего не соображаешь, переволновался. И один раз на ВКОШП.
    Потом как только соревнование кончается (время закончилось), так сразу спадает волнение и начинаешь смотреть на задачи и думать: Что?!?! И это я не смог решить?!?!
    Ответ написан
    1 комментарий
  • Как проверить что у уравнения есть корни на отрезке?

    @tomatho
    Сначала начнём с того, что arctg(t) принимает значение sqrt(2) только в одном месте.
    Найдём это t.
    Из свойства:
    arctg( tg(z) ) = z при -pi/2 < z < pi/2
    Получаем:
    arctg( tg( sqrt(2) ) ) = sqrt(2)
    То есть, t = tg( sqrt(2) )
    Ну а теперь 2^x - |p| должно быть равно tg( sqrt(2) ) так как arctg принимает значение sqrt(2) только в одном месте. Получаем уравнение:
    2^x - |p| = tg( sqrt(2) )
    Следовательно:
    2^x = tg( sqrt(2) ) + |p|
    x = log2(tg( sqrt(2) ) + |p| )
    После чего нужно просто посчитать x и проверить находится ли x в промежутке [a, b]
    Ответ написан
    Комментировать