Программирование

Как определить код целых чисел в памяти компьютера

Проверка, в каком коде (прямой, обратный или дополнительный) хранятся целые числа в памяти компьютера. Примеры на C/Python и доказательство, что -2 = 11111110.

Как определить, в каком коде (прямом, дополнительном или обратном) хранятся целые числа в памяти компьютера? Как с помощью программы доказать, что отрицательное число типа int, равное -2, представлено в двоичном виде как 11111110?

Как определить код целых чисел в памяти компьютера: можно программно сравнить побитовое представление отрицательных чисел с эталонами для прямого, обратного и дополнительного кодов — например, если представление -1 равно набору единиц, это дополнительный код. Чтобы доказать, что int со значением -2 равен 11111110, выведите младший байт или используйте 8‑битный тип (int8_t) и распечатайте двоичные биты (пример кода ниже).


Содержание


Как определить код целых чисел в памяти компьютера

Коротко: сравните побитовые представления знакомых значений и их отрицаний. Почему это работает? Потому что разные схемы представления имеют разные побитовые правила для оператора унарного минуса.

Практический принцип:

  • в дополнительном коде (two’s complement) выполняется правило -x == ~x + 1;
  • в обратном коде (one’s complement) — -x == ~x;
  • в прямом коде (sign‑magnitude) знак хранится отдельно, и отрицание не сводится к простому побитовому инвертированию/прибавлению.

Проверка на примере a = 1:

  • вычисляем b = -a;
  • смотрим на (unsigned)a, (unsigned)b и (unsigned)~a;
  • если (unsigned)b == (unsigned)~a → обратный код;
  • если (unsigned)b == (unsigned)~a + 1 → дополнительный код;
  • иначе — прямой код.

Эта идея и формулы описаны в учебных заметках и статьях о дополнительном коде и способах представления целых чисел (см. Cornell — two’s complement и GeeksforGeeks — representation of integers).


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

Кратко про три схемы (на примере 8‑бит):

  • Прямой код (sign‑magnitude, «прямой»): старший бит — знак (0 = +, 1 = −), остальные биты — модуль числа.
    Пример: +5 = 00000101, −5 = 10000101. Плюс: простая идея; минус: два нуля (+0 и −0).

  • Обратный код (one’s complement, «обратный»): отрицательное число — побитовое отрицание положительного.
    Пример: +5 = 00000101, −5 = 11111010. Минус: тоже два нуля (−0 = все единицы).

  • Дополнительный код (two’s complement, «дополнительный»): отрицание = побитовое отрицание плюс 1.
    Пример: +5 = 00000101, −5 = 11111011 (инвертируем и прибавляем 1). В дополнительном коде только один ноль, арифметика проще. Об этой схеме подробно — в Cornell и на StackOverflow.

Отсюда видно, почему для -2 в дополнительном коде 8‑бит: +2 = 00000010 → инверсия 11111101 → +1 → 11111110.


Как определить код целых чисел программно (тест на системе)

Ниже — минимальная C‑программа, которая различает схемы по описанному тесту. Компилируется под gcc/clang.

c
// detect_repr.c
#include <stdio.h>

int main(void) {
 int a = 1;
 int b = -a;
 unsigned ua = (unsigned)a;
 unsigned ub = (unsigned)b;
 unsigned ucomp = (unsigned)~a;

 if (ub == ucomp) {
 printf("Обнаружен обратный код (one's complement)\n");
 } else if (ub == ucomp + 1u) {
 printf("Обнаружен дополнительный код (two's complement)\n");
 } else {
 printf("Возможно прямой код (sign-magnitude)\n");
 }
 return 0;
}

Пояснения:

  • Мы сравниваем беззнаковые представления, чтобы смотреть именно на биты, а не на математическое значение.
  • Стандарт C не жестко предписывает конкретную битовую организацию знаковых чисел, но на практике почти все современные машины используют дополнительный код (см. GeeksforGeeks и обсуждение на StackOverflow).

Выполните:

  • gcc -std=c11 detect_repr.c && ./a.out
    Ожидаемый результат (на современной машине): “Обнаружен дополнительный код (two’s complement)”.

Доказательство для -2: пример на C и Python

Ниже — несколько простых примеров, которые на вашей машине выведут 11111110 как 8‑битное представление −2.

Пример на C (используем 8‑битный тип int8_t):

c
// show_minus2_int8.c
#include <stdio.h>
#include <stdint.h>

void print_bits_uint8(uint8_t v) {
 for (int i = 7; i >= 0; --i)
 putchar((v >> i) & 1 ? '1' : '0');
 putchar('\n');
}

int main(void) {
 int8_t x = -2;
 print_bits_uint8((uint8_t)x); // выведет: 11111110
 return 0;
}

Команда:

  • gcc -std=c11 show_minus2_int8.c && ./a.out
    Вывод: 11111110

Если вы хотите показать полный 32‑битный int (на обычной системе int = 32 бита):

c
// show_minus2_int32.c
#include <stdio.h>
#include <stdint.h>

void print_bits_u32(uint32_t v) {
 for (int i = 31; i >= 0; --i) {
 putchar((v >> i) & 1 ? '1' : '0');
 if (i % 8 == 0 && i != 0) putchar(' ');
 }
 putchar('\n');
}

int main(void) {
 int x = -2;
 print_bits_u32((uint32_t)x); // обычно: 11111111 11111111 11111111 11111110
 return 0;
}

Пример в Python — самый короткий:

python
x = -2
print(format(x & 0xFF, '08b')) # 11111110 (младший байт)
print(format(x & 0xFFFFFFFF, '032b'))# полный 32-битный вид: 1111...1110

Объяснение: операция & с маской 0xFF/0xFFFFFFFF берёт представление числа как беззнаковое значение нужной ширины — то есть фактически показывает младшие 8 или 32 бита. При дополнительном коде младшие 8 бит для −2 равны 11111110.

Если вы хотите увидеть «почему» математически: +2 = 00000010; инверсия → 11111101; прибавляем 1 → 11111110. Это правило дополнительного кода (см. Cornell и TutorialsPoint).


Источники


Заключение

Как определить код целых чисел в памяти компьютера — можно просто и надёжно: программно вывести побитовое представление пары значений (например, 1 и −1) и сравнить с правилами для прямого/обратного/дополнительного кода; практически везде вы увидите дополнительный код. Чтобы «показать» для −2 именно 11111110, используйте 8‑битный тип (int8_t) или маску &0xFF и выведите биты — приведённые примеры на C и Python делают это за одну команду.

Авторы
Проверено модерацией
Модерация
Как определить код целых чисел в памяти компьютера