Сравнение версий

Ключ

  • Эта строка добавлена.
  • Эта строка удалена.
  • Изменено форматирование.

Срок выполнения: 13–20 14–23 ноября

Задание
  1. Составьте эффективный алгоритм вычисления формулы Тейлора для своего варианта. Слагаемые ряда вычисляйте до тех пор, пока они больше или равны машинному эпсилон (предвычисленному для 1).
  2. Напишите функцию вычисления "машинного эпсилон".
  3. Напишите функцию, которая эффективно вычисляет ряд, заданный вариантом, с точностью машинного эпсилон (оно должно вычисляться вычисляет значение по алгоритму из п. 1 (эпсилон вычисляйте с помощью функции из пункта п. 2).
  4. Напишите программу, которая вычисляет заданную функцию дважды: напрямую по формуле из варианта и с помощью вашей подпрограммы из пункта п. 3. Выведите полученные значения и разность между ними.

Примечание: тип вещественных чисел нужно задавать в программе с помощью typedef, программа Программа должна работать верно с любым вещественным типом.

Математические функции (<cmath>): http://en.cppreference.com/w/cpp/numeric/math
(обращайте внимание на пометки:
since C++11
(или C++14) – средства из нового стандарта, пока присутствуют не во всех реализациях библиотеки;
until C++11 – средства из старого стандарта, которые изменены или заменены в новом)

...

Замечания о точности

"Машинное эпсилон" несёт в себе информацию о точности вычислений в конкретном формате с плавающей запятой. Но его вычисление (как и другие подобные расчёты) зависит от машинного кода, создаваемого компилятором. Так на Intel (и совместимых машинах) регистры арифметического устройства для вещественных чисел хранят по 80 битов (всего), но модуль умеет дополнительно сохранять результат в память в 32- (float) и 64-разрядном (double) форматах (и, конечно, загружать такие числа). Компилятор (пример – 32-битный GCC) может создать код, который будет считать всё на регистрах (включая сравнения). В итоге мы получим "эпсилон" для 80-битового формата. Сохранив его в float или double, мы лишь приведём его к ближайшему представимому в запрошенном формате числу (обрежем значимую часть). Полученное значение будет неверным.

Блок кода
languagecpp
firstline1
titleВычисление эпсилонfirstline1
linenumberstrue
float eps(float startVal) {
    float sv = startVal;
    while (true) {
       float val = sv * 0.5f;
       if (startVal + val == startVal) return sv;
       sv = val;
   }
}

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

Блок кода
languagecpp
firstline1
titleБолее надёжный примерfirstline1
linenumberstrue
float pass(float x) { return x; }
float eps(float startVal) {
    float sv = startVal;
    while (true) {
       float val = sv * 0.5f;
       if (pass(startVal + val) == startVal) return sv;
       sv = val;
   }
}

...

Значение будет дробным. Чтобы гарантированно получить все необходимые знаки, обычно его округляют в большую сторону – ceil(n). При этом нужно помнить, что достоверным является количество знаков, на единицу меньшее – floor(n).

О типах данных

Обычно для более быстрых вычислений выбирают меньший тип (например, float), для более точных – больший (например, double). Обычно можно работать с float, а в критичных местах использовать double для промежуточных данных расчёта.

...

Расширение SSE появилось в процессоре Pentium III, а SSE2 – в Pentium 4.

Примеры

float.cpp

Варианты

Расчёт номера своего варианта см. на странице Успеваемость студентов.

...