Загрузка данных


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;
}
```