ЯП2 / ЯП2
.pdfМинистерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования
ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР) Кафедра безопасности информационных систем (БИС)
Отчет по лабораторной работе №2 по дисциплине «Языки программирования»
По теме «Вещественные числа. Ошибки при работе с вещественными числами»
Студент гр. 731-2
_____________ А.Д. Коноваленко
_____________
Принял Доцент каф. КИБЭВС
_________ _____________ А.С. Романов
_____________
Томск 2023
|
СОДЕРЖАНИЕ |
|
Введение .................................................................................................................. |
3 |
|
1 ХОД РАБОТЫ...................................................................................................... |
4 |
|
1.1 |
Ручное вычисление........................................................................................ |
4 |
1.2 |
Возникновения программных ошибок ........................................................ |
4 |
Заключение........................................................................................................... |
8 |
|
Приложение А...................................................................................................... |
9 |
2
Введение
Цель работы: знакомство с основными ошибками, возникающими при обработке вещественных чисел.
3
1 ХОД РАБОТЫ
1.1 Ручное вычисление
Согласно варианту задания были получены следующие значения чисел:
X = 21730337312,21062003;
Y = X * 10-10= 2,173033731221062003;
С = X+Y = 21730337314,243753761221062003; C’ = 21730337314,243753761;
Z = X±10-8= (21730337312,21062002; 21730337312,21062004); K = 21730337312;
Абсолютная ошибка: А = |С-С’|= 0,000000000221062003;
Относительная ошибка: О = А/C = 1,0173*10-20.
Предположим, что в младшем разряде X произошла ошибка, тогда
Z = X – 0,001 = 21730337 312,20962003.
Умножение без ошибки будет равняться: m = X*X=472207559702453073937,17147951704.
Умножение с ошибкой будет равняться: n = X*Z = 472207559702431343599,85926889701.
Абсолютная ошибка данных значений будет равняться А = |m-n| = 21 730 337,3122106200272009.
Относительная ошибка данных значений будет равняться О = A/m = 4,60186*10-14.
При округлении X до целого числа абсолютная ошибка будет равняться А = |X-K| = 0,21062003; а относительная ошибка будет равняться О = A/X = 9,69244*10-12.
1.2 Возникновения программных ошибок
Коды примеров возникновения ошибок в вещественных числах были написаны на языке программирования С++. Листинг программы представлен
4
в приложении А.
На рисунках 1.1 - 1.2 представлены код и результат работы кода ошибки «Исчезновение операнда» соответственно.
Рисунок 1.1 – Код ошибки «Исчезновение операнда»
Рисунок 1.2 – Результат работы кода ошибки «Исчезновение операнда»
Ошибка «Исчезновение операнда» происходит если один операнд относительно мал по отношению с другим операндом. Поэтому операнд а1 был потерян, так как для типа данных float он слишком мал. В тоже время для типа данных double отводится больше памяти для вещественных чисел, поэтому операнд b1 был представлен без потерь.
На рисунках 1.3 - 1.4 представлены код и результат работы кода ошибки «Умножение ошибки» соответственно.
5
Рисунок 1.3 – Код ошибки «Умножение ошибки»
Рисунок 1.4 – Результат работы кода ошибки «Умножение ошибки»
Ошибка «Умножение ошибки» возникает при увеличении абсолютной погрешности операнда. В данном случае за счет постоянного увеличения значений. Ошибка возникает из-за увеличении операндов на значение 0.1, при том что данное значение в вещественных числах не может быть представлено точно.
На рисунках 1.5 - 1.6 представлены код и результат работы кода ошибки «Потеря значимости» соответственно.
6
Рисунок 1.5 – Код ошибки «Потеря значимости»
Рисунок 1.6 – Результат работы кода ошибки «Потеря значимости»
Ошибка «Потеря значимости» возникает при невозможности представить вычисления в допустимой форме. В данном случает из-за того, что числа приблизительно равны друг другу. И как упоминалось ранее тип данных double имеет больше выделенной памяти для вещественных чисел нежели тип данных float и поэтому имеет меньшую ошибку.
7
Заключение
В ходе выполнения работы было осуществлено знакомство с основными ошибками, возникающими при обработке вещественных чисел.
8
Приложение А
(Обязательное) Код программы
#include <iostream> int main()
{
setlocale(LC_ALL, "Russian");
std::cout << "Ошибка №1 - Исчезновение операнда" << std::endl; float a1 = 0.001f;
float b1 = 1000000.f; float result1 = a1 + b1; std::cout.precision(12);
std::cout << "Тип float. Результат - " << result1 << std::endl; double a2 = 0.001;
double b2 = 1000000.; double result2 = a2 + b2; std::cout.precision(11);
std::cout << "Тип double. Результат - " << result2 << std::endl; std::cout << "\n" << std::endl;
std::cout << "Ошибка №2 - Умножение ошибки" << std::endl; float a3 = 0.f;
double b3 = 0.;
for (int i = 0; i < 1000; i++)
{
a3 += 0.1f;
b3 += 0.1;
}
std::cout.precision(12);
std::cout << "Тип float. Результат - " << a3 << std::endl; std::cout.precision(12);
std::cout << "Тип double. Результат - " << b3 << std::endl; std::cout << "\n" << std::endl;
std::cout << "Ошибка №3 - Потеря значимости" << std::endl; float a4 = 1111111.1f;
float b4 = 1111111.0f; float result3 = a4 - b4; double a5 = 1111111.1; double b5 = 1111111.0; double result4 = a5 - b5; std::cout.precision(12);
std::cout << "Тип float. Результат - " << result3 << std::endl; std::cout.precision(12);
std::cout << "Тип double. Результат - " << result4 << std::endl;
}
9