|
|
|
Длинная арифметика на Си12.07.2010, 19:01. Показов 99120. Ответов 44
Здравствуйте, форумчане!
Хотелось бы мне начать топик, сообщения в котором я планирую пополнять постоянно (по возможности и уровню занятости, разумеется). Тема топика, как видно из заголовка, длинная арифметика. Я не хочу подробно описывать, что такое длинная арифметика и зачем она нужна. Об этом любой может прочитать на той же википедии. Но небольшое вступление сделать все таки надо. В длинной арифметике вычисления производятся над очень большими числами. С точки зрения программирования на языке Си такими числами можно считать любые, которые "не помещаются" в стандартные типы данных, то есть те, которые больше 32-х (64-х) бит. Наиболее популярно применение длинной арифметики, пожалуй, в криптографии. Я знаю, что очень многим студентам в университетах дают задания на длинную арифметику и надеюсь, что кто-то наткнется на эти сообщения и они ему помогут (сам в свое время мучился). Под конечной целью буду предполагать создание библиотеки или пакета (набора функций) для работы с длинными числами, возможно реализация каких-либо криптографических алгоритмов для примера. Начальный план действий будет таков:
PS. Я нисколько не претендую на специалиста в данной области. В первую очередь создаю топик для самого себя, чтобы изучить данную тему и как следует в ней разобраться. Но я надеюсь, что это заитересует многих. Я знаю, что только начинаю осваивать языки программирования, поэтому очень надеюсь на поддержку наших гуру во всех аспектах задачи. PPS. За "Библию" в этой теме беру второй том из серии "Искусство программирования" Д. Кнута.
16
|
|
| 12.07.2010, 19:01 | |
|
Ответы с готовыми решениями:
44
Длинная арифметика Умножение (длинная арифметика) |
|
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
|
|
| 12.07.2010, 20:01 | |
Сообщение было отмечено как решение
Решение
The GNU Multiple Precision Arithmetic Library http://gmplib.org/
5
|
|
|
|
||
| 12.07.2010, 20:07 [ТС] | ||
|
0
|
||
|
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
|
|
| 12.07.2010, 20:20 | |
|
А "тупое" использование твоей библиотеки покажет основные принципы ?
Все кому лень разбираться будут просто копировать ТВОЙ код и использовать.
0
|
|
|
476 / 444 / 34
Регистрация: 20.11.2009
Сообщений: 1,293
|
|
| 12.07.2010, 20:20 | |
|
fasked, а может лучше на цпп? С объектами? Думаю, для тебя же самого это будет куда полезнее.
0
|
|
|
|
|||
| 12.07.2010, 20:23 [ТС] | |||
|
2
|
|||
|
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
|
|
| 12.07.2010, 20:32 | |
|
Ну а какой план ?
Нужно: сложение, вычитание, умножение на обычное число, деление на обычное число, умножение двух длинных чисел, деление двух длинных чисел Вывод длинного в строку, чтение длинного из строки Да - еще преобразование обычного числа в длинное
0
|
|
|
|
|||||||||||||||||
| 12.07.2010, 21:00 [ТС] | |||||||||||||||||
Сообщение было отмечено как решение
РешениеДобавлено через 21 минуту Перед тем, как приступить конкретно к реализации, хотелось (или необходимо) бы немного теории. Первое, что необходимо сделать при проектирования нашего пакета - это выбор представления данных для хранения и обработки больших чисел. Идеальным средством, предоставляемым базовыми возможностями языка, являются массивы. Данные в массивах хранятся последовательно, поэтому с адресацией никаких проблем не возникнет. Теперь надо определить массивами какого типа будут большие числа. От этого зависит какой тип будет иметь один разряд большого числа. Наиболее эффективным выбором будет выбор такого типа, вычисления над которыми процессор мог бы производить без дополнительных затрат (вычисления, связанные с большими числами, процесс довольно ресурсоемкий). Поэтому подходящим выбором будут 16-битовые числа. Сейчас я попытаюсь объяснить почему. Максимальное значение, которое умещается в 16-битовом числе равно 0xFFFF. Соответственно максимально возможный результат математической операции над 16-битовыми числами равен 0xFFFE0001. (0xFFFF * 0xFFFF = 0xFFFE0001). Такое число аккурат помещается в 32 бита регистра процессора. Процессору не понадобятся дополнительные операции по перемещению битов в регистрах, что даст ощутимый результат в скорости. 16-битовые числа в языке Си представлены типом unsigned short, 32-х битовые типом unsigned long. Таким образом за основной тезис можно взять выражение f(USHORT, USHORT) < ULONG, где f() - любая арифметическая операция. Думаю, это очень удобно. Проверить данное отношение для конкретного компилятора можно открыв заголовочный файл limits.h. Там найти значения, подобные этим:
Следует отметить, что в 64-разрядных системах, можно ускорить время выполнения, аналогично используя базовые типы длиной 32 и 64 бита соответственно. Следующий вопрос - это упорядочение разрядов в массиве. Существует два варианта: - порядок от старшего к младшему - порядок от младшего к старшему Рассмотрим эти варианты. Возьмем для примера число 0xFFFFFFFF При порядке от старшего к младшему число в ячейках памяти будет выглядеть следующим образом
Другой порядок избавляет нас от такой проблемы.
Далее займемся непосредственно программированием.
9
|
|||||||||||||||||
|
26 / 26 / 5
Регистрация: 28.12.2009
Сообщений: 85
|
|
| 12.07.2010, 21:13 | |
|
Ооо..... а я когда то пытался сделать такое. Была задача, написать класс для хранения очень больших чисел ( целых ). Ии... перегрузка основных операций ( + - / * ). Сделал.. но, не полностью, реализовал только + и -. Дальше шло деление но, на нем я остановился ибо деление давало дробный результат а цисла то у меня целые... поразмыслив над этой проблемой несколько часов и найдя "кривое" решения я подумал что цель не стоит затраченого на нее времени. Умножение "крутилось" в голове но, так как НОРМАЛЬНО сделать деление не получилось, я решил забить и на умножение. Ведь.... зачем делать недоделаную программу ?
Таким образом, будет очень интересно посмотреть на ваш пакет. Ну, конечно же в исходных кодах
0
|
|
|
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
|
||||||
| 13.07.2010, 03:23 | ||||||
Сообщение было отмечено как решение
Решениеотсюда, откомментированный, 3 ^ 100
21
|
||||||
|
|
|||||||||||||||||||||||||||||||
| 13.07.2010, 14:31 [ТС] | |||||||||||||||||||||||||||||||
|
Итак, простейшее представление длинного числа в языке Си будет выглядеть следующим образом.
Для начала нам хватит следующих определений.
REAL_MAX_ORDER - количество разрядов в одном длинном числе. Число может быть произвольным, но для начала можно взять значение поменьше (в демонстративных целях). Далее определены синонимы базовым типам, для более удобного написания.
Теперь простейшее представление длинного числа выглядит следующим образом
Все определения вынесены в отдельный заголовочный файл по имени real.h Содержимое файла real.h
1
|
|||||||||||||||||||||||||||||||
|
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
|
|
| 13.07.2010, 15:06 | |
|
odip, предлагаю засунуть это тему в раздел "Большая коллекция решенных задач".
Топик очень познавательныйй вышел...
0
|
|
|
|
|||||||||||||||||||||||||||||||||||||
| 13.07.2010, 16:37 [ТС] | |||||||||||||||||||||||||||||||||||||
|
Добавлено через 1 час 30 минут Сложение двух длинных неотрицательных чисел Сложение двух чисел производится по классическому "школьному" алгоритму. Сначала разберем простейшую реализацию такого алгоритма. Допустим есть два числа: число U и число V. Над ними необходимо произвести заданную арифметическую операцию. Число W будет содержать результат операции. В соответствии с исходными данными прототип функции сложения выглядит следующим образом:
Переменная k - знак переноса. По свойству операции сложения переменная k может содержать только два значения, либо 0, либо 1. Попробуем протестировать получившуюся функцию.
Однако же эта функция нуждается в определенных улучшениях. Все ее недостатки связаны с длинами чисел. В таком виде функция проходится по максимально возможному количеству разрядов числа. То есть по старшим нулям, фактически работает вхолостую. Значит следует учесть длину чисел. Прототип принимает следующий вид:
2. Проверка длины результирующего числа. Если есть возможность того, что результат не поместиться в число W, то вылетает исключение. 3. Первый цикл работает пока существует более короткое число. 4. Второй цикл уже не учитывает короткое число, а только разряды более длинного + знак переноса. 5. Учет знака переноса для формирования окончательного результата. Осталось протестировать, вызываем функцию со следующими аргументами:
Функция сложения двух длинных чисел готова, чуть позже я приведу более "модную" реализацию. Жду ваших комментариев и критики.
1
|
|||||||||||||||||||||||||||||||||||||
|
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
|
||||||
| 13.07.2010, 21:57 | ||||||
|
Мне кажется стоит сделать структуру куда положить массив и длину
Тогда операции будут выглядешь намного проще - почти как целые числа
И название realint странное Это вещественное ( real ) или целое ( int ) ?
0
|
||||||
|
|
|||||||||||||||||||||||||||
| 14.07.2010, 14:56 [ТС] | |||||||||||||||||||||||||||
|
Посетила меня мысль положить в первый регистр числа длину. То есть первую ячейку массива, максимальная длина числа тогда ограничиться 16-ой степенью двойки разрядов ![]()
Да. И с названием я что-то явно накосячил, надо его как-то иначе обозвать. У кого какие предложения? ![]() Добавлено через 14 часов 13 минут Обновился ![]()
В связи с переименованием большинство typedef и define тоже переписаны, но смысл у них остается тот же. Константы:
Типы данных:
Макросы:
BIGINT_MSDPTR - определение указателя на страший значащий разряд. BIGINT_LSDPTR - соответственно указатель на младший значащий разряд. Следовательно прямая запись и вывод числа выглядят теперь вот так:
0
|
|||||||||||||||||||||||||||
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
|
|
| 14.07.2010, 15:20 | |
|
Тему не читал, как-то накропал проектик, может пригодится кому, там исходники есть
2
|
|
| 14.07.2010, 15:22 | ||
|
Не по теме:
0
|
||
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
|
|
| 14.07.2010, 15:25 | |
|
Число представлено в виде строки. А значит, его длина сколь угодно большая. Хоть 30 знаков хоть 200. Результат тоже соответственно в виде строки цифр.
А вот на делитель наложены ограничения по размеру. ...Да, и остаток тоже вычисляется.
0
|
|
|
113 / 113 / 28
Регистрация: 05.07.2009
Сообщений: 225
|
||||||
| 14.07.2010, 19:15 | ||||||
|
Не по теме: kravam, код не смотрел, но при вводе очень большого числа (знаков 700) прога выкинула. Так что ограничения всё-таки есть. Добавлено через 2 минуты Не по теме:
0
|
||||||
| 14.07.2010, 19:15 | |
|
Помогаю со студенческими работами здесь
20
Простая Длинная арифметика
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/
O1rJuneU_ls
https:/ / vkvideo. ru/ video-115721503_456239114
|
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ВВЕДЕНИЕ
Введу сокращения:
аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
|
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi
ветка по-частям.
коммит Create переделка под биомассу. txt
вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
|
|
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ *
Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях.
Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её.
Последовательность действий:. . .
|
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
|
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение.
И на уровне агентов добавится между грибами или бактериями взаимодействий.
До того я пробовал подход через многомерные массивы,. . .
|
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Налог на собак: https:/ / **********/ gallery/ V06K53e
Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf
Пост отсюда. . .
|