Leonov, Izuchenie construk. 9 вар
.doc
-
1. Постановка задачи
Описать алгоритм в виде блок-схемы и написать программу на языке C#, которая будет реализовать табулирование функции для заданной системы уравнений на числовом промежутке [a; b] с шагом p. Данные должны выводиться в табличной форме, где каждому значению аргумента соответствует подсчитанное значение функции
-
2. Описание алгоритма
На рис. 1 представлена блок-схема алгоритма табулирования функции на заданном отрезке с заданным шагом. Алгоритм сводится к циклу, на каждой итерации которого вычисляется значение f в одной из точек. Например, при a=-6, b=6, p=1 выполняется 13 итераций цикла: будет вычислено значение функции в точках x=-6; -5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5; 6. Строго говоря, в некоторых точках при |x|<5 функция не определена, поскольку имеет место выход за область определения арккосинуса. В случае языка C# при этом будет выдано значение NaN, обозначающее, что величина не является действительным числом.
Перед тем, как выполнять цикл, следует увеличить b на некоторую малую величину, такую, что практическое применение программы предполагает значения p заведомо больше этой величины. Дело в том, что без увеличения b возможны ситуации, когда b-a нацело делится на p, однако значение в точке b не будет вычислено ввиду того, что p хранится с погрешностью: не все конечные десятичные дроби могут быть представлены как конечные дроби в двоичной системе счисления (пример: дроби 0,1 или 0,4 в десятичной системе бесконечны в двоичной).
Рис. 1. Блок-схема алгоритма табулирования функции
-
3. Исходный код программы
using System;
namespace Laboratorka
{
class Program
{
static void Main(string[] args)
{
double a, b, p, f;
Console.Write("Введите левый конец: ");
a = Convert.ToDouble(Console.ReadLine());
Console.Write("Введите правый конец: ");
b = Convert.ToDouble(Console.ReadLine());
Console.Write("Введите шаг табуляции: ");
p = Convert.ToDouble(Console.ReadLine());
b += 0.0000001;
Console.WriteLine("{0, 30}{1, 30}", "x", "f");
for (double x = a; x <= b; x += p)
{
if (Math.Abs(x) < 5.0)
f = 2.0 * x - 4.0 * Math.Pow(Math.Acos(x), 3.0);
else f = Math.Tan(x) - 5.0;
Console.WriteLine("{0, 30}{1, 30}", x, f);
}
Console.ReadKey();
}
}
}
-
4. Тестирование
На рис. 2 представлен основной тест программы. Проверка правильности выполнялась путём сопоставлением с результатами в Mathcad. Заметим, что комплексным числам в Mathcad соответствует значение NaN в разработанной программе. Преимущества представленного теста:
1) небольшое число точек (вся таблица видна на экране одновременно);
2) охватывает и целые, и дробные значения аргумента;
3) включает особые точки (x=-5 и x=5 - граничные значения в силу задания ветвей функции; x=-1 и x=1 - границы области определения арккосинуса).
На рис. 3-4 представлены результаты эксперимента, показывающего значимость строки кода, меняющей значение b на малую величину. На рис. 3 показан результат без строки, на рис. 4 - со строкой.
Рис. 2. Тестирование со сравнением с результатами в Mathcad
Рис. 3. Проблема потерянного конца
Рис. 4. Решённая проблема потерянного конца