Как определить код целых чисел в памяти компьютера
Проверка, в каком коде (прямой, обратный или дополнительный) хранятся целые числа в памяти компьютера. Примеры на C/Python и доказательство, что -2 = 11111110.
Как определить, в каком коде (прямом, дополнительном или обратном) хранятся целые числа в памяти компьютера? Как с помощью программы доказать, что отрицательное число типа int, равное -2, представлено в двоичном виде как 11111110?
Как определить код целых чисел в памяти компьютера: можно программно сравнить побитовое представление отрицательных чисел с эталонами для прямого, обратного и дополнительного кодов — например, если представление -1 равно набору единиц, это дополнительный код. Чтобы доказать, что int со значением -2 равен 11111110, выведите младший байт или используйте 8‑битный тип (int8_t) и распечатайте двоичные биты (пример кода ниже).
Содержание
- Как определить код целых чисел в памяти компьютера
- Представления отрицательных чисел: прямой, обратный и дополнительный коды
- Как определить код целых чисел программно (тест на системе)
- Доказательство для -2: пример на C и Python
- Источники
- Заключение
Как определить код целых чисел в памяти компьютера
Коротко: сравните побитовые представления знакомых значений и их отрицаний. Почему это работает? Потому что разные схемы представления имеют разные побитовые правила для оператора унарного минуса.
Практический принцип:
- в дополнительном коде (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.
// 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):
// 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 бита):
// 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 — самый короткий:
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).
Источники
- How are negative numbers stored in computers? — StackOverflow
- Integer Representation (Two’s Complement) — Cornell
- Representation of Integers — GeeksforGeeks
- Representing numbers — Khan Academy
- How do Computers Represent Negative Numbers? Two’s Complement — YouTube
- Computer Number System — Tutorialspoint
Заключение
Как определить код целых чисел в памяти компьютера — можно просто и надёжно: программно вывести побитовое представление пары значений (например, 1 и −1) и сравнить с правилами для прямого/обратного/дополнительного кода; практически везде вы увидите дополнительный код. Чтобы «показать» для −2 именно 11111110, используйте 8‑битный тип (int8_t) или маску &0xFF и выведите биты — приведённые примеры на C и Python делают это за одну команду.