- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
void Axis::set_color(Color c)
{
Shape::set_color(c);
notches.set_color(c);
label.set_color(c);
}
Аналогично, функция Axis::move() перемещает все три части объекта класса Axis одновременно.
void Axis::move(int dx, int dy)
{
Shape::move(dx,dy);
notches.move(dx,dy);
label.move(dx,dy);
}
15.5. Аппроксимация
Рассмотрим еще один небольшой пример построения графика функции: “анимируем” вычисление экспоненты. Наша цель — дать вам почувствовать математические функции, продемонстрировать применение графиков для иллюстрации вычислений, показать фрагменты кода и, в заключение, предупредить о типичных проблемах, связанных с вычислениями.
Один из способов вычисления экспоненты сводится к суммированию степенного ряда.
ex = 1 + x + x2/2! + x3/3! + x4/4! + ...
Чем больше членов ряда мы вычислим, тем точнее будет значение ex; иначе говоря, чем больше членов ряда мы вычисляем, тем больше правильных цифр найдем в результате. В программе мы суммируем ряд и строим график его частичных сумм. В этой формуле знак восклицания, как обычно, обозначает факториал, т.е. мы строим графики функций в следующем порядке:
exp0(x) = 0 // нет членов
exp1(x) = 1 // один член
exp2(x) = 1+x // два члена ; pow(x,1)/fac(1)==x
exp3(x) = 1+x+pow(x,2)/fac(2)
exp4(x) = 1+x+pow(x,2)/fac(2)+pow(x,3)/fac(3)
exp5(x) = 1+x+pow(x,2)/fac(2)+pow(x,3)/fac(3)+pow(x,4)/fac(4)
...
Каждая функция немного точнее приближает ex, чем предыдущая. Здесь pow(x,n) — стандартная библиотечная функция, возвращающая xn. В стандартной библиотеке нет функции, вычисляющей факториал, поэтому мы должны определить ее самостоятельно.
int fac(int n) // factorial(n); n!
{
int r = 1;
while (n>1) {
r*=n;
––n;
}
return r;
}
Альтернативная реализация функции fac() описана в упр. 1. Имея функцию fac(), можем вычислить n-й член ряда.
double term(double x, int n) { return pow(x,n)/fac(n); } // n-й
// член ряда
Имея функцию term(), несложно вычислить экспоненты с точностью до n членов.
double expe(double x, int n) // сумма n членов для x
{
double sum = 0;
for (int i=0; i<n; ++i) sum+=term(x,i);
return sum;
}
Как построить график этой функции? С точки зрения программиста трудность заключается в том, что наш класс Function получает имя функции одного аргумента, а функция expe() имеет два аргумента. В языке С++ нет элегантного решения этой задачи, поэтому пока воспользуемся неэлегантным решением (тем не менее, см. упр. 3). Мы можем удалить точность n из списка аргументов и сделать ее переменной.
int expN_number_of_terms = 10;
double expN(double x)
{
return expe(x,expN_number_of_terms);
}
Теперь функция expN(x) вычисляет экспоненту с точностью, определенной значением переменной expN_number_of_terms. Воспользуемся этим для построения нескольких графиков. Сначала построим оси и нарисуем истинный график экспоненты, используя стандартную библиотечную функцию exp(), чтобы увидеть, насколько хорошо она приближается функцией expN().
Function real_exp(exp,r_min,r_max,orig,200,x_scale,y_scale);
real_exp.set_color(Color::blue);
Затем выполним цикл приближений, увеличивая количество членов ряда n.
for (int n = 0; n<50; ++n) {
ostringstream ss;
ss << " приближение exp; n==" << n ;
win.set_label(ss.str());
expN_number_of_terms = n;
// следующее приближение:
Function e(expN,r_min,r_max,orig,200,x_scale,y_scale);
win.attach(e);
win.wait_for_button();
win.detach(e);
}
Обратите внимание на последний вызов detach(e) в этом цикле. Область видимости объекта e класса Function ограничена телом цикла for. Каждый раз, кода мы входим в этот блок, мы создаем новый объект e класса Function, а каждый раз, когда выходим из блока, объект e уничтожается и затем заменяется новым. Объект класса Window не должен помнить о старом объекте e, потому что он будет уничтожен. Следовательно, вызов detach(e) гарантирует, что объект класса Window не попытается нарисовать разрушенный объект.
На первом этапе мы получаем окно, в котором нарисованы оси и “настоящая” экспонента (синий цвет).
Как видим, значение exp(0) равно 1, поэтому наш синий график “настоящей” экспоненты пересекает ось y в точке (0,1). Если присмотреться повнимательнее, то видно, что на самом деле мы нарисовали первое приближение (exp0(x)==0) черным цветом поверх оси x. Кнопка Next позволяет получить аппроксимацию, содержащую один член степенного ряда. Обратите внимание на то, что мы показываем количество сленгов ряда, использованного для приближения экспоненты, как часть метки окна.
Это функция exp1(x)==1, представляющая собой аппроксимацию экспоненты с помощью только одного члена степенного ряда. Она точно совпадает с экспонентой в точке (0,1), но мы можем построить более точную аппроксимацию.
Используя два члена разложения (1+x), получаем диагональ, пересекающую ось y в точке (0,1). С помощью трех членов разложения (1+x+pow(x,2)/fac(2)) можем обнаружить признаки сходимости.
Десять членов приближения дают очень хорошее приближение, особенно для значений x, превышающих –3.
На первый взгляд, мы могли бы получать все более точные аппроксимации, постоянно увеличивая количество членов степенного ряда. Однако существует предел, и после тринадцати членов происходит нечто странное: аппроксимация ухудшается, а после вычисления восемнадцати членов на рисунке появляются вертикальные линии.
Помните, что арифметика чисел с плавающей точкой — это не чистая математика. Числа с плавающей точкой просто хорошо приближают действительные числа, поскольку для их представления можно использовать лишь ограниченное количество бит. С определенного момента наши вычисления стали порождать числа, которые невозможно точно представить в виде переменных типа double, и наши результаты стали отклоняться от правильного ответа. Более подробная информация на эту тему приведена в главе 24.
Последний рисунок представляет собой хорошую иллюстрацию следующего принципа: если ответ выглядит хорошо, еще не значит, что программа работает правильно. Если программа проработает немного дольше или на несколько других данных, то может возникнуть

