Lab_1_2
.pdfРисунок – Диалоговая форма приложения slave.exe до и после изменения текстовых данных в памяти
Рисунок – Консольный вывод приложения master.exe в ходе поиска и изменения текстовых данных в памяти стороннего процесса
Наблюдать процесс поиска текстовой строки в виде «сырой» последовательности байт в памяти стороннего процесса. Заголовок диалогового окна должен измениться после успешного завершения ведущего приложения.
12. Оформить отчёт и ответить на контрольные вопросы.
1.3.2 Содержание отчёта
Отчёт о лабораторной работе должен содержать:
1.Название, цель и задачи лабораторной работы.
2.Зафиксировать результаты работы по пунктам задания. Необходимо отделит введенные вами код от ответов программы. В качестве результатов отражайте:
2.1.Комментарии;
2.2.Текст программ реализации арифметических действий.
2.3.Программный код
3.Ответы на контрольные вопросы.
|
21 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
1.4 Контрольные вопросы
1.Какие существуют форматы чисел?
2.Как задать число с клавиатуры?
3.Как выполнить арифметические операции над целыми числами и числами с фиксированной точкой?
4.Как выполнить математические операции над числами с плавающей точкой?
5.Перечислите основные шаги по переводу чисел в формат IEEE754 и обратно?
6.Расскажите о порядке байт в многобайтном представлении чисел.
7.Перечислите основные математические операции с двоичными числами.
8.Расскажите об используемых библиотечных функциях для преобразования и форматированного вывода чисел в различных системах счисления.
9.Расскажите об особенностях операций с вещественными числами с плавающей запятой.
10.Расскажите способы представления текстовой информации в памяти ЭВМ.
1.5 Список литературы
1.http://habrahabr.ru/post/112953/
2.http://www.h-schmidt.net/FloatConverter/IEEE754.html
3.http://planetcalc.ru/747/
4.Kernighan B., Ritchie D. / Керниган Б., Ритчи Д. - The C Programming Language, Second Edition / Язык программирования Си (2-е издание)
1.6 Приложения
Если имеется некоторое число x, для хранения которого использован четырехбайтный целочисленный тип int в программе на языке С/С++, то получить произвольный бит на позиции pos можно с помощью следующей функции:
unsigned int getBits(int x, unsigned int pos)
{
return ( ((x >> pos) & 1) ? 1 : 0);
}
Структура файла general.h: |
|
|
22 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
//Представление двухбайтного беззнакового целого в виде числа и массива байт.
//integerValue = 1 = 0x0001
//Если порядок от младшего к старшему (little-endian), то будет:
//[00000001] [00000000] = [0x01] [0x00]
//Елси порядок от старшего к младшему (big-endian), то будет:
//[00000000] [00000001] = [0x00] [0x01]
union ByteOrder
{
unsigned char bytesArray[2]; unsigned short integerValue;
};
// Функция осуществляет проверку порядка байт на данной машине void checkByteOrder()
{
ByteOrder num;
num.integerValue = 1; //1 = 0x0001 = 00000000 00000001
printf("Unsigned short value = 0x%04x\n", num.integerValue); printf("bytes[0] = 0x%02x\n", num.bytesArray[0]); printf("bytes[1] = 0x%02x\n", num.bytesArray[1]);
if (num.bytesArray[0] == 1) { printf("little-endian bytes order\n");
}
else {
printf("big-endian bytes order\n");
}
}
// Функция, позволяющая получить бит в числе x на позиции unsigned int getBits(int x, unsigned int pos)
{
return ( ((x >> pos) & 1) ? 1 : 0 );
}
Структура файла integers.h
// ПРИМЕР
|
23 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
// Проверка порядка байт на данной машине void printByteOrder(int numExample)
{
…
checkByteOrder();
}
//ПРИМЕР
//Библиотечная функция преобразования целого числа в произвольную систему
//счисления
void |
convertIntNumbers(int numExample) |
{ |
|
// Буфер для хранения строкового представления числа const size_t BUFSIZE = 65;
char buffer[BUFSIZE];
int newRadix = 16; // Основание новой системы счисления int convertedNum = -666; // Число, которое преобразуется
_itoa(convertedNum, buffer, newRadix);
printf("============================\n");
printf("Example %d: Convert integer from decimal to:\n", numExample); printf("Num = %d\n", convertedNum);
printf("Base %d: \n\tnum_%d = %s (%d chars)\n", newRadix, newRadix, buffer, BUFSIZE);
newRadix = 2;
_itoa(convertedNum, buffer, newRadix);
// Сравнение полученных результатов преобразования и ручного перебора бит printf("Num = %d\n", convertedNum);
printf("Base %d: \n\t%s (%d chars)\n", newRadix, buffer, BUFSIZE); printf("Convert with getBits() \n\t");
for (int i = 31; i > -1; i--) { printf("%u", getBits(convertedNum, i));
}
printf("\n");
}
|
24 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
Структура файла floats.h
// Представление числа с одинарной точностью в виде целого числа union ParsedFloat
{
float value; __int32 integer;
unsigned char byteArray[4];
struct ieee_t
{
unsigned int mantissa : 23; unsigned int exponenta : 8; unsigned int sign : 1;
} ieee;
};
//Печать представления числа с плавающей точкой в виде набора байт
//в шестандцатиричном формате
void printParsedFloatToHex(ParsedFloat &parsedFloat)
{
printf("Float number: dec = %f, hex = ", parsedFloat.value); for (int i = 3; i > -1; i--)
printf("0x%02X ", parsedFloat.byteArray[i]); printf("\n");
}
// Функция, имитирующая работу фармокомбайна void farmaSimulation()
{ |
|
|
|
|
float |
bunker, |
// исходный вес бункера |
||
|
bufBunker, |
|
|
|
|
bunker1, |
// вес бункера после очередной итерации |
||
|
tablet, |
// вес таблетки |
||
итерациях |
tablet1, |
// |
вес таблетки с учетом ошибки в предыдущих |
|
compens, |
// компенсация веса таблетки |
|||
|
||||
|
bufBadBunker, |
|
|
|
|
badBunker; |
|
|
|
|
|
|
|
|
|
|
|
25 |
|
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
long int n; |
// количество циклов |
tablet = 0.00001; tablet1 = 0.0; bunker = 300.0; bunker1 = 0.0; compens = 0.0;
badBunker = bunker; bufBunker = bunker; bufBadBunker = bunker;
n = 10000000;
printf("Source bunker capasity = %04.5f kg\n", bunker); for (long int i = 0; i < n; i++) {
// вес таблетки с компенсацией ошибки tablet1 = tablet - compens;
// вес бункера после вычета скомпенсированной таблетки bunker1 = bunker - tablet1;
// вычисление компенсации для следующей итерации compens = (bunker - bunker1) - tablet1;
// новый вес бункера bunker = bunker - tablet1;
// второй бункер не учитывает поправки на суммирование badBunker -= tablet;
}
printf("Final bunker capasity = %04.5f kg\n", bunker);
printf("Out = %04.5f kg \t diff = %04.5f kg\n\n", tablet*n, bufBunker - bunker);
printf("Final bad bunker capasity = %04.5f kg\n", badBunker);
printf("Out = %04.5f kg \t diff = %04.5f kg\n", tablet*n, bufBadBunker - badBunker);
|
26 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
}
//ПРИМЕР
//Пример прямого и обратного преобразования вещественного числа в двоичное
//представление
void convertFloatNumbers(int numEx)
{
printf("============================\n");
printf("Example %d: Parse float number s*m*2^e\n", numEx); ParsedFloat ft;
//ft.value = -25.625; ft.value = 155.625;
//ft.value = -6.2598534E18f;
//ft.value = -0.34375f;
//Прямое
printf("Float number = %f\n", ft.value);
printf("s_16 = %x\ts_10 = %u\n", ft.ieee.sign, ft.ieee.sign); printf("e_16 = %x\te_10 = %u\n", ft.ieee.exponenta, ft.ieee.exponenta); printf("m_16 = %x\tm_10 = %u\n", ft.ieee.mantissa, ft.ieee.mantissa);
// Обратное:
long s = (ft.ieee.sign) ? -1 : 1; long e = ft.ieee.exponenta - 127; long m = ft.ieee.mantissa;
printf("Back composed float number = %f\t[pow]\n", s * (1 + m / pow(2.0, 23)) * pow(2.0, e)); // Строки эквиваленты
printf("Back composed float number = %f\t[shifts]\n", s * (1 + m / (2 << 23)) * (2 << e)); // Строки эквиваленты
// Печать числа в виде октетов в 16 ричном представлении printParsedFloatToHex(ft);
}
//ПРИМЕР
//Сравнение вещественных чисел с плавающей запятой.
//Сравнение значений float и double
void |
compareFloatNums(int numEx) |
|
{ |
|
|
|
|
|
|
|
27 |
|
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
float a = 0.2f; printf("============================\n");
printf("Example %d: Compare two floating point numbers:\n", numEx); printf("Float num = %.15f\n", 0.2f);
printf("Double num = %.30f\n", 0.2);
// float == double? if (a == 0.2) {
printf("YES: %f == 0.2\n", a);
}
else {
printf("NO: %f != 0.2\n", a);
}
}
//ПРИМЕР
//Сравнение ошибки суммирования чисел в формате float и double
void |
compareSumFloatNums(int numEx) |
{ |
printf("============================\n"); |
|
|
|
printf("Example %d: Error sum of float numbers\n", numEx); |
|
unsigned int startNum = 512; |
|
for (unsigned int curNum = startNum - 5; curNum < startNum + 5; curNum++) { |
|
float step = 1.0 / curNum; |
|
float curSum = 0.0; |
|
//double step = 1.0 / curNum; |
|
//double curSum = 0.0; |
|
for (unsigned int i = 1; i < curNum + 1; i++) { |
|
//printf("step*curNum = %.15f\n", step*curNum); |
|
curSum += step; |
|
} |
|
printf("num = %u\tsum = %g\n", curNum, curSum - 1); |
} |
} |
|
//ПРИМЕР
//Абсолютные ошибки суммирования чисел в формате float и double
void |
compareSumFloatDoubleNums(int numEx) |
|
|
28 |
|
|
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
{
printf("============================\n");
printf("Example %d: Error sum of float numbers\n", numEx); float c, d, f;
//double c, d, f; c = 123456789;
d = 123456788; f = c - d;
printf("Answer = %f\tSolution = %f\n", 1.0, f);
}
//ПРИМЕР
//Проверка выполнения закона коммутативности
void |
checkCommutativeLaw(int numEx) |
{ |
|
printf("============================\n"); printf("Example %d: Check commutative law\n", numEx); float val = 10e20;
printf("(10^20 + 1) - 10^20 = %.15f\n(10^20 - 10^20) + 1 = %.15f\n", (val + 1) - val, (val - val) + 1);
}
//ПРИМЕР
//Циклические ошибки суммирования чисел в формате float
void |
checkCycleSumErrors(int numEx) |
{ |
|
printf("============================\n"); printf("Example %d: Check cycle sum errors\n", numEx); farmaSimulation();
}
//ПРИМЕР
//Вычисление машинной эпсилон
void |
calcEpsilon(int numEx) |
{ |
|
printf("============================\n"); printf("Example %d: Calc epsilon\n", numEx);
float e = 0.0;
|
29 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |
float e1 = 0.0; int k = 0;
e = 1.0; do
{
e = e / 2.0; e1 = e + 1.0; k++;
} while (e1 > 1.0); printf("eps = %e\n", e);
}
//ПРИМЕР
//Переполнение и потеря значимости
void |
calcOverflow(int numEx) |
{ |
|
printf("============================\n"); printf("Example %d: Calc overflow\n", numEx);
float a = FLT_MAX / 4.0; float b = sqrt( a*a ) / 4.0; printf("a = %e\n", a); printf("b = %e\n", b);
}
Структура файла main.h:
int main(int argc, char** argv)
{
int numEx = 0;
printByteOrder(++numEx);
convertIntNumbers(++numEx);
convertFloatNumbers(++numEx);
compareFloatNums(++numEx);
compareSumFloatNums(++numEx);
compareSumFloatDoubleNums(++numEx);
checkCycleSumErrors(++numEx);
checkCommutativeLaw(++numEx);
|
30 |
Д.И. Кардаш, А.М. Вульфин |
Лабораторные работы СВТ |