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

Деление больших чисел (нужно ускорить)

24.07.2016, 10:29. Показов 4022. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ребятки, помогите ускорить. Уж очень медленно.

Класс совсем простой(вектор со знаком):
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
static const unsigned long long BASE = 1000000000;
static const unsigned int BASE_DIGITS = 9;
#define BASE_MINUS_1 (unsigned long long)999999999
 
struct BigInt {
 
public:
    std::vector<int> a;
    int sign;
}


Деление A /B. Результат в res.
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
void divide(const BigInt &A, const BigInt &B, BigInt &res){
 
    long long norm = BASE / (B.a.back() + 1);
 
    BigInt a = A;   a.sign = positive; a *= norm;
    BigInt b = B;   b.sign = positive; b *= norm;
 
    BigInt r;
    res.a.resize(a.a.size());
 
    for (long long i = a.a.size() - 1; i >= 0; i--) {
        r *= BASE;
        r += a.a[i];
        unsigned long long s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
        unsigned long long s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
        unsigned long long d = (BASE * s1 + s2) / b.a.back();
        r -= b * d;
        while (r < 0)
            r += b, --d;
        res.a[i] = d;
    }
 
    // удалить нули впереди числа
    while (!res.a.empty() && !res.a.back())
        res.a.pop_back();
}
Как это деление называется - не знаю. Но работает.
На маленьких числах ещё терпимо. На числах чуть побольше отак:
C++
1
2
3
4
5
6
7
8
9
10
11
12
D:\>TestBigInt.exe -div Mp36
 Проверка умножения и деления.
 Generating Mersenn number A = Mp36:
 
 big integer :  623340076 ... 729201151
 number of decimal digits = 895932
 number of segments       = 99548
 
 time : 2.486 sec.
 
 Умножение. B = A*A time : 1.183 sec.
 Деление.   C = B/A time : 527.645 sec.


Вторую неделю пытаюсь что-нибудь найти.
* уже нагуглился, теории начитался.. Нет ли чего-нибудь, что можно подсунуть компилятору?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.07.2016, 10:29
Ответы с готовыми решениями:

Ускорить деление больших чисел
Всё бы ничего, да уж очень медленно. :( По форуму смотрел, в Инете искал. Ничего аппетитного нетути. Деление длинного на длинное. ...

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

Деление больших чисел
Здравствуйте, уважаемые форумчане. Необходимо разделить большое чило на большое число. Эти числа хранятся в массиве ( каждый элемент -...

13
 Аватар для shilko2013
257 / 234 / 185
Регистрация: 02.04.2016
Сообщений: 898
24.07.2016, 10:56
Накопал код Mr.X
Мб вам поможет)
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//////////////////////////////////////////////////////////////////////////////////////
//Необходимо разделить большое чило на большое число.
//Эти числа хранятся в массиве (каждый элемент - одна цифра числа).
//////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
//////////////////////////////////////////////////////////////////////////////////////
typedef std::string  T_num_s;
//////////////////////////////////////////////////////////////////////////////////////
void  del_leading_zero(T_num_s&  a)
{
    while(a.size() > 1
          && a[0] == '0')
    {
        a.erase(0, 1);
    }
}
//////////////////////////////////////////////////////////////////////////////////////
bool less_for_big_int(T_num_s  a, T_num_s  b)
{
    del_leading_zero(a);
    del_leading_zero(b);
 
    return  a.size() == b.size() ? a < b : a.size() < b.size();
}
//////////////////////////////////////////////////////////////////////////////////////
void  reduce_big_int(T_num_s&  minuend, const T_num_s&  subtrahend)
{    
    for(T_num_s::size_type  cur_pos = 0; cur_pos < subtrahend.size(); ++cur_pos)
    {
        T_num_s::size_type  minuend_cur_pos     = minuend.size()     - 1 - cur_pos;
        T_num_s::size_type  subtrahend_cur_pos  = subtrahend.size()  - 1 - cur_pos;
 
        char&        cur_minuend_dig_ref     = minuend     [minuend_cur_pos];
        const char&  cur_subtrahend_dig_ref  = subtrahend  [subtrahend_cur_pos];
 
        if(cur_minuend_dig_ref >= cur_subtrahend_dig_ref)
        {
            cur_minuend_dig_ref -= cur_subtrahend_dig_ref - '0';
        }
        else
        {
            (cur_minuend_dig_ref -= cur_subtrahend_dig_ref - '0') += 10;
            for(int i = 1; ; ++i)
            {
                if(minuend[minuend_cur_pos - i] == '0')
                {
                    minuend[minuend_cur_pos - i] = '9';
                }
                else
                {
                    --minuend[minuend_cur_pos - i];
                    break;
                }
            }
        }
        del_leading_zero(minuend);
    }
    del_leading_zero(minuend);
}
//////////////////////////////////////////////////////////////////////////////////////
void  inc_big_int(T_num_s&  a)
{    
    for(T_num_s::size_type  cur_pos = a.size() - 1;; --cur_pos)
    {
        if(a[cur_pos] < '9')
        {
            ++a[cur_pos];
            return;
        }
        else
        {
            a[cur_pos] = '0';
            if(cur_pos == 0)
            {              
                a.insert(0, "1");
                return;
            }
        }    
    }
}
//////////////////////////////////////////////////////////////////////////////////////
T_num_s  div_big_int(const T_num_s&  a, const T_num_s&  b)
{
    if(b == "0")
    {
        return  "division into zero";
    }    
 
    T_num_s  res = "0";
    T_num_s  minuend     = a;
    T_num_s  subtrahend  = b;
    
    while(subtrahend.size() < minuend.size())
    {
        subtrahend += '0';    
    }
 
    for(;;)
    {
        while(!less_for_big_int(minuend, subtrahend))
        {
            reduce_big_int(minuend, subtrahend);
            inc_big_int(res);
        }
        if(subtrahend.size() <= b.size())
        {
            break;
        }
        
        subtrahend.erase(subtrahend.size() - 1);   
        res += '0';              
        del_leading_zero(res);
    }          
    
    return  res;
}
//////////////////////////////////////////////////////////////////////////////////////
int main()
{
    for(;;)
    {
        std::cout << "a = ";
        T_num_s  a;
        std::cin >> a;
        del_leading_zero(a);
 
        std::cout << "b = ";
        T_num_s  b;
        std::cin >> b;
        del_leading_zero(b);
 
        std::cout << "a / b = "
                  << div_big_int(a, b)
                  << std::endl
                  << std::endl
                  << std::endl;    
    }
}
1
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
24.07.2016, 12:15  [ТС]
shilko2013, спасибо. Попробовал.

main()
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main(int argc, char *argv[])
{
    setlocale(LC_CTYPE, "russian");
    std::cout << "*** Деление a / b ***" << endl;
 
    BigInt A = BigInt::generate_number("Mp32");
    BigInt B = A;
    A *= A;
 
    std::cout << " Делимое:" << endl;  
    A.printInfo();  std::cout << endl;
 
    double total_time = (double)clock() / CLOCKS_PER_SEC;
    BigInt C = A / B;
    std::cout << " BigInt time  : " << (double)clock() / CLOCKS_PER_SEC - total_time << " sec." << std::endl;
 
    T_num_s  a = A.toString();
    T_num_s  b = B.toString();
 
    total_time = (double)clock() / CLOCKS_PER_SEC;
    T_num_s c = div_big_int(a, b);
    std::cout << " T_num_s time : " << (double)clock() / CLOCKS_PER_SEC - total_time << " sec." << std::endl << std::endl;

Результат:
C++
1
2
3
4
5
6
7
8
9
D:\>TestBigInt.exe
*** Деление a / b ***
 Делимое:
 big integer :  26290 ... 819038721
 number of decimal digits = 79502
 number of segments       = 8834
 
 BigInt time  : 0.865 sec.
 T_num_s time : 87.115 sec.
Мда... встроенное деление еле чухает. А T_num_s ещё в 100 раз медленнее.
0
Заблокирован
24.07.2016, 12:24
SerVal, чем плохо делить в плавающей точке и быстро и сердито и для больших чисел погрешность будет минимальной. Смысл городить длинную арифметику, она же по факту кроме теории нигде не применима?
1
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
24.07.2016, 12:45  [ТС]
Цитата Сообщение от Unknownx Посмотреть сообщение
Смысл городить длинную арифметику, она же по факту кроме теории нигде не применима?
С этим согласен. За исключением RSA, но там давно всё написано.
Но я любитель больших целых чисел. Типа чисел Мерсена, Шрота, Серпинского.юю и всяких простых чисел.

Вот один дядя намедни нашёл почти самое большое простое число: 453·2^3387048+1

Кликните здесь для просмотра всего текста

On 14 July 2016, 18:48:35 UTC, PrimeGrid's PPS Mega Prime Search project found the mega prime: 453·2^3387048+1

The prime is 1,019,606 digits long and enters Chris Caldwell's The Largest Known Primes Database ranked 165th overall.

The discovery was made by Andreas Mueller (Andreas) of Germany using an Intel(R) Xeon(R) CPU E5620 @ 2.40GHz with 16GB RAM, running Linux. This computer took about 3 hours 40 minutes to complete the primality test using LLR.

А другой дядя 3 часа 40 минут его проверял. Я тоже хочу.. ну, если не найти, то хотя бы проверить.
А тому кто найдёт самое большое - дадут большую денежку ~ 100 тыс. уё. Это я тоже хочу.
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
24.07.2016, 13:09
Самое большое число никогда не найдут, просто потому что числовой ряд бесконечен
0
Заблокирован
24.07.2016, 13:13
Цитата Сообщение от SerVal Посмотреть сообщение
Но я любитель больших целых чисел. Типа чисел Мерсена, Шрота, Серпинского.юю и всяких простых чисел.
ну я так думаю что любовь вызвана не простой склонностью к числам, а конкретной задачей, м.б могу узнать что за таск стоит?В любом случае конечно же сделать супер быстрый класс для больших чисел, знать бы конкретную задачу под что его точим.
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
24.07.2016, 13:18
Расчет факториала от потенциально бесконечного числа С++
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
24.07.2016, 13:20
Цитата Сообщение от SerVal Посмотреть сообщение
Я тоже хочу.. ну, если не найти, то хотя бы проверить.
Так во многих же языках есть встроенная длинная арифметика.
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
24.07.2016, 13:20
ну а если есть склонность, то очень интересно почитать вот это:
http://bajandin.narod.ru/1Prime.pdf
1
 Аватар для shilko2013
257 / 234 / 185
Регистрация: 02.04.2016
Сообщений: 898
24.07.2016, 13:54
В PascalABC.NET есть бесконечные числа, можно оттуда алгоритм стырить)
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
24.07.2016, 14:59  [ТС]
Цитата Сообщение от Serg_o_Grey Посмотреть сообщение
в трех файлах выложил
Это какой-то ужос. Разобраться что там происходит - невозможно.
В первую очередь потому, что вычисления и пользовательский интерфейс - единое целое.
Выцапать функцию деления - никак невозможно. Может она и замечательная.. гдето внутри.. но увы...

Цитата Сообщение от Mr.X Посмотреть сообщение
Так во многих же языках есть встроенная длинная арифметика.
Ну.. предполагается, что результат нужен "при этой жизни". Не так ли?
Медленно можно на php или на Хаскеле сделать.
Ну, а если в другиз язаках всё замечетельно - не подскажет ли кто: "453·2^3387048+1 это простое число или нет?
Что по этому поводу говорит тест Миллера-Рабина или Люка-Лемера в наскеле?
******
Попробовал ещё большие числа в C#.
Теоретически они там есть, а практически... "декларация о намерениях"..... не дождёшься.
******

Добавлено через 1 минуту
Цитата Сообщение от shilko2013 Посмотреть сообщение
В PascalABC.NET есть бесконечные числа, можно оттуда алгоритм стырить)
Там тоже пойло, что и в C#.
0
116 / 106 / 51
Регистрация: 29.03.2016
Сообщений: 480
24.07.2016, 15:13
Цитата Сообщение от SerVal Посмотреть сообщение
Это какой-то ужос. Разобраться что там происходит - невозможно.
вы сильно неправы. для деления достаточно указать в функции main:
box *X1;
X1 = new box;
InputOfNumber(X1); // функция запрашивает ввода числа с клавиатуры (ничего не мешает скопировать и вставить)
box *X2;
X2 = new box;
InputOfNumber(X2);
box *X;
X = new box; // сюда записывается результат
print_X(X); // печать результата

chastnoe(X1, X2, X); // вычисление
0
 Аватар для SerVal
37 / 36 / 9
Регистрация: 16.04.2015
Сообщений: 283
24.07.2016, 15:34  [ТС]
Цитата Сообщение от Serg_o_Grey Посмотреть сообщение
ну а если есть склонность, то очень интересно почитать вот это:
http://bajandin.narod.ru/1Prime.pdf
Как ускорим деление, можно будет попробовать искать простые при помощи матрицы.
А сейчас, на pdf-ки мой компилятор почему-то ругается.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.07.2016, 15:34
Помогаю со студенческими работами здесь

Класс больших чисел. Деление по Кнуту.
Кнут т2 стр. 300 алгоритм D. Кто реализовал для b=2^32 или 2^16 - поделитесь, плз, если не жалко ! (А то у меня много неясных моментов....

Деление больших чисел методом Ньютона-Рафсона
Добрый день, ребятки. Давно уже хочу заменить деление с бинарным поиском на Ньютона-Рафсона. Бинарный поиск - уж очень медленно. И ищу...

Деление больших чисел
Здравствуйте форумчане возникла надобность поделить очень большое число 100 знаков программа отказывается это делать выдавая ошибку в...

Деление больших чисел
Есть 2 массива, в котором хранятся 50-значные числа. Необходимо найти частное и вывести его. Заготовочка есть небольшая, только здесь...

Деление больших чисел
Произвести деление двоичных беззнаковых чисел большой размерности. Нужно ввод чисел сделать на С++, там же вызывать функции. Подскажите,...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru