← Назад к вопросам

Почему при размере в 32 бита в int нельзя записать значение 4 млрд?

2.0 Middle🔥 111 комментариев
#Docker, Kubernetes и DevOps

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему при размере в 32 бита в int нельзя записать значение 4 млрд?

Это отличный вопрос о том, как компьютеры хранят числа. Ответ кроется в знаке числа и способе представления целых чисел в памяти.

Размер типа int в Java

В Java int всегда занимает 32 бита (4 байта). Однако эти 32 бита нужно использовать не только для самого числа, но и для его знака (положительное или отрицательное).

Как работает представление со знаком

int в Java — это знаковый тип (signed). Один бит зарезервирован для обозначения знака числа:

  • Старший бит (MSB) = 0 → положительное число
  • Старший бит (MSB) = 1 → отрицательное число
32 бита: [знак][30 остальных битов для значения]
         ^^^^^^
         1 бит

Поэтому для хранения числового значения остаётся только 31 бит, а не 32.

Максимальное значение int

С 31 битом для значения максимальное число, которое можно представить:

2^31 - 1 = 2,147,483,647  (примерно 2.1 млрд)

Почему минус 1? Потому что ноль занимает одно значение.

public class IntegerRange {
    public static void main(String[] args) {
        System.out.println("Max int: " + Integer.MAX_VALUE);
        System.out.println("Min int: " + Integer.MIN_VALUE);
    }
}

Как видите, максимальное значение — 2,147,483,647, что меньше 4 млрд.

Двоичное представление (дополнительный код)

Ява использует двоичное дополнение (two's complement) для представления отрицательных чисел. Вот как это работает:

Положительное число 5:

32 бита: 00000000 00000000 00000000 00000101

Отрицательное число -5:

1. Берём положительное число: 00000000 00000000 00000000 00000101
2. Инвертируем все биты:      11111111 11111111 11111111 11111010
3. Добавляем 1:               11111111 11111111 11111111 11111011

Почему не использовать unsigned?

В Java нет встроенного unsigned int. Однако есть long:

public class UnsignedComparison {
    public static void main(String[] args) {
        // int: диапазон от -2,147,483,648 до 2,147,483,647
        int i = Integer.MAX_VALUE;  // 2,147,483,647
        
        // long: 64 бита, достаточно для 4 млрд
        long l = 4_000_000_000L;    // Требует L, чтобы быть long
        
        // Попытка записать 4 млрд в int вызовет переполнение
        int unsignedValue = (int) 4_000_000_000L;
        System.out.println(unsignedValue);  // -294967296
    }
}

Переполнение int

Попробуем записать 4 млрд в int:

public class IntegerOverflow {
    public static void main(String[] args) {
        int max = Integer.MAX_VALUE;      // 2,147,483,647
        int overflow = max + 1;            // Переполнение
        
        System.out.println("Max int: " + max);        // 2147483647
        System.out.println("After +1: " + overflow);   // -2147483648
        
        long value = 4_000_000_000L;
        int narrowed = (int) value;
        System.out.println("4 млрд как int: " + narrowed);  // -294967296
    }
}

При переполнении число просто обворачивается и становится отрицательным.

Решение: используйте long

Для чисел больше 2.1 млрд используйте long (64 бита):

public class LongExample {
    public static void main(String[] args) {
        // long: диапазон от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807
        long fourBillion = 4_000_000_000L;
        long maxLong = Long.MAX_VALUE;
        
        System.out.println("4 млрд: " + fourBillion);
        System.out.println("Max long: " + maxLong);
        
        // Для ещё больших чисел используйте BigInteger
        BigInteger huge = new BigInteger("999999999999999999999");
        System.out.println("Huge number: " + huge);
    }
}

Практический пример: работа с большими числами

public class ResourceCounter {
    private long totalViews;      // Может быть больше 2 млрд
    private long totalRevenue;    // В копейках
    private int activeUsers;      // Обычно меньше 2 млрд
    
    public void recordView() {
        totalViews++;
        // 4 млрд просмотров без проблем благодаря long
    }
}

Ключевые моменты

  • int в Java = 32 бита, но 1 бит для знака, остаётся 31 для значения
  • Максимум int = 2^31 - 1 = 2,147,483,647 (≈2.1 млрд)
  • 4 млрд больше 2.1 млрд, поэтому не влезает в int
  • Решение: используйте long для больших чисел
  • Переполнение: превышение максимума переворачивает число в минус

Этот принцип работает не только в Java, но и во всех языках с 32-битными целыми числами со знаком.

Почему при размере в 32 бита в int нельзя записать значение 4 млрд? | PrepBro