LogicGates.org Open the simulatorSimulator

int32: the 32-bit signed integer

int32 holds every whole number from −2,147,483,648 to 2,147,483,647, which is −2³¹ to 2³¹ − 1. That is 2³² = 4,294,967,296 values in 32 bits, stored in two’s complement.

int32 limits

Maximum
2,147,483,647
power2³¹ − 1
hex0x7FFFFFFF
binary0111 1111 1111 1111 1111 1111 1111 1111
Minimum
−2,147,483,648
power−2³¹
hex0x80000000
binary1000 0000 0000 0000 0000 0000 0000 0000
Distinct values
2³² = 4,294,967,296
Size
32 bits, 4 bytes

The hex and binary forms are the bit patterns. The top bit is the sign: 0 for the maximum, 1 for the minimum.

int32 overflow playground

Starts at the maximum, one step from overflowing. Change the operation, the value or the type, or cast to another width, and watch the bits wrap.

Decimal, 0x hex or 0b binary, with a minus sign if negative. 2^31 − 1 works too.

int32: 2,147,483,647 +1 −2,147,483,648 Overflow: wrapped past the maximum to the bottom of the range
Before 0x7FFFFFFF
Exact answer 2,147,483,648 written in 33 bits: the leftmost bit does not fit and is dropped
After 0x80000000

The solid underlined bit is the sign bit: 1 means negative in a signed type. Struck-through bits are dropped.

  1. Exact answer: 2,147,483,648.
  2. That is above the maximum of int32, 2,147,483,647.
  3. The hardware keeps only the low 32 bits, which is the same as taking the answer modulo 2³² = 4,294,967,296: 2,147,483,648.
  4. The top bit is 1, so read as signed it is 2,147,483,648 − 4,294,967,296 = −2,147,483,648.

What int32 is called in each language

Language Type Limits in code Note
C and C++ int32_t INT32_MIN, INT32_MAX int is 32 bits on common desktop and phone platforms, but the standard only promises 16.
Java int Integer.MIN_VALUE, Integer.MAX_VALUE
C# int int.MinValue, int.MaxValue
Rust i32 i32::MIN, i32::MAX
Go int32 (alias rune) math.MinInt32, math.MaxInt32
Swift Int32 Int32.min, Int32.max
Kotlin Int Int.MIN_VALUE, Int.MAX_VALUE
MySQL INT (or INTEGER)
PostgreSQL integer (int4)
SQL Server int
JavaScript Int32Array element The bitwise operators (|, &, ^, <<, >>) work on 32-bit signed integers.
Python ctypes.c_int32

Only names with exactly 32 bits on every platform are listed as the type. C’s int, whose width depends on the platform, is in the notes.

What happens when int32 overflows

In 32 bits, 2,147,483,647 + 1 wraps to −2,147,483,648, and −2,147,483,648 − 1 wraps to 2,147,483,647. The processor keeps the low 32 bits of the answer, which is the same as working modulo 2³², and the top bit then decides the sign. You can see it in JavaScript:

(2147483647 + 1) | 0 → -2147483648

Whether a program is allowed to wrap like that depends on the language:

What each language does when integer arithmetic overflows
Language By default To check or wrap on purpose
C and C++ Unsigned types wrap around modulo 2ⁿ. Signed overflow is undefined behaviour: the compiler may assume it never happens and optimise on that basis. Types narrower than int are promoted to int first, so even uint16_t × uint16_t can overflow a signed int. __builtin_add_overflow (GCC, Clang); ckd_add in C23’s <stdckdint.h>; -fsanitize=undefined to catch it
Java Wraps around silently, in two’s complement. Math.addExact, multiplyExact and friends throw ArithmeticException
C# Wraps around, unless the code is in a checked context, which throws OverflowException. A constant expression that overflows is a compile error. checked(...) blocks, or the CheckForOverflowUnderflow compiler option
Rust Panics in debug builds. Release builds wrap, unless overflow-checks is turned on for that profile. checked_add, wrapping_add, saturating_add, overflowing_add
Go Wraps around silently. Only constant expressions that overflow are compile errors. math/bits.Add64 reports the carry; Mul64 returns the high half of the product
Swift Traps: the program stops with a runtime error. &+, &-, &* wrap on purpose; addingReportingOverflow reports it
Kotlin Wraps around silently, like Java. Math.addExact on the JVM
JavaScript Numbers never wrap, but lose precision past 2⁵³. Bitwise operators and typed arrays wrap to their width. BigInt never overflows. Number.isSafeInteger; BigInt.asIntN and asUintN to wrap deliberately
Python int never overflows: it grows as needed. ctypes and NumPy fixed-width types do wrap
SQL An error: the statement fails with an out of range or arithmetic overflow message. MySQL outside strict mode clips an out-of-range value stored into a column to the limit, with a warning

Common mistakes with int32

  • Negating −2,147,483,648 or taking its absolute value. The exact answer, 2,147,483,648, is one past the maximum of 2,147,483,647, so once it is stored as int32 it wraps back to −2,147,483,648: −x and abs(x) of the minimum stay negative wherever the result wraps, and in C and C++ the overflow is undefined behaviour.
  • Finding a midpoint as (low + high) / 2. When low and high are both 1,073,741,824 or more, just over half the maximum, their sum overflows int32. low + (high − low) / 2 gives the same midpoint without the overflow.
  • Storing timestamps or growing IDs in 32 bits. A signed 32-bit count of seconds since 1970 runs out at 2038-01-19 03:14:07 UTC, and an auto-increment ID stops at 2,147,483,647. Use 64 bits for anything that keeps growing.

When int32 overflowed for real

The Year 2038 problem

Unix time counts seconds since 1970-01-01 00:00:00 UTC. In a signed 32-bit integer the last second it can hold is 2038-01-19 03:14:07 UTC; one second later it wraps to −2,147,483,648, which reads as 1901-12-13 20:45:52 UTC. Systems that still store time in 32 bits need to move to 64.

Boeing 787 generator control units

In 2015 the US Federal Aviation Administration ordered 787 operators to cycle power regularly, because a software counter in the generator control units overflowed after 248 days of continuous power and could shut down all AC power. 2³¹ hundredths of a second is 248.55 days, which is why it is widely taken to be a signed 32-bit count of centiseconds.

Gangnam Style on YouTube

In December 2014 YouTube said Psy’s Gangnam Style had been watched so many times, closing in on 2,147,483,647 views, the largest signed 32-bit integer, that it had upgraded the view counter to a 64-bit integer.

Where you meet int32

  • int in Java, C# and (on common platforms) C
  • Unix time in older systems
  • JavaScript bitwise operators

Need no negatives and twice the reach? The unsigned type of the same width is uint32, from 0 to 4,294,967,295.

Every integer type

Type Minimum Maximum
int8 −128 127
uint8 0 255
int16 −32,768 32,767
uint16 0 65,535
int32 this page −2,147,483,648 2,147,483,647
uint32 0 4,294,967,295
int64 −9,223,372,036,854,775,808 9,223,372,036,854,775,807
uint64 0 18,446,744,073,709,551,615
int128 −170,141,183,460,469,231,731,687,303,715,884,105,728 170,141,183,460,469,231,731,687,303,715,884,105,727
uint128 0 340,282,366,920,938,463,463,374,607,431,768,211,455

Questions

What is the maximum value of int32?

2,147,483,647, which is 2³¹ − 1 or 0x7FFFFFFF in hex. The minimum is −2,147,483,648 (−2³¹).

Why is the minimum of int32 one further from zero than the maximum?

32 bits make 2³² patterns. Two’s complement gives the half with the top bit set to the negatives, −2,147,483,648 to −1, and the other half to zero and the positives, 0 to 2,147,483,647. Zero takes one of the non-negative patterns, so there is one more negative number than positive. That is also why negating −2,147,483,648 overflows back to itself.

How many values can int32 hold?

2³² = 4,294,967,296 distinct values, from −2,147,483,648 to 2,147,483,647.

What happens when int32 overflows?

On the hardware the result keeps only its low 32 bits, so 2,147,483,647 + 1 becomes −2,147,483,648. Java, Kotlin, Go and C# (outside a checked context) do exactly that. In C and C++ signed overflow is undefined behaviour; Rust panics in debug builds and wraps in release builds; Swift stops with a runtime error.

What is int32 called in other languages?

C and C++: int32_t; Java: int; C#: int; Rust: i32; Go: int32 (alias rune); Swift: Int32; Kotlin: Int; Python: ctypes.c_int32. In SQL: INT (or INTEGER) in MySQL, integer (int4) in PostgreSQL, int in SQL Server.