Файл: Разработка модуля для выполнения операций с натуральными числами в 16-ричной системе счисления (1 Выбор и проработка программных средств).pdf
Добавлен: 04.07.2023
Просмотров: 54
Скачиваний: 2
Так же, как и в классе Sorting, публичный метод Start начинает тестирование. Инкапсулированный метод creatingNumbers предоставляет пользователю возможность ввести основание и степень для вычислений с проведением соответствующих проверок.
Структурная схема разработанного приложения представлена на рисунке 2.2.
Рисунок 2.2 – Структурная схема приложения HEXNumbers
Глава 3. Описание алгоритмов и текст программы
3.1 Создание и конвертация шестнадцатеричных чисел
Конструктор класса HEX перегружен и может принимать как число в десятичном представлении, так и строку, содержащую шестнадцатеричный вариант числа.
public HEX(int decNumber)
{ _number = decNumber; }
public HEX(string hexNumber)
: this(ConvertFromHEX(hexNumber))
{}
_number является скрытым членом типа int, который содержит десятичное представление создаваемого числа. В случае первого конструктора аргумент просто присваивается инкапсулированному члену. При применении перегруженного варианта конструктора к члену _number присваивается результат статического метода ConvertFromHEX.
public static int ConvertFromHEX(string hex)
{
ThrowExceprtionIfNotValidHEX(hex);
return int.Parse(hex, NumberStyles.HexNumber);
}
В этом случае производится проверка на правильность указания шестнадцатеричного числа в строке с помощю метода ThrowExceprtionIfNotV alidHEX.
static void ThrowExceprtionIfNotValidHEX(string hex)
{
if (!CorrectHEXNumber(hex)) throw new ApplicationException();
}
Проверка производится с помощью публичного статического метода CorrectHEXNumber. Если проверка оказывается провальной, вызывается исключение типа ApplicationException, как безопасного типа исключения для системы.
public static bool CorrectHEXNumber(string hex)
{
return HEXExpression.Match(hex).Value == hex;
}
Для проведения проверки используется регулярное выражение, с помощью метода можно возвратить ту часть строки, которая удовлетворяет заданному шаблону. В данном случае проводится проверка на равенство исходной строки и результата сравнения регулярного выражения.
Регулярное выражение, которое определяет символы шестнадцатеричного представления числа, создается следующим образом:
static Regex HEXExpression;
HEXExpression = new Regex("[0-9a-fA-F]+");
Для присваивания значения члену _number используется перегруженный метод int.Parse, в параметрах которого указывается строка, содержащая нужное число, и система счисления, которая используется в представлении.
Открытый рефлектором метод Parse выглядит следующим образом.
public static int Parse(string s, NumberStyles style)
{
NumberFormatInfo.V alidateParseStyleInteger(style);
return Number.ParseInt32(s, style, NumberFormatInfo.CurrentInfo);
}
internal static unsafe int ParseInt32(string s, NumberStyles style, NumberFormatInfo info)
{
byte* stackBuffer = stackalloc byte[114];
Number.NumberBuffer number = new Number.NumberBuffer(stackBuffer);
int num = 0; Number.StringToNumber(s, style, ref number, info, false);
if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
{
if (!Number.HexNumberToInt32(ref number, ref num)) throw new OverflowException (Environment.GetResourceString ("Overflow_Int32"));
} else if (!Number.NumberToInt32(ref number, ref num))
throw newOverflowException(Environment.GetResourceString("Overflow_Int32"));
return num;
}
Метод ConvertFromHEX перегружен и может иметь следующее представление.
public static int ConvertFromHEX(HEX hex)
{
return ConvertFromHEX(hex.ToString());
}
Преобразование из десятичного представления в шестнадцатеричное обеспечивается следующим кодом.
public static HEX ConvertFromDecimal(int dec)
{
return new HEX(dec.ToString("X"));
}
Метод ToString целочисленного типа данных (int) позволяет преобразовать число в форматированную строку, с форматом, указанным в качестве аргумента метода. Сам метод ToString(string) выглядит так, как представлено в коде ниже.
public string ToString(string format)
{
return Number.FormatInt32(this, format, NumberFormatInfo.CurrentInfo);
}
3.2 Арифметические операции HEX
По условию задания класс должен обеспечивать следующие математические операции над HEX-числами:
- сложение;
- вычитание;
- умножение;
- деление.
Для выполнения этих действий были разработаны статические операторы типа HEX, которые преобразовали аргумент типа HEX в десятичный вид, далее выполнялись необходимые математические действия, а дальше конечный результат преобразовывался обратно в шестнадцатеричное представление.
Представим код разработанных операторов.
public static HEX operator +(HEX h1, HEX h2)
{ return new HEX(h1._number + h2._number); }
public static HEX operator -(HEX h1, HEX h2)
{ return new HEX(h1._number - h2._number); }
public static HEX operator *(HEX h1, HEX h2)
{ return new HEX(h1._number * h2._number); }
public static HEX operator /(HEX h1, HEX h2)
{ return new HEX(h1._number / h2._number); }
Так как операторы принадлежит тому типу данных, над которым происходят операции, у методов есть доступ к скрытым данным, в данном случае это член _number.
3.3 Сортировка чисел
Для пользователя статический класс для сортировки массива данных типа HEX представлен единственным методом Start. Код этого класса для удобства чтения и модификаций разбит на несколько частей (методов) и выглядит так, как показано ниже.
public static void Start(int count)
{
Console.WriteLine(string.Format("создание массива из {0} случайных HEX-чисел:", count));
creating(count);
showArray();
Console.Write("\nсортировка массива...");
Console.WriteLine(string.Format("{0} ms", sortList())); Console.WriteLine("\nрезультат в шестнадцатиричном представлении:"); showArray(); Console.WriteLine("\nрезультат в десятичном представлении:"); showArrayDec(); Console.WriteLine("\nнажмите любую клавишу для завершения..."); Console.ReadKey();
}
Аргумент count определяет количество чисел в динамическом массиве, который будет содержать данные, предназначенные для сортировки.
Все действия класса оповещаются соответствующими подсказками в консоли. Первым этапом является создание массива в коде creating.
static List<HEX> _array; static void creating(int count) {
_array.Clear(); for (int i = 0; i < count; i++)
_array.Add(new HEX(_random.Next(byte.MaxValue))); }
Сам массив представляет собой динамическую коллекцию объектов типа HEX. Особенностью такого выбора явился широкий спектр возможностей данного типа коллекций. В частности, размер коллекции не является фиксированным, что удобно при создании массивов, истинное число членов которого не может быть неизвестно заранее, или блоки данных могут добавляться в несколько заходов. Также интерфейсы IList и IList<T> позволяют конвертировать коллекцию в массив типа T[], производить сортировку по заданному алгоритму, динамически добавлять и удалять данные, производить поиск по определенному выражению и так далее.
Метод showArray выводит данные массива на консоль. Также присутствует похожий метод showArrayDec, который выводит данные этого же массива, но в десятичном представлении. Код этих методов представлен ниже.
static void showArray()
{
foreach (HEX h in _array) Console.Write(string.Format("{0}, ", h.ToString()));
Console.WriteLine();
}
static void showArrayDec()
{
foreach (HEX h in _array) Console.Write(string.Format("{0}, ", HEX.ConvertFromHEX(h.ToString())));
Console.WriteLine();
}
Оба метода используют для вывода форматированную строку, которая создается методом string.Format. Использование этого метода позволяет создавать новый объект строчного типа в одну строку без создания «временных» строковых констант и конкатенаций строк. Такой способ, как известно, существенно экономит ресурсы управляемой кучи .NET. Для перебора всех значений массива используется итератор foreach, который поддерживается типом данных List<T>.
Последним шагом является сортировка массива, а также вывод данных на консоль. Сортировка производится с помощью метода sortList, который, к тому же, возвращает количество занятого процессом времени в миллисекундах.
static long sortList()
{
long time = DateTime.Now.Ticks;
_array.Sort((h1, h2) =>
{
int _h1 = HEX.ConvertFromHEX(h1.ToString()),
_h2 = HEX.ConvertFromHEX(h2.ToString());
return _h1 == _h2 ? 0 : _h1 > _h2 ? -1 : 1;
});
return (DateTime.Now.Ticks - time) / 10000;
}
Сортировка массива производится по заданному в параметрах метода Sort делегата возвращаемому значению. Начиная с версии .NET Framework 3.5 пользователю предоставляется возможность оперировать лямбда-выражениями, которые во многих случаях заменяют многострочные операции создания и инициализацию предикатов и делегатов.
Сама сортировка коллекций данных выполняется по следующему принципу: если значения двух объектов равны, делегатом возвращается значение 0, если первый операнд больше второго, возвращается 1 и в противоположном случае – -1. Так как по условию задания задана сортировка по убыванию, условия возврата значений 1 и -1 необходимо поменять местами.
Для упрощения записи использовался тринарный оператор ?:, который заменяет присваивание данных в конструкции if-else.
Блок-схема алгоритма сортировки объектов класса HEX представлена на рисунке 3.1.
Рисунок 3.1 – Блок-схема алгоритма сортировки объектов HEX
3.4 Возведение в степень
Класс, позволяющий возвести число в степень, указанные в шестнадцатеричном виде, также представляет из себя метод Start(), который содержит основную логику действия.
public static void Start()
{
creatingNumbers();
Console.WriteLine(string.Format("число '{0}' будет возведено в степень '{1}'", _number, _power));
Console.WriteLine(string.Format("результат в шестнадцатеричном представлении: {0}", _result
new HEX((int)Math.Pow(HEX.ConvertFromHEX(_number.ToString()), HEX.ConvertFromHEX(_power.ToString())))));
Console.WriteLine(string.Format("результат в десятичном представлении: {0}", HEX.ConvertFromHEX(_result.ToString())));
Console.WriteLine(string.Format("нажмите любую клавишу для завершения...{0}", Console.ReadKey()));
}
Вторым и последним методом в классе является метод creatingNumbers, содержащий в себе интерфейс ввода пользователем необходимых чисел и функции их проверки.
Для начала пользователю предлагается ввести необходимые число и показатель степени с консоли. Следующим этапом является проверка правильности введенного шестнадцатеричного числа методом HEX.CorrectHEXNumber. Если обе проверки прошли успешно, инициализируются соответствующие HEX-члены класса, которые далее, в методе Start, участвуют в вычислениях.
Результат вычислений записывается в объект _result и подсчитывается с использованием стандартного класса Math и его метода, позволяющего произвести подсчет степени, Pow, который принимает два числа типа double, или совместимые с ним, и возвращает тоже тип double, который после явно приводится к целочисленному типу данных.
static HEX _number, _power, _result; static void creatingNumbers()
{
string number, power; do
{
Console.Clear(); Console.Write("введите число, возводимое в степень в HEX-представлении: ");
number = Console.ReadLine();
Console.Write("введите степень в HEX-представлении: ");
power = Console.ReadLine();
} while (!(HEX.CorrectHEXNumber(number) && HEX.CorrectHEXNumber(power)));
_number = new HEX(number);
_power = new HEX(power);
}
Блок-схема алгоритма возведения числа в степень представлена на рисунке 3.2.
Правильность расчетов, производимых разработанными классами, определяется проверочными тестами в разделе 4 данной работы.
Рисунок 3.2 – Блок-схема алгоритма возведения числа в степень
Глава 4. Тестирование и анализ результатов работы программы
Первым тестом при запуске приложения запускается сортировка массива из 100 случайных чисел. Результат работы программы представлен на рисунке 4.1.
Рисунок 4.1 – Сортировка массива
Как видно на рисунке, данные отсортированы по убыванию от 253 до 1, а на процесс сортировки ушло 20 миллисекунд.
После нажатия клавиши происходит переход к тесту возведения числа в степень. И первым пользователю предлагается ввести число, которое нужно возвести в степень, и сам показатель степени.
В качестве теста введем неверные данные (“az” и “-15”). Так как программа не приняла один из ответов (а в нашем случае оба) правильными, данные не записываются, и предлагается повторить попытку еще раз.
Введем для числа, возводимого в степень значение 10, что соответствует шестнадцатеричному представлению «А», а для показателя степени – 4, в hex-виде значение будет таким же.
Приложение оповестило, что число «А» будет возведено в степень «4» и представила результаты – в десятичном представлении это 10000, в представлении hex – 2710.
Рисунок 4.2 – Ввод неверных данных в окно тестирования
Рисунок 4.3 – Возведение А в степень 4
В качестве проверки на правильность расчетов воспользуемся стандартным Windows-калькулятором, в котором есть возможность конвертировать текущее число в различные системы счисления. 10000 в представлении hex отображена на рисунке 4.4.