Загрузка данных
1 ХОД ВЫПОЛНЕНИЯ РАБОТЫ
1.1 Создание функции вывода битов
Для выполнения задания была создана функция print_bits_simple, которая выводит битовое представление любого участка памяти.
Алгоритм работы функции:
1. На вход функция получает указатель на данные и их размер в байтах.
2. Указатель приводится к типу unsigned char* для побайтового доступа к памяти.
3. Внешний цикл проходит по всем байтам от старшего к младшему.
4. Внутренний цикл проходит по битам каждого байта от 7 к 0.
5. Каждый бит извлекается с помощью сдвига вправо и побитового И с 1.
6. Биты выводятся на экран, между байтами добавляется пробел для наглядности.
```c
void print_bits_simple(void *data, int size) {
unsigned char *p = (unsigned char*)data;
for (int i = size - 1; i >= 0; i--) {
for (int j = 7; j >= 0; j--) {
printf("%d", (p[i] >> j) & 1);
}
printf(" ");
}
printf("\n");
}
```
1.2 Добавление переменных разных типов
В функции main были объявлены переменные различных типов для демонстрации работы программы:
Целые числа:
· char signed_char = -5 — однобайтовое знаковое
· unsigned char unsigned_char = 5 — однобайтовое беззнаковое
· short int signed_short = -32768 — двухбайтовое знаковое
· unsigned short int unsigned_short = 32768 — двухбайтовое беззнаковое
· int signed_int = -10 — четырехбайтовое знаковое
· unsigned int unsigned_int = 10 — четырехбайтовое беззнаковое
Вещественные числа:
· float float_num = 0.5f — четырехбайтовое
· float float_negative = -1.0f — четырехбайтовое отрицательное
· double double_num = 0.5 — восьмибайтовое
1.3 Вывод результатов
Для каждой переменной был организован вывод с поясняющей подписью:
```c
printf(" signed char (-5): ");
print_bits_simple(&signed_char, sizeof(signed_char));
```
Функция print_bits_simple вызывается с передачей адреса переменной и её размера, определенного с помощью оператора sizeof.
1.4 Запуск программы
Программа была скомпилирована и запущена. Все переменные были успешно выведены в битовом представлении. Результаты работы программы приведены в разделе 2 "ТЕСТИРОВАНИЕ".
---
2 ТЕСТИРОВАНИЕ
2.1 Результаты выполнения программы
```
=== ЦЕЛЫЕ ЧИСЛА ===
1 байт (char):
signed char (-5): 11111011
unsigned char (5): 00000101
2 байта (short):
signed short (-32768): 10000000 00000000
unsigned short (32768): 10000000 00000000
4 байта (int):
signed int (-10): 11111111 11111111 11111111 11110110
unsigned int (10): 00000000 00000000 00000000 00001010
=== ВЕЩЕСТВЕННЫЕ ЧИСЛА ===
4 байта (float):
float (0.5): 00111111 00000000 00000000 00000000
float (-1.0): 10111111 10000000 00000000 00000000
8 байт (double):
double (0.5): 00111111 11100000 00000000 00000000 00000000 00000000 00000000 00000000
```
2.2 Объяснение результатов
2.2.1 Целые числа
Однобайтовые числа:
· unsigned char (5): 5 = 00000101 в двоичной системе. Вывод совпадает.
· signed char (-5): Отрицательные числа хранятся в дополнительном коде. Для -5: инвертировать 00000101 → 11111010, прибавить 1 → 11111011. Вывод подтверждает это.
Двухбайтовые числа:
· unsigned short (32768): 32768 = 2^15 = 10000000 00000000.
· signed short (-32768): Минимальное отрицательное число тоже имеет код 10000000 00000000.
Четырехбайтовые числа:
· unsigned int (10): 10 = 00000000 00000000 00000000 00001010.
· signed int (-10): В дополнительном коде -10 = 11111111 11111111 11111111 11110110.
2.2.2 Вещественные числа
Число 0.5 в формате float:
· По стандарту IEEE 754: 0.5 = 1.0 × 2^(-1)
· Знак: 0
· Экспонента: -1 + 127 = 126 = 01111110
· Мантисса: 0
· Итог: 00111111 00000000 00000000 00000000
Число -1.0 в формате float:
· -1.0 = -1.0 × 2^(0)
· Знак: 1
· Экспонента: 0 + 127 = 127 = 01111111
· Мантисса: 0
· Итог: 10111111 10000000 00000000 00000000
Число 0.5 в формате double:
· Аналогично float, но с 11-битной экспонентой (смещение 1023)
· Экспонента: -1 + 1023 = 1022 = 01111111110
· Итог: 00111111 11100000 00000000 00000000 00000000 00000000 00000000 00000000
---
ЗАКЛЮЧЕНИЕ
В ходе выполнения лабораторной работы была разработана программа на языке C для вывода битового представления числовых данных различных типов.
В результате работы были достигнуты следующие цели:
1. Разработана универсальная функция print_bits_simple, позволяющая выводить битовое представление любого участка памяти.
2. Продемонстрировано битовое представление целых чисел:
· Для положительных чисел используется прямой код.
· Для отрицательных чисел используется дополнительный код.
· Беззнаковые и знаковые числа одинаково хранятся в памяти, но по-разному интерпретируются.
3. Продемонстрировано битовое представление вещественных чисел:
· Числа хранятся по стандарту IEEE 754.
· Число представляется в виде знака, экспоненты и мантиссы.
· Для типов float и double используются разные форматы.
4. Получены навыки работы с указателями и побитовыми операциями в языке C.
Таким образом, цель работы полностью достигнута. Полученные знания о способах хранения числовых данных в памяти ЭВМ позволяют глубже понять принципы работы компьютерной архитектуры и низкоуровневого программирования.
---
ПРИЛОЖЕНИЕ А (обязательное)
Листинг программы
```c
#include <stdio.h>
/**
* Выводит битовое представление области памяти
*
* @param data - указатель на начало области памяти
* @param size - размер области памяти в байтах
*/
void print_bits_simple(void *data, int size) {
unsigned char *p = (unsigned char*)data;
// Проходим по байтам от старшего к младшему
for (int i = size - 1; i >= 0; i--) {
// Проходим по битам внутри байта от 7 к 0
for (int j = 7; j >= 0; j--) {
// Извлекаем j-й бит
printf("%d", (p[i] >> j) & 1);
}
// Разделяем байты пробелом
printf(" ");
}
printf("\n");
}
int main() {
// ---- ЦЕЛЫЕ ЧИСЛА ----
// 1 байт (char)
char signed_char = -5;
unsigned char unsigned_char = 5;
// 2 байта (short)
short int signed_short = -32768;
unsigned short int unsigned_short = 32768;
// 4 байта (int)
int signed_int = -10;
unsigned int unsigned_int = 10;
// ---- ВЕЩЕСТВЕННЫЕ ЧИСЛА ----
// 4 байта (float)
float float_num = 0.5f;
float float_negative = -1.0f;
// 8 байт (double)
double double_num = 0.5;
// ---- ВЫВОД РЕЗУЛЬТАТОВ ----
printf("=== ЦЕЛЫЕ ЧИСЛА ===\n\n");
printf("1 байт (char):\n");
printf(" signed char (-5): ");
print_bits_simple(&signed_char, sizeof(signed_char));
printf(" unsigned char (5): ");
print_bits_simple(&unsigned_char, sizeof(unsigned_char));
printf("\n2 байта (short):\n");
printf(" signed short (-32768): ");
print_bits_simple(&signed_short, sizeof(signed_short));
printf(" unsigned short (32768):");
print_bits_simple(&unsigned_short, sizeof(unsigned_short));
printf("\n4 байта (int):\n");
printf(" signed int (-10): ");
print_bits_simple(&signed_int, sizeof(signed_int));
printf(" unsigned int (10): ");
print_bits_simple(&unsigned_int, sizeof(unsigned_int));
printf("\n=== ВЕЩЕСТВЕННЫЕ ЧИСЛА ===\n\n");
printf("4 байта (float):\n");
printf(" float (0.5): ");
print_bits_simple(&float_num, sizeof(float_num));
printf(" float (-1.0): ");
print_bits_simple(&float_negative, sizeof(float_negative));
printf("\n8 байт (double):\n");
printf(" double (0.5): ");
print_bits_simple(&double_num, sizeof(double_num));
return 0;
}
```