|
|
|
Длинная арифметика на Си12.07.2010, 19:01. Показов 98857. Ответов 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,698
|
|
| 14.07.2010, 15:20 | |
|
Тему не читал, как-то накропал проектик, может пригодится кому, там исходники есть
2
|
|
| 14.07.2010, 15:22 | ||
|
Не по теме:
0
|
||
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
|
|
| 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
Простая Длинная арифметика
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|
Фото: Daniel Greenwood
kumehtar 13.11.2025
|