Представь: ты пишешь код для игрового движка, всё работает идеально, а потом бац — персонаж телепортируется в минус бесконечность, очки игрока обнуляются на 1000-м уровне, а счётчик патронов превращается в -32768. Знакомо?
Дело не в багах. Дело в том, что компьютер считает совсем не так, как ты думаешь. И если не понять эту базу — будешь писать код на удачу. А мы сейчас вскроем эту тему так, что ты увидишь матрицу 💊
Компьютер говорит только на языке нулей и единиц (и это не метафора)
Забудь про привычные цифры 0-9. В памяти компьютера существуют только два состояния:
• 0 — выключен
• 1 — включен
Каждая ячейка памяти — это 8 битов (байт). Восемь переключателей, которые могут быть либо вкл, либо выкл. Вот и всё оборудование.
Как из этого получить число 255? Просто включи все восемь:
11111111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255
А как записать 25?
00011001 = 16 + 8 + 1 = 25
Видишь закономерность? Каждая позиция — это степень двойки. Двоичная система — это не про математику из учебника, это буквально то, как работает железо.
«255 + 1 = 0». WTF? 🚨
Окей, у тебя есть 8 бит. Максимум, что в них влезает — число 255 (все биты включены).
А теперь попробуй добавить единицу:
unsigned char x = 255; // 11111111
x = x + 1; // ???
Что произойдёт?
Все биты обнуляются, а девятый бит (которого нет) попытается включиться. Но его же нет! В итоге получаешь... ноль.
255 + 1 = 0
Это называется переполнением. И это не баг — это фича 😏
Именно так работают таймеры, счётчики кадров, генераторы случайных чисел. И если не понимать этого — получишь неожиданные глюки.
Обратная история: 0 - 1 = 255. Компьютер просто «прокрутит» все биты назад.
Отрицательные числа: самый гениальный хак в истории IT 🧠
Ладно, с положительными разобрались. А как записать -1?
Программисты решили отдать старший бит под знак:
• Если старший бит = 0, число положительное
• Если старший бит = 1, число отрицательное
Так появился <b>знаковый тип</b>.
Теперь в 8 битах можно хранить от -128 до +127:
01111111 = +127 (старший бит 0 = плюс)
10000000 = -128 (старший бит 1 = минус)
А -1? Это вообще красота:
11111111 = -1
Почему? Потому что если от нуля (00000000) отнять единицу — получишь все единицы. Компьютер просто считает в обратную сторону. Это называется дополнительный код, и это одна из самых элегантных идей в программировании.
Типы данных: сколько памяти — столько и музыки 🎸
Окей, 8 бит — это мало. Что если нужны большие числа?
Просто бери больше байт:
• 1 байт (char): от -128 до +127
• 2 байта (short): от -32 768 до +32 767
• 4 байта (int): от -2 млрд до +2 млрд
• 8 байт (long long): вообще космос (±9 квинтиллионов)
Хочешь только положительные? Используй unsigned — удвоишь диапазон:
unsigned char = 0...255
unsigned int = 0...4 млрд
Правило №1: Выбирай тип по задаче. Счётчик кадров в игре? int хватит. Таймер на миллисекунды? Возьми long long, чтобы не словить переполнение.
Шестнадцатеричная система: язык хакеров и системных программистов 💻
Представь, что пишешь код для шифрования в мессенджере или разрабатываешь движок. Двоичная система — слишком длинная, десятичная — неудобная.
Решение? Шестнадцатеричная система (hex).
В ней 16 цифр: 0-9 и A-F (где A=10, B=11... F=15).
Фишка в том, что 4 бита = 1 hex-цифра:
1010 1111 (двоичное) = AF (hex) = 175 (десятичное)
Опытные программисты читают hex как текст. Видят 0xFF — сразу понимают, что это 255. Видят 0x1A2B — моментально представляют биты.
В коде это выглядит так:
int color = 0xFF5733; // цвет в RGB (красный-оранжевый)
int mask = 0x0F; // битовая маска для младших 4 бит
Hex везде: цвета в вебе (#FF5733), адреса памяти, дампы данных, криптография.
Восьмеричная система: привет из прошлого (но всё ещё живая) 👴
Есть ещё восьмеричная система (0-7). Её почти вытеснил hex, но она до сих пор используется в Unix для прав доступа к файлам:
chmod 755 file.txt
Каждая цифра — это 3 бита:
7 = 111 = rwx (чтение, запись, выполнение)
5 = 101 = r-x (чтение, выполнение)
В C восьмеричные числа начинаются с нуля:
int x = 0755; // это 493 в десятичной
⚠️ Ловушка: не пиши int x = 010; думая, что это десятка. Это восемь.
А какая разница, если компилятор всё равно переводит в двоичное? 🤔
Хороший вопрос. Производительность одинаковая — компилятор всё превращает в нули и единицы.
Но код — это для людей. Используй ту систему, которая понятнее для задачи:
✅ Работаешь с адресами памяти? → hex
✅ Настраиваешь права в Unix? → восьмеричная
✅ Обычные вычисления? → десятичная
И ещё: целые числа считаются быстрее, чем дробные (float, double). Если можешь обойтись int — обходись.
// Медленно (без причины)
double counter = 0.0;
// Быстро
int counter = 0;
Что ты теперь знаешь (и почему это круто) 🚀
Ты только что заглянул под капот всей вычислительной техники. Теперь понимаешь:
💡 Почему числа иногда «переполняются» и ведут себя странно
💡 Как работают отрицательные числа и почему это элегантно
💡 Откуда берутся лимиты типов данных (-128, 255, 2 млрд...)
💡 Зачем программисты пишут 0xFF вместо 255
💡 Почему целые числа — твой выбор по умолчанию
Это не просто теория. Это база, на которой строятся игровые движки, алгоритмы шифрования, операционные системы и всё, что работает в твоём телефоне прямо сейчас.
Теперь, когда увидишь баг с переполнением — не будешь в ступоре. Поймёшь, что происходит на уровне битов. И это уже не магия, а твой инструмент.
💡 Хочешь копнуть глубже? Полный учебный материал с детальными примерами, схемами и крутыми иллюстрациями ждёт тебя на нашем сайте!