Найти тему

Polynomial_p2.zip

Оглавление

О программировании

Указанный архив можно скачать там.

Начните чтение с History.pdf.

В архиве вы найдете несколько PDF-файлов с текстами и много кода, повторяющегося в значительной мере. Гиперссылки выделены синим цветом.

Архив следует разгрузить в один каталог и читать PDF с помощью Adobe Reader. При использовании других средств просмотра PDF работоспособность гиперссылок не гарантируется.

Что в этом выпуске

Доведен до ума класс Polynomial с коэффициентами double.

Дальше возник вопрос о многочленах с коэффициентами других типов. Если c коэффициентами типа float проблема решается контекстной заменой,
то для целочисленных типов (включая вычеты по модулю) характерны другие алгебраические свойства. Например, для int нет деления, а вместо него деление с остатком. Для вычетов по непростому модулю нет ни того, ни другого. И еще у этих типов нет округления результатов операций, что позволяет ставить и решать вопрос о делимости многочленов, НОД и НОК.

Получается, что хотя структура объекта одинаковая, набор операций и их реализация существенно зависят от свойств типа коэффициентов. Поэтому пришлось строить наследственное дерево классовых шаблонов:

Суффиксы отражают свойства коэффициентов:
R — операции с округлением,
r — операции точные (без округления),
D — есть деление,
d — нет деления (есть деление с округлением).
Суффиксы отражают свойства коэффициентов: R — операции с округлением, r — операции точные (без округления), D — есть деление, d — нет деления (есть деление с округлением).

Общий для всех шаблонов суффикс S означает скалярные типы коэффициентов. Все значения скалярного типа имеют одинаковый размер в оперативной памяти, что позволяет размещать их в памяти в виде сплошного динамического массива и работать с ними через указатели. Такими являются все встроенные числовые типы.

Структура самого объекта (степень и указатель на массив коэффициентов) одинакова для всех шаблонов, но на нижележащих уровнях появляются новые операции над многочленами или другие реализации операций.

В связи с этим появляется много заморочек, борьба с которыми (даже чуть эмоционально) описана в текстах.

Если пользователю нужен только один тип коэффициентов, можно предложить ему — вместо возни с иерархией шаблонов — генератор классов типа Polynomial. Ему следует заполнить небольшую анкету о свойствах типа коэффициентов и получить на выходе .obj-файл с необходимым ему классом многочленов.

Еще одна существенная проблема. Начиная со стандарта C++11, в языке появилась концепция move, иначе называемая семантикой перемещения. Применительно к нашим объектам это означает следующее. Например, в случае операции присваивания коэффициенты исходного многочлена можно не копировать в массив коэффициентов многочлена-копии, а просто передать его во владение копии. При этом надо обеспечить, что исходный многочлен больше не будет использоваться, а его массив коэффициентов не будет удален (динамическая память под ним не будет освобождена). Понятно, что это повышает быстродействие.

Стандартный способ реализации семантики перемещения исполняется продукцией MS. Это очень удобно и дает, я полагаю, хорошие результаты.

Имеющаяся у меня бесплатная система программирования, хоть и датируется 20 годом и все еще в развитии, стандарт C++11 реализует неполностью. В связи с этим было испытано 2 рукодельных способа реализации перемещения — с каждым вариантом проекта. Результаты и обнаруженные проблемы описаны в документах архива.

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