• Погрешность чисел в c++?

    @Mercury13
    Программист на «си с крестами» и не только
    #include <iostream>
    #include <iomanip>
    
    int main()
    {
        double q = 1.0 / 6.0;
        std::cout << std::setprecision(9) << q << std::endl;
        return 0;
    }


    Float не годится, поскольку не даёт такой погрешности.
    Ответ написан
    Комментировать
  • Как подключить 2 монитора VGA к 1 компьютеру?

    @Mercury13
    Программист на «си с крестами» и не только
    Мы уже выяснили, что у вас есть разъём DVI и можно подключить второй монитор. ЕСТЬ ДВА ВАЖНЫХ МОМЕНТА.

    1. Встроенные и дешёвые видяхи обычно не могут выводить на два монитора, там один RAMDAC (или как сейчас эта деталь называется?) и разъёмы просто запараллелены. СМОТРИТЕ СПЕЦИФИКАЦИЮ.

    2. Есть два вида DVI, я их называю DVI+ и DVI−, по виду крестика на разъёме.
    Если крестик полный, в DVI есть VGA-линии, и покатит любой пассивный переходник, который можно купить за сотню на компоразборках или выпросить у знакомого сисадмина (если ты в Киеве — приходи, дам, остался один).
    Если неполный — нужны активные переходники вроде такого.

    https://ru.aliexpress.com/item/32884792319.html?sp...

    Сам удивился, что они на Али дёшевы, думал, 10…20$ стоят.

    Допустим, на моей старенькой 750Ti есть два DVI: один DVI−, другой DVI+. Так что если сменю карточку, а старую отдам брату — видимо, он сможет подключить её к старому монитору. Но только к одному: хочет второй — только DVI/HDMI. Или через активный переходник. Кстати, там четыре разъёма, но спецификации говорят: до 3 мониторов.
    Ответ написан
    3 комментария
  • Как законно использовать код который распространяется под MIT?

    @Mercury13
    Программист на «си с крестами» и не только
    В любом доступном месте About или сопроводительной документации.
    Если текстовая документация — любят делать файл «copying» с указанием всех, чей код позаимствован.
    Если система в вебе — лицензию должен видеть вебмастер (например, в файле «.copying», который не показывается сервером), а не конечный пользователь.
    В клиентском вебе достаточно где-то в .js сделать закомментированную ссылку на лицензию.
    Ответ написан
  • Как сделать графическую оболочку для консольного приложения?

    @Mercury13
    Программист на «си с крестами» и не только
    Вот мой код. Не законченный (завязанный на моей собственной библиотеке абстрактных потоков, не реализована функция flush, поток ошибок намеренно не перенаправлен), но относительно действующий.

    spoiler
    class ConStream : public st::Stream
    {
    public:
        ConStream();
        ~ConStream() override;
        bool open(
                const std::wstring& aFname,
                const std::wstring& aCmdLine,
                const std::wstring& aLog);
    
        // Console does not have remainder.
        st::Pos remainder() override { return 0; }
        // Only when we bumped into end.
        size_t eof() override { return fIsEof; }
        size_t readNe (void* aBuf, size_t aSize) override;
        size_t writeNe(const void* aBuf, size_t aSize) override;
        void flush() override;
        bool isOpen() override { return fIsOpen; }
    
        bool readln(std::string& s);
        void endInput();
    
        // Shall we implement close?
        //void close() override {}
    
        // Implemented capabilities
        unsigned long caps() const override
            { return st::cRead | st::cWrite | st::cMultiplex | st::cRealtime
                | st::cSizeUnaware; }
    private:
        st::AsyncFile fLog;
        bool fIsOpen = false;
        bool fIsEof = false;
        bool fFoundCr = false;
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        HANDLE hStdOutInside, hStdOutOutside;
        HANDLE hStdInInside, hStdInOutside;
        //HANDLE hStdErrInside, hStdErrOutside;
        //bool readln(std::string& s);
    };
    
    
    ConStream::ConStream()
    {
        SECURITY_ATTRIBUTES sa;
          // Security attributes
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor = nullptr;
        sa.bInheritHandle = true;  // Help says the handle will be inherited
    
        SECURITY_DESCRIPTOR sd;
        if (isWinNT()) {       // security initialization for Windows NT
            InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(&sd, true, nullptr, false);
            sa.lpSecurityDescriptor = &sd;
        }
    
        // Stdout pipe
        // read = outside, write = inside
        CreatePipe(&hStdOutOutside, &hStdOutInside, &sa, 0);
        SetHandleInformation(hStdOutOutside, HANDLE_FLAG_INHERIT, 0);
    
        // Stderr pipe
        // read = outside, write = inside
        //CreatePipe(&hStdErrOutside, &hStdErrInside, &sa, 1024*64);  // enough for stderr?
        //SetHandleInformation(hStdErrOutside, HANDLE_FLAG_INHERIT, 0);
    
        // Stdin pipe
        // read = inside, write = outside
        CreatePipe(&hStdInInside, &hStdInOutside, &sa, 1024*10);
        SetHandleInformation(hStdInOutside, HANDLE_FLAG_INHERIT, 0);
    }
    
    
    void ConStream::endInput()
    {
        if (hStdInOutside != INVALID_HANDLE_VALUE) {
            CloseHandle(hStdInOutside);
            hStdInOutside = INVALID_HANDLE_VALUE;
        }
    }
    
    
    ConStream::~ConStream()
    {
        if (fIsOpen) {
            if (WaitForSingleObject(pi.hProcess, 2000) == WAIT_TIMEOUT) {
                TerminateProcess(pi.hProcess, 0);
            }
    
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
        }
        CloseHandle(hStdInInside);
        endInput();
        //CloseHandle(hStdErrOutside);
        //CloseHandle(hStdErrInside);
        CloseHandle(hStdOutOutside);
        CloseHandle(hStdOutInside);
    }
    
    
    bool ConStream::open(
            const std::wstring& aFname,
            const std::wstring& aCmdLine,
            const std::wstring& aLog)
    {
        if (fIsOpen)
            return false;
    
        // Fill startup info
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        size_t n = aFname.length() + aCmdLine.length() + 10;
    
        si.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        si.hStdOutput = hStdOutInside;
        si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
        si.hStdInput = hStdInInside;
        si.wShowWindow = SW_HIDE;
    
        std::wstring ws;
        ws.reserve(n);
        ws += L'"';
        ws += aFname;
        ws += L"\" ";
        ws += aCmdLine;
    
        fIsOpen = CreateProcess(
                nullptr,        // lpApplicationName
                &*ws.begin(),   // lpCommandLine
                nullptr,        // lpProcessAttributes
                nullptr,        // lpThreadAttributes
                TRUE,           // bInheritHandles
                0,              // dwCreationFlags
                nullptr,        // lpEnvironment
                nullptr,        // lpCurrentDirectory
                &si,            // lpStartupInfo
                &pi );          // lpProcessInformation
    
        if (fIsOpen && !aLog.empty())
            fLog.open(aLog.c_str(), st::File::omNew);
    
        return fIsOpen;
    }
    
    
    void ConStream::flush()
    {
    
    }
    
    
    size_t ConStream::readNe (void* aBuf, size_t aSize)
    {
        if (!fIsOpen)
            return 0;
    
        DWORD nRead;
        if (!ReadFile(hStdOutOutside, aBuf, static_cast<DWORD>(aSize), &nRead, nullptr))
            return 0;
    
        if (fLog.isOpen())
            fLog.write(aBuf, nRead);
    
        return nRead;
    }
    
    
    // Implemented write
    size_t ConStream::writeNe(const void* aBuf, size_t aSize)
    {
        if (!fIsOpen)
            return 0;
    
        DWORD nWritten;
        if (!WriteFile(hStdInOutside, aBuf, static_cast<DWORD>(aSize), &nWritten, nullptr))
            return 0;
        return nWritten;
    }
    
    
    bool ConStream::readln(std::string& s)
    {
        if (!fIsOpen)
            return false;
    
        s.clear();
        enum { SZ = 256, TIME = 30 };
        char buf[SZ + 2];
        DWORD nRead, nm1, nm2;
    
        while (true) {
            if (!PeekNamedPipe(hStdOutOutside, buf, SZ, &nRead, &nm1, &nm2))
                throwWinError();
            // Read nothing — maybe, the program has finished?
            if (nRead == 0) {
                if (WaitForSingleObject(pi.hProcess, TIME) == WAIT_OBJECT_0) {
                    // Try again
                    if (!PeekNamedPipe(hStdOutOutside, buf, SZ, &nRead, &nm1, &nm2))
                        throwWinError();
                    if (nRead == 0)
                        return !s.empty();
                    // otherwise fall out
                }
            }
            const char* start = buf;
            const char* end = buf + nRead;
            if (fFoundCr && *start == '\n') {
                ++start;
                fFoundCr = false;
            }
            for (const char* p = start; p != end; ++p) {
                switch (*p) {
                case '\r':
                    fFoundCr = true;
                    // fall through
                case '\n':
                    s.append(start, p);
                    // Read until CR
                    ++p;
                    skipRead(p - buf);
                    return true;
                default: ;
                }
            }
            // Copy the entire buffer and go on
            s.append(start, end);
            skipRead(end - buf);
        }
    }
    Ответ написан
  • Почему CharToOemW преобразует не все символы?

    @Mercury13
    Программист на «си с крестами» и не только
    А такое будет работать?

    inline const char* wtc(const WCHAR *from)
    {
      //Используется буффер -- статическая переменная
      static char buf[1024] = { 0 };
      size_t nChars = std::min<size_t>(wcslen(from), 1024 - 1);
      if (!CharToOemBuffW(from, buf, nChars)) {
        cout << GetLastError();
        exit(-1);
      }
      buf[nChars] = 0;
      return buf;
    }
    Ответ написан
  • Как отправить POST запрос с помощью C#?

    @Mercury13
    Программист на «си с крестами» и не только
    На самого себя.

    Если, например, страница example.com/test.php, то эта страница и будет action.
    Ответ написан
  • Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Например, int занимает 4 байта

    По современному консенсусу, да. Но иногда может занимать 2 байта (меньше — вроде нет).

    В случае с double можно задать абсолютно любое число

    double x = 1e500;
    Ответ статического анализатора Clang: magnitude of floating-point constant is too large for type 'double'; maximum is 1.79…E+308

    На число 1.23456789012345678901234 не жалуется, но учите матчасть — относительная точность double 52 двоичных цифры (исключая головную единицу), или около 16 десятичных.

    для чего в конце приписывают 'f' ,когда пользуются типом данных float?

    Чтобы расчёт float x; return x + 12.34f вёлся в менее точном типе float, а не double.
    А вот коду float x = 12.34; это совершенно не нужно, компилятор и сам поймёт, что преобразование double → float можно сделать при компиляции.

    Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

    Зависит от машины, но по выработанному консенсусу — float 4, double 8.
    Нестандартная (присущая x86) реализация long double имеет 10 значащих байтов, но 12 или 16 вместе с выравниванием.
    Ответ написан
    Комментировать
  • Что означают данные строки?

    @Mercury13
    Программист на «си с крестами» и не только
    Перед нами вариативный шаблон Си++11.

    Функция printTypes действует так. Для первого параметра подбираем подходящую перегрузку функции NameOf. Второй и далее — снова подставляем в функцию printTypes.

    types... t — это любое количество параметров любых типов. Которые, в свою очередь, можно рекурсивно подставить в шаблон printTypes.

    DEF_TYPENAME(float) — это использование препроцессора Си++ (никакой уже не 11), чтобы объявить несколько стандартных специализаций одного шаблона.
    Ответ написан
  • Как правильно называть переменные в заголовке функции (параметры или аргументы)?

    @Mercury13
    Программист на «си с крестами» и не только
    Одна сатана. В терминологии одних языков принято parameter, других argument.
    Ответ написан
    Комментировать
  • Посимвольный i/o vs i/o в строку (буфер)?

    @Mercury13
    Программист на «си с крестами» и не только
    Очень-очень верно! Даже на чём-то типа istringstream виртуальный вызов занимает довольно много времени, и ОЧЕНЬ желательна буферизация своими силами.
    Подтверждаю, приходилось писать код скоростного разбора XML.
    Ответ написан
    Комментировать
  • Почему нельзя передавать лямбду как аргумент шаблона?

    @Mercury13
    Программист на «си с крестами» и не только
    #include <iostream>
    
    template <class Body>
    void call(const Body& body) {
        body();
    };
    
    void test() {
      std::cout << "function" << std::endl;
    }
    
    int main() {
      call(test);
      call([]() {
        std::cout << "lambda" << std::endl;
      });
      return 0;
    }


    Дело в том, что лямбда — это объект неизвестного класса с операцией (). И только так её вызывают.
    Ответ написан
    1 комментарий
  • Правилен ли такой подход к разбиению C приложения на модули?

    @Mercury13
    Программист на «си с крестами» и не только
    Смотря в чём задача.
    Возможно, нет никаких проблем.
    Возможно, удастся вытащить общую функциональность в defines.h.
    Возможно, удастся каким-то образом разорвать порочный круг. Например, в ООП это можно делать через интерфейс.
    Ответ написан
    Комментировать
  • Как отловить момент, когда в QComboBox создаётся редактор?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    Опять приходится отвечать своими силами.
    void TimedWideComboBox::connectToEditor()
    {
        if (!lineEdit())
            return;
        connect(lineEdit(), &QLineEdit::textEdited, this, &This::origDataChanged);
    }
    
    bool TimedWideComboBox::event(QEvent* ev)
    {
        bool b = Super::event(ev);
        switch (ev->type()) {
        case QEvent::ChildAdded: {
                auto ev1 = static_cast<QChildEvent*>(ev);
                if (ev1->child() == lineEdit()) {
                    connectToEditor();
                    return true;
                }
            } break;
        default:;
        }
        return b;
    }
    Ответ написан
  • Как сделать так, чтобы CodeBlocks не ставил знаки?

    @Mercury13
    Программист на «си с крестами» и не только
    Settings → Editor → General Settings (стоит по умолчанию) → Editor Settings (стоит по умолчанию) → Indent Options → Brace completion

    5cfa263e49d5b731760499.png
    Ответ написан
    Комментировать
  • Важен ли для программиста язык?

    @Mercury13
    Программист на «си с крестами» и не только
    Профессионализм — это, с одной стороны, понимание программирования как такового, независимо от языка. С другой — это чувство библиотеки, понимание рисунка кода на том или ином языке, понимание того, что под капотом.

    Это значит: программист на C# будет слегка плавать в том, на каких библиотеках выполнить JS-задачу, и как эти библиотеки работают. Будет говорить на JS как на C# — будет получаться что-то вроде «feel myself», что, по легенде, значит «онанировать». Но это всё, надо признать, дело опыта. Нужно быть знакомым, но не нужно углубляться.
    Ответ написан
    Комментировать
  • Какая сложность алгоритма (относительно n)?

    @Mercury13
    Программист на «си с крестами» и не только
    O(n²), разумеется.
    Первый цикл выполняется O(n) раз, и второй O(n). Так что O(n²).
    Если быть точнее, те итерации, которые выполнятся,— это трапеция на квадрате n×n, никакого тебе O(n), O(n log n) и подобного не будет.
    Кстати, запись O(n/2) и O(n²/2) не имеет особого смысла — само определение символов Ландау говорит, что разница в константу не играет роли. По той же причине пишут O(n log n), не указывая, по какому основанию логарифм.

    UPD2. Запись O(n²) означает: «не превышает cn² при стремлении n→∞». Так что всё, что O(n), одновременно и O(n²). И «никакого тебе O(n)» означает, что оценку n² мы улучшить не можем.
    Ответ написан
    Комментировать
  • Исключение. Что это значит?

    @Mercury13
    Программист на «си с крестами» и не только
    Это значит: вы «сломали» память. Как правило, разыменованием «висячего» указателя или вылетом за пределы массива.
    Ответ написан
    Комментировать
  • Как договорится с художником и какие есть лицензии у изображений?

    @Mercury13
    Программист на «си с крестами» и не только
    На вопрос 2 — из некоммерческих годятся общественное достояние (Public domain = PD = CC0) и «укажи автора» (Creative Commons Attribution = CC-BY). Никакие другие лицензии CC для коммерческой игры не годятся!

    Если игра открытая — подумай, под какой лицензией она будет выпущена и совместимы ли требования с этой лицензией. Например, с GPL совместимы PD = CC0, CC-BY, CC-BY-SA.

    Разумеется, возможна ситуация, что одни части игры под одной лицензией, другие — под другой. Например, движок GPL-ный, а изображения под более строгой или более мягкой лицензией. Так, Doom (1993) имеет GPL-ный движок и коммерческое всё остальное.

    Каждую полукоммерческую лицензию приходится рассматривать по отдельности.

    Если лицензий несколько (например, CC-BY + GPL2 + GPL3) — если среди них есть хоть одна, которая тебя устраивает, порядок!
    Ответ написан
    Комментировать
  • Как вычислить интеграл с помощью формулы Симпсона?

    @Mercury13
    Программист на «си с крестами» и не только
    Перед нами типичная студенческая работа.

    Первое, что нужно сделать,— вынести расчёт интеграла в отдельную функцию. Помимо прочего, она должна принимать параметром n — количество точек разбиения. И проверьте, разумеется, работоспособность.

    Затем поднимаемся на более высокий уровень — налаживаем алгоритм выдерживания точности. Я бы написал так.
    n := 10
    yНовое := расчёт(n)
    повтор
      n := n·2
      yСтарое := yНовое
      yНовое := расчёт(n)
    пока |yСтарое - yНовое| > эпсилон
    вывести/вернуть yНовое

    Сможешь перевести на Си?
    Ответ написан
    Комментировать
  • Чем отличается NAT от обычного "роутинга"?

    @Mercury13
    Программист на «си с крестами» и не только
    Это две совершенно разные технологии. Они идут рука об руку, но никаких проблем использовать их порознь.
    DHCP без NAT — любая домосеть с «белыми» адресами, которая автоматически раздаёт их.
    NAT без DHCP — никаких проблем его сделать на обычном домашнем роутере.

    Как действует NAT. Берём и корректируем в исходящем пакете какие-нибудь параметры вроде исходящего порта (чтобы узнать, чей пакет). Заодно меняем исходящий адрес на внешний адрес сети. Когда приходит ответ, восстанавливаем исходного абонента, меняем входящий адрес на адрес этого абонента и ретранслируем его во внутреннюю сеть.

    Задача простого роутинга (который не NAT) — просто передать пакет дальше по цепочке, уменьшив TTL и определив по таблице маршрутизации, на какое из соединений надо его передавать.
    Ответ написан