Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/26: Рейтинг темы: голосов - 26, средняя оценка - 4.85
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283

Потестируйте скорость работы класса больших чисел

19.08.2015, 17:47. Показов 6181. Ответов 100
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ребятки, сделал себе небольшой классик для больших чисел.
Типа того:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
static const long long BASE = 1000000000;
static const int BASE_DIGITS = 9;
 
enum sign { positive = 1, negative = -1 };
 
struct BigInt {
 
    std::vector<int> a;
    int sign;
 
    // constructors
    BigInt() : sign(positive) { } // default constructor
}
Ну и хотелось бы сравнить, насколько он медленно работает.
C++
1
2
3
4
5
6
7
8
>TestBigInt.exe -factorial 100000
--- factorial test ---
Calculating 100000!
 big integer :  2824 ... 0
 number of decimal digits = 456574
 number of segments       = 50731
 
time : 10.961 sec.
Это на Intel Quad Q9550 2,8 GHz
Если у кого есть результаты, приведите их пожалуйста.

*мне нравятся большие числа и женщины, но с числами интереснее.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.08.2015, 17:47
Ответы с готовыми решениями:

Скорость работы id и класса
Что быстрее работает id или класс? Бывают такие моменты, что думаешь, а что лучше использовать. Да понятно если стиль повторяется много...

Обертка класса, наследование - скорость работы
1. Есть класс MyServer(использует класс TcpListener), как только MyServer ловит какое то соединение, он возвращает ссылку на экземпляр...

Конструктор класса больших чисел
Добрый вечер! Решаю следующую задачу: нужно создать класс Huge, который будет использовать массив из 50 элементов для хранения целых...

100
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
31.08.2015, 14:21  [ТС]
Студворк — интернет-сервис помощи студентам
mymedia, класс.. усё работает!
Подставил Вашу функцию вместо своего пойла.

// generate BigInt from string: "M23", "12", "12-1", 12*3, "2^3", "2^3-1" "12*2^34+3"
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    // generate BibInt from string: "M23", "12", "12-1", 12*3, "2^3", "2^3-1"  "12*2^34+3" " 
    struct invalid_format
        : public std::invalid_argument
    {
        invalid_format(const std::string& s) : std::invalid_argument(s) { }
    };
 
    const BigInt BigInt::generate_number(const std::string& str) throw(invalid_format)
    {
        // first try parse Mersenn numbers "M1", "M2" ...
        long long messen_exp = BigInt::mersenExp(str);
        if (messen_exp != 0)
        {
            return BigInt::mersenNumber(str);
        }
 
        using namespace std;
        const regex regular{ R"(^(?:(\d+)\*)?(\d+)(?:\^(\d+))?([-+]\d+)?$)" };
        // Значения по умолчанию для отсутствующих компонент выражения
        const std::array<long long, 4> defaults = { 1, 0, 1, 0 };
 
        smatch results;
        if (!regex_match(str, results, regular)) {
            throw invalid_format("'" + str + "' cannot convert to integer");
        }
 
        std::array<long long, 4> out;
        for (int i = 0; i < 4; i++) {
            if (results[i + 1] != "") {
                out[i] = stoll(results[i + 1]);
            }
            else {
                out[i] = defaults[i];
            }
        }
 
        // не все операнды присуьствуют.
        // сложение с нулём, умножение на 1, возведение в единичную степень нам не нужны. 
        if (out[0] == 1)
        {
            if (out[3] != 0)
                return BigInt::power(out[1], out[2]) + out[3];
            else
                return BigInt::power(out[1], out[2]);
        }
 
        if (out[2] == 1)
        {
            if (out[3] != 0)
            {
                return out[0] * out[1] + out[3];
            }
            else
                return out[0] * out[1];
        }
 
        // все операнды присутствуют
        return BigInt::power(out[1], out[2]) * out[0] + out[3];
    }

C++
1
2
3
4
5
6
7
8
>TestBigInt.exe -generate "3*2^5-1"
 
Generating number 3*2^5-1
 big integer :  95
 number of decimal digits = 2
 number of segments       = 1
 
time : 0.012 sec.
*надо ещё попроверять на числах побольше.
Вложения
Тип файла: rar TestBigInt.rar (50.6 Кб, 2 просмотров)
0
196 / 197 / 120
Регистрация: 27.05.2011
Сообщений: 545
06.09.2015, 12:52
SerVal, я вот тут что подумал. Надо было добавить в функцию genetate_number возможность построения отрицательных чисел. Для этого достаточно добавить необязательные +/- в регулярном выражении перед первой компонентой.
Вариант со значениями по умолчанию и с +/-
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <regex>
#include <stdexcept>
#include <string>
 
struct invalid_format : std::invalid_argument
{
    invalid_format(const std::string& s) : std::invalid_argument(s) { }
};
 
// Читает строку в формате m*b^p±s и строит большое целое.
// m — целое число; b, p, s — натуральные или ноль. Каждая из компонент
// может отсутствовать. При несоответствии формату генерируется
// исключение invalid_argument.
BigInt BigInt::generate_number(const std::string& str) throw(invalid_format)
{
    const std::regex regular { R"(^(?:([-+]?\d+)\*)?(\d+)(?:\^(\d+))?([-+]\d+)?$)" };
    // Значения по умолчанию для отсутствующих компонент выражения
    constexpr int defaults[] = { 1, 0, 1, 0 };
 
    std::smatch results;
    if (!regex_match(str, results, regular)) {
        throw invalid_format("'" + str + "' cannot convert to integer");
    }
 
    BigInt out[4];
    for (int i = 0; i < 4; i++) {
        if (results[i + 1] != "") {
            // Тут должна быть какая-нибудь функция преобразования.
            // Я предположил, что явный конструктор BigInt может
            // из строки построить число. (Кода я что-то не вижу).
            out[i] = BigInt(results[i + 1]);
        } else {
            out[i] = defaults[i];
        }
    }
 
    return out[0] * power(out[1], out[2]) + out[3];
}

Мне кажется, умножить на 1 и прибавить 0 — не так страшно в плане производительности. Максиум один прогон по разрядам числа. А возведение в единичную степень вообще ничего не стоит: только вызов функции, проверка условия и моментальный возврат. В общем, можно убрать код, который пытается не сделать лишнего и сократить функцию на 20 строк.

Впрочем, если уж так не хочется делать лишних действий, то лучше было бы совсем отказаться от значений по умолчанию и проверять наличие соответсвующих компонет непосредственно из results (результатов) распарсивания строки.
Вариант с проверкой присутствия компонент и с +/-
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <regex>
#include <stdexcept>
#include <string>
 
struct invalid_format : std::invalid_argument
{
    invalid_format(const std::string& s) : std::invalid_argument(s) { }
};
 
// Читает строку в формате m*b^p±s и строит большое целое.
// m — целое число; b, p, s — натуральные или ноль. Каждая из компонент
// может отсутствовать. При несоответствии формату генерируется
// исключение invalid_argument.
BigInt BigInt::generate_number(const std::string& str) throw(invalid_format)
{
    const std::regex regular { R"(^(?:([-+]?\d+)\*)?(\d+)(?:\^(\d+))?([-+]\d+)?$)" };
    std::smatch results;
    if (!regex_match(str, results, regular)) {
        throw invalid_format("'" + str + "' cannot convert to integer");
    }
 
    BigInt answer(results[2]);
    if (results[3] != "") {
        answer = power(answer, BigInt(results[3]));
    }
    if (results[1] != "") {
        answer *= BigInt(results[1]);
    }
    if (results[4] != "") {
        answer += BigInt(results[4]);
    }
 
    return answer;
}

Собстенно говоря, если не хотите "лишних" действий, то значения по умолчанию не нужны. Можно основываться на массиве results. Это массив строк, которые соответсвуют регулярным подвыважениям. Т.е. в results[1] хранится первая компонента числа, в results[2] — вторая и т.д. В results[0] хранится исходная строка.

ИМХО, чем меньше кода, тем меньше в нём может быть ошибок, поэтому не стоит комбинирвать два подхода: со значениями по умолчанию и с проверкой присутствия компонент в строке.

Как вам известно, спецификация исключений функции запрещает ей генерировать какие-либо исключения помимо указанных. Так вот моя функция может генерировать исключения только типа invalid_format, в случае если передана неверная строка. Все остальные случаи (например, опечатку в регулярном выражении) я считаю нешатными, и пусть лучше программа завершится с выводом отладочной информации, чем ошибка пойдёт распространяться дальше. Так будет проще исправить баг. Поэтому в вашем коде, возможно, нужно этот момент исправить. Впрочем, тут лучше реализовать ту стратегию реакции на ошибки, которая у вас принята.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 14:21  [ТС]
Цитата Сообщение от mymedia Посмотреть сообщение
Максиум один прогон по разрядам числа.
Разрядов-то - миллионы.

Ну и, как известно, интерфейс пользователя - засада ещё та.
Всегда найдётся дядя, который введёт что-нибудь непредсказуемое.
Ваша функция замечательно работает.. пусть работает.
*****
2 All:
Библиотеку маленько оптимизировал:
1. распараллелил умножение методом Карацубы - на два ядра процессора.
2. пробное деление на простые числа меньше 1 000 000 - распараллелил на все ядра процессора.
3. число теперь можно задавать в виде "2*3^4-5"
.. но всё равно очень медленно.

C++
1
2
3
4
5
6
7
8
9
10
11
>TestBigInt.exe -miller_rabin M23
 
Number M23:
 big integer :  2 ... 696392191
 number of decimal digits = 3376
 number of segments       = 376
 
Miller-Rabin primality test.
Test passed. Maybe it's prime.
 
time : 1025.19 sec.
C++
1
2
3
4
5
6
7
8
>TestBigInt.exe -generate "2^57885167-1"
 
Generating number 2^57885167-1
 big integer :  37 ... 354300927
 number of decimal digits = 17425172
 number of segments       = 1936131
 
time : 694.602 sec.
Ну что это такое.
Вложения
Тип файла: rar TestBigInt.rar (56.9 Кб, 2 просмотров)
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 14:28  [ТС]
C++
1
2
3
4
5
6
7
8
>TestBigInt.exe -factorial 1000000
-- factorial test --
Calculating 1000000!
 big integer :  8 ... 0
 number of decimal digits = 5565709
 number of segments       = 618413
 
time : 47.42 sec.
Ищу какие-нибудь оптимизушки.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
06.09.2015, 14:42
Цитата Сообщение от SerVal Посмотреть сообщение
Ищу какие-нибудь оптимизушки.
Без исходников трудно что-либо посоветовать...
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 16:06  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
Без исходников трудно что-либо посоветовать...
Ну, исходники-то не секретные.
Правда, удобнее добавить весь проект для Visual Studio 2013.
*экзешник TestBigInt.exe в директории TestBigInt\x64\Release

Всё какбэ компилится и работает. Если у кого есть идеи как всё это ускорить/оптимизировать - напишите.
Вложения
Тип файла: rar TestBigInt_vc2013_project.rar (3.03 Мб, 8 просмотров)
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
06.09.2015, 16:19
SerVal, а чего не 10 мегабайт? Закинул бы заодно в архив пару мультиков...
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 16:30  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
SerVal, а чего не 10 мегабайт? Закинул бы заодно в архив пару мультиков...
Зато надо только разархивировать, тыкнуть в TestBigInt.sln и всё видно и компилится.
А ежели упаковать только несколько файлов, то надо объяснять какой куда пихать.
И вообще, мне нравится, когда всё как для полных придурков... типа в стиле Микрософт.
0
06.09.2015, 16:48

Не по теме:

Цитата Сообщение от SerVal Посмотреть сообщение
А ежели упаковать только несколько файлов, то надо объяснять какой куда пихать.
Или просто удалить из проекта TestBigInt.sdf

0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 16:52  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Или просто удалить из проекта TestBigInt.sdf
А я не знаю, зачем он нужен.. не сам же я его создавал.
Вдруг без него не будет компилиться?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
06.09.2015, 17:02
Цитата Сообщение от SerVal Посмотреть сообщение
Если у кого есть идеи как всё это ускорить/оптимизировать - напишите.
У тебя самые дорогие операции - это сложение, умножение в столбик, а также операции над векторами.
Короче, нужно оптимизировать операции сложения и умножения: переписать на ассемблере, либо воспользоваться интринсиками, а также нужно переделать карацубу - слишком много операций выделения памяти.
Да и базу BASE можно увеличить до 9223372036854775808 вместо твоего жалкого миллиарда.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 17:17  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Да и базу BASE можно увеличить до 9223372036854775808 вместо твоего жалкого миллиарда.
Как говорится, я "двумя руками ЗА". А как её увеличить? *переполнение ж будет.
*ассемблер не нужен - он не переносится на другое платформы и процессоры.

Цитата Сообщение от nonedark2008 Посмотреть сообщение
либо воспользоваться интринсиками
Что такое интринсики - я не знаю.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
06.09.2015, 17:37
Цитата Сообщение от SerVal Посмотреть сообщение
переполнение ж будет.
У тебя используется для хранения unsigned long long, а это 64 бита.
Оставляем последний бит для переноса - итого у нас 63 бита.
Значит базу можно взять равной 2^63.
Цитата Сообщение от SerVal Посмотреть сообщение
ассемблер не нужен - он не переносится на другое платформы и процессоры
Никто не заставляет использовать современные команды, которые есть только в последних поколениях процессоров.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
06.09.2015, 18:00  [ТС]
У тебя используется для хранения unsigned long long, а это 64 бита.
Оставляем последний бит для переноса - итого у нас 63 бита.
Значит базу можно взять равной 2^63.
Помилуй Бог. Где Вы такое увидели???

Файл BigInt.h
C++
1
2
3
4
5
6
7
8
9
10
static const long long BASE = 1000000000;
static const int BASE_DIGITS = 9;
#define BASE_MINUS_1 (long long)999999999
 
struct BigInt {
public:
    std::vector<int> a;
    int sign;
...
}
Мало того, unsigned вообще нельзя использовать для хранения(ни в каком виде) - алгоритмы не будут работать.
И при умножении: (BASE-1) * (BASE-1) должно помещаться в long long.

Может быть я что-то не понял, в Вашем предложении?
Вообще-то, компилится всё это 3 секунды.
Не могли бы Вы скомпилить с базой 9223372036854775808 и проверить результат, скажем, на факториале?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
07.09.2015, 00:04
Цитата Сообщение от SerVal Посмотреть сообщение
unsigned вообще нельзя использовать для хранения(ни в каком виде)
Можно.
Цитата Сообщение от SerVal Посмотреть сообщение
алгоритмы не будут работать
Значит нужно найти алгоритмы получше.
Не очень хорошо, когда половина блока практически всегда простаивает впустую.
Цитата Сообщение от SerVal Посмотреть сообщение
И при умножении: (BASE-1) * (BASE-1) должно помещаться в long long.
Есть замечательная инструкция mulx, которая позволяет умножить два слова по 64 бита и получить 128 битный результат.
Если не хочется возиться с SIMD, то всегда можно оптимизировать что-то другое. Но в твоей программе самой дорогой операцией является именно умножение, так что стоит начинать именно с него.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
07.09.2015, 00:55  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Есть замечательная инструкция mulx, которая позволяет умножить два слова по 64 бита и получить 128 битный результат.
Ну дорогой, nonedark2008, я стараюсь применить Ваши советы, но чего-то никак.

В какой библиотеке инструкция mulx?
Вот я натяпал:
C++
1
2
3
4
5
    long long a = 2;
    long long b = 3;
    long long result;
    result = mulx(a,b);
    std::cout << "result = " << result << endl;
Не компилится. Может я какую-нибудь includ-у не прописал?

Инструкцию lldiv я нашёл:
C++
1
2
3
        lldiv_t div_rem = std::lldiv(cur, x);
        a[i] = div_rem.quot;   // quotent
        rem =  div_rem.rem;  // reminder
А mulx - нетути.

Добавлено через 18 минут
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Но в твоей программе самой дорогой операцией является именно умножение, так что стоит начинать именно с него.
Да где оно самое дорогое?
Умножение "столбиком" только если длинное умножать на короткое(на int, long или long long).
Но и тут столбика нетути. Каждый элемент длинного умножается на короткое с учётом переносов и всё.
А длинное на длинное умножается Карацубой - и тут "столбика" нетути.

Вот умножение длинного на короткое:
C++
1
2
3
4
5
6
7
8
9
10
11
void BigInt::operator *= (const unsigned long long v) {
 
    for (unsigned long long i = 0, carry = 0; i < a.size() || carry; ++i) {
        if (i == a.size())
            a.push_back(0);
        unsigned long long cur = a[i] * v + carry;
        carry = (cur / BASE);
        a[i] = cur % BASE;
    }
    trim(); // remove trailing zeros
}
Что тут можно оптимизировать? Не понимаю
Не могли бы Вы показать несколько строчек кода?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
07.09.2015, 01:06
Цитата Сообщение от SerVal Посмотреть сообщение
В какой библиотеке инструкция mulx?
В ассемблере так и остается mulx.
Также есть интринсик _mulx_u64 и объявлен он в волшебном файле immintrin.h.
Но возможно данная инструкция твоим процессором не поддерживается.

Не по теме:

Бла-бла-бла, совместимость, бла-бла, производительность.


Всегда есть что-нибудь попроще, есть инструкции для переемножения двух 32 битных переменных с помещением результата в 64 битную переменную. Можно умножать сразу несколько пар чисел одновременно с использованием SIMD. Возможностей по оптимизации со стороны процессора множество, главное их найти и с умом применить.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
07.09.2015, 01:14
Цитата Сообщение от SerVal Посмотреть сообщение
Да где оно самое дорогое?
Во вложении вырезка из анализа производительности для -factorial 1000000.
Миниатюры
Потестируйте скорость работы класса больших чисел  
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
07.09.2015, 01:28
Цитата Сообщение от SerVal Посмотреть сообщение
Что тут можно оптимизировать? Не понимаю
Ну, деление и взятие остатка - дорогие операции.
Если взять базу в виде степени двойки,
то вместо деления и взятия остатка можно обойтись простыми битовыми сдвигами.
От строчек 4-5 наверняка можно избавиться,
все нелинейные блоки внутри циклов могут существенно замедлить их работу.
Цитата Сообщение от SerVal Посмотреть сообщение
Не могли бы Вы показать несколько строчек кода?
Оптимизация кода - это долгое и неблагодарное занятие,
в качестве развлечения меня не тянет этим заниматься, да и не дока я в этом.
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
14.09.2015, 23:35  [ТС]
Тэээкс.. Скоро сказка сказывается, да не скоро дело делается.
Но прогресс есть. Вместо умножения методом Карацубы подставил умножение FFT.
Там где много умножений, всё маленько ускорилось. Например, генерация большого числа.

Было:
C++
1
2
>TestBigInt.exe -generate "2^77071069-1"
time : 8672.88 sec.
Стало:
C++
1
2
3
4
5
6
7
8
>TestBigInt.exe -generate "2^77071069-1"
 
Generating number 2^77071069-1
 big integer :  368882791 ... 195571711
 number of decimal digits = 23200704
 number of segments       = 2577856
 
time : 89.052 sec.
Умножение преобразованием Фурье проверил на всех простых числах Мерсена, вплоть до Mp48.
Ну, и непонятно, насколько всё это быстро. На чём бы ещё проверить?
Програмки, которая генерит большие числа и показывает часть десятичных цифр нигде нетути.

*остальные тесты не ускорились, потому что там есть "деление" и "остатки от деления", которые надо как-то оптимизировать.
Всем привет и хорошего настроения.
Вложения
Тип файла: rar TestBigInt.rar (52.4 Кб, 5 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.09.2015, 23:35

Создание класса для работы с массивами чисел
Сделать класс для работы с массивами чисел. У класса должно быть 5 метода. 1. Получение первого элемента массива. 2....

Создать класс для работы с одномерным массивом целых чисел. Разработать следующие элементы класса:
Создать класс для работы с одномерным массивом целых чисел. Разработать следующие элементы класса: Свойства: • возвращающее размерность...

Разработать класс "Массив больших чисел", который состоит из объектов класса "Большие целые числа". Найти сумму элементов массива.
Разработать класс &quot;Массив больших чисел&quot;, который состоит из объектов класса &quot;Большие целые числа&quot;. Найти сумму элементов...

ArrayList, скорость копирования больших структур, копирование по ссылке
Добрый день, Возникла следующая ситуация, в программе есть ArrauList на базе сложной и громосткой структуры данных. И есть ф-и, которые...

Реализация класса "Вектор" для работы с массивом чисел
Помогите решить задачу пожалуйста) Объявите класс &quot;Вектор&quot;, полем которого является массив чисел, а методами: очистка вектора; добавление...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru