8-916-722-04-28ТелВКонтактеВКTelegramTgMAXMAX Пробный урокПробный урок

Целые числа, дополнительный код отрицательных чисел, числа с плавающей точкой и формат IEEE 754

Форматы представления чисел в памяти

В памяти компьютера любое число хранится как последовательность бит фиксированной длины (разрядности), но способ интерпретации этих бит зависит от типа числа. Различают представление целых чисел без знака, целых чисел со знаком и вещественных (дробных) чисел — для каждого из этих типов используется свой формат кодирования.

Целые числа без знака

Целое число без знака хранится просто как его запись в двоичной системе счисления, дополненная нулями слева до нужной разрядности n. При разрядности n бит можно представить 2ⁿ различных неотрицательных чисел — от 0 до 2ⁿ−1 включительно. Например, при n=8 бит диапазон представимых чисел без знака — от 0 до 255 (2⁸−1).

Целые числа со знаком: прямой и обратный коды

Чтобы хранить и отрицательные числа, старший (самый левый) бит отводят под знак: 0 означает положительное число, 1 — отрицательное. В прямом коде положительного числа его абсолютная величина просто записывается в оставшихся n−1 битах; для отрицательного числа в прямом коде также записывается абсолютная величина, но со знаковым битом 1. Такой способ прост, но неудобен для арифметики: при сложении чисел разных знаков в прямом коде нельзя просто складывать биты столбиком. Промежуточный вариант — обратный (инверсный) код: для отрицательного числа все биты его прямого кода (кроме знакового) инвертируются (0 заменяется на 1 и наоборот).

Дополнительный код

На практике для хранения и обработки отрицательных целых чисел практически все современные компьютеры используют дополнительный код, который получают из обратного кода прибавлением единицы к младшему разряду. Главное преимущество дополнительного кода — вычитание чисел сводится к обычному сложению, что сильно упрощает устройство процессора: не нужен отдельный аппаратный узел для вычитания. Алгоритм получения дополнительного кода отрицательного числа −X при разрядности n бит:

1) записать модуль |X| в двоичной системе, дополнив нулями слева до n бит; 2) инвертировать все биты полученной записи (получить обратный код); 3) прибавить 1 к младшему разряду.

Пример 1. Запись отрицательного числа в дополнительном коде

Дано: запишите число −5 в дополнительном коде, используя 8 бит.

Решение. Модуль числа |5|=5=00000101₂ (дополнено нулями до 8 бит). Инвертируем все биты, получая обратный код: 11111010. Прибавляем 1 к младшему разряду:

−5=111110112(дополнительныйкод,8бит)

Ответ: 11111011₂. Проверка: как беззнаковое число 11111011₂=251, а 256−251=5 — то есть при интерпретации со знаком эта запись действительно кодирует −5.

Пример 2. Вычитание через сложение в дополнительном коде

Дано: вычислите 5+(−3), используя 8-битный дополнительный код, и убедитесь, что операция сводится к обычному сложению.

Решение. Дополнительный код числа 5: 00000101. Дополнительный код числа −3: модуль |3|=00000011, обратный код 11111100, дополнительный код 11111101. Складываем оба кода столбиком как обычные двоичные числа:

00000101+11111101=100000010

Так как разрядность фиксирована (8 бит), девятый (самый левый) бит переноса за пределы разрядной сетки отбрасывается, и остаётся результат 00000010₂=2.

Ответ: 5+(−3)=2 — результат сложения в дополнительном коде совпал с ожидаемым результатом обычного вычитания 5−3=2, что и демонстрирует главное преимущество дополнительного кода.

Диапазон представимых целых чисел

При разрядности n бит и использовании дополнительного кода один бит уходит под знак, поэтому диапазон представимых целых чисел со знаком:

от−2n−1до2n−1−1

Например, при n=8 бит диапазон — от −128 до 127 (обратите внимание на асимметрию: отрицательных значений на одно больше, так как ноль занимает одну из неотрицательных комбинаций). При n=32 бит (стандартный тип int во многих языках программирования) диапазон — от −2 147 483 648 до 2 147 483 647.

Числа с плавающей точкой

Для хранения вещественных (дробных) чисел с широким диапазоном значений (от очень маленьких до очень больших) используется формат с плавающей точкой, аналогичный экспоненциальной записи числа в математике: число представляется в виде произведения мантиссы (значащих цифр) на основание системы счисления в некоторой степени — порядке (экспоненте). Такое представление позволяет одним и тем же количеством разрядов охватить огромный диапазон величин ценой некоторой потери точности для очень больших чисел.

Формат IEEE 754

Наиболее распространённый стандарт хранения чисел с плавающей точкой — IEEE 754. В формате одинарной точности (32 бита, тип float) разряды распределены так: 1 бит под знак числа (s), 8 бит под порядок (экспоненту) со смещением 127, и 23 бита под дробную часть мантиссы. Число хранится в нормализованном виде — мантисса всегда начинается с неявной единицы перед точкой, поэтому эта единица в памяти не хранится явно, а лишь подразумевается. Значение числа вычисляется по формуле:

значение=(−1)s·1,мантисса·2порядок−127

Пример 3. Представление числа в формате IEEE 754

Дано: представьте число 5,5 в формате IEEE 754 одинарной точности (обзорно, по шагам).

Решение. Переведём 5,5 в двоичную систему: целая часть 5=101₂, дробная часть 0,5=0,1₂ (так как 0,5=2⁻¹), итого 5,5=101,1₂. Нормализуем запись, сдвинув точку так, чтобы перед ней осталась одна значащая единица: 101,1₂=1,011₂·2². Знак положительный, s=0. Порядок со смещением: 2+127=129=10000001₂. Мантисса — дробная часть после нормализованной единицы, дополненная нулями до 23 бит: 01100000000000000000000.

Ответ: 5,5 в формате IEEE 754 (32 бита) записывается как 0 10000001 01100000000000000000000 (знак — порядок — мантисса).

Программная иллюстрация

Рассмотрим программу на Python, которая вычисляет n-битный дополнительный код целого числа и получает битовое представление вещественного числа в формате IEEE 754 одинарной точности с помощью модуля struct.

import struct

def twos_complement(x, bits=8):

"""Возвращает n-битный дополнительный код числа x (строкой из 0 и 1)."""

return format(x & ((1 << bits) — 1), f'0{bits}b')

print(twos_complement(-5, 8)) # 11111011

print(twos_complement(5 + (-3), 8)) # 00000010 (после отбрасывания переноса)

def float_to_ieee754_bits(x):

"""Возвращает 32-битную строку — представление x в формате IEEE 754."""

packed = struct.pack('>f', x)

return ''.join(f'{byte:08b}' for byte in packed)

print(float_to_ieee754_bits(5.5))

Функция twos_complement использует побитовую операцию И с маской (1<<bits)−1, чтобы оставить только младшие bits разрядов результата — это программный эквивалент отбрасывания «лишнего» переноса из примера 2. Функция float_to_ieee754_bits упаковывает вещественное число в 4 байта по стандарту IEEE 754 (символ '>f' означает big-endian, float одинарной точности) и переводит каждый байт в двоичную строку — результат должен совпасть с ответом примера 3.

Типичные ошибки

Частая ошибка — путать прямой, обратный и дополнительный коды и, например, записывать отрицательное число в прямом коде там, где по условию задачи требуется дополнительный. Вторая ошибка — забывать про смещение (127 для одинарной точности) при вычислении порядка числа в формате IEEE 754: порядок хранится не как есть, а увеличенным на смещение, чтобы избежать отдельного кодирования его знака. Третья ошибка — заявлять, что диапазон n-битных чисел со знаком симметричен относительно нуля: на самом деле отрицательных значений на единицу больше положительных (диапазон от −2^(n−1) до 2^(n−1)−1), потому что ноль «занимает» одно из неотрицательных значений.

Краткий словарь терминов

Прямой код — представление числа со знаком, в котором старший бит хранит знак, а остальные биты — абсолютную величину числа.

Обратный код — представление отрицательного числа, получаемое инвертированием всех битов (кроме знакового) его прямого кода.

Дополнительный код — представление отрицательного числа, получаемое прибавлением 1 к обратному коду; используется для сведения вычитания к сложению.

Мантисса — значащие цифры числа с плавающей точкой, определяющие его точность.

Порядок (экспонента) — степень основания системы счисления в представлении числа с плавающей точкой, определяющая его масштаб.

IEEE 754 — международный стандарт представления чисел с плавающей точкой в памяти компьютера.

Заключение

Представление чисел в памяти компьютера подчинено строгим двоичным форматам: целые числа со знаком практически всегда хранятся в дополнительном коде, сводящем вычитание к сложению, а вещественные числа — в формате с плавающей точкой (стандарт IEEE 754), где мантисса отвечает за точность, а порядок — за диапазон представимых величин. Понимание этих форматов объясняет, почему компьютерная арифметика имеет свои особенности и ограничения — фиксированный диапазон целых чисел и ограниченную точность вещественных. В следующей теме мы перейдём от представления чисел к формальному аппарату алгебры логики, лежащему в основе работы самих вычислительных устройств.

Запишитесь на бесплатный урок

Определим уровень, покажем формат занятий и составим план подготовки.