LogicGates.org Open the simulatorSimulator

int128: the 128-bit signed integer

int128 holds every whole number from −2¹²⁷ to 2¹²⁷ − 1, about ±1.70 × 10³⁸, stored in two’s complement. The exact limits, all 39 digits, are below.

int128 limits

Maximum
170,141,183,460,469,231,731,687,303,715,884,105,727
power2¹²⁷ − 1
hex0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
binary0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
Minimum
−170,141,183,460,469,231,731,687,303,715,884,105,728
power−2¹²⁷
hex0x80000000000000000000000000000000
binary1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Distinct values
2¹²⁸ = 340,282,366,920,938,463,463,374,607,431,768,211,456
Size
128 bits, 16 bytes

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

int128 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.

int128: 170,141,183,460,469,231,731,687,303,715,884,105,727 +1 −170,141,183,460,469,231,731,687,303,715,884,105,728 Overflow: wrapped past the maximum to the bottom of the range
Before 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Exact answer 170,141,183,460,469,231,731,687,303,715,884,105,728 written in 129 bits: the leftmost bit does not fit and is dropped
After 0x80000000000000000000000000000000

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

  1. Exact answer: 170,141,183,460,469,231,731,687,303,715,884,105,728.
  2. That is above the maximum of int128, 170,141,183,460,469,231,731,687,303,715,884,105,727.
  3. The hardware keeps only the low 128 bits, which is the same as taking the answer modulo 2¹²⁸ = 340,282,366,920,938,463,463,374,607,431,768,211,456: 170,141,183,460,469,231,731,687,303,715,884,105,728.
  4. The top bit is 1, so read as signed it is 170,141,183,460,469,231,731,687,303,715,884,105,728 − 340,282,366,920,938,463,463,374,607,431,768,211,456 = −170,141,183,460,469,231,731,687,303,715,884,105,728.

What int128 is called in each language

Language Type Limits in code Note
C and C++ __int128 Not standard: a GCC and Clang extension on 64-bit targets, with no limit macros.
Java none Use java.math.BigInteger.
C# Int128 Int128.MinValue, Int128.MaxValue .NET 7 and later.
Rust i128 i128::MIN, i128::MAX
Go none Use math/big.
Swift Int128 Int128.min, Int128.max Swift 6 and later.
Kotlin none Use java.math.BigInteger on the JVM.
MySQL none Use DECIMAL(39, 0) for whole numbers this big.
PostgreSQL none Use numeric.
SQL Server none Use decimal(38, 0), which stops one digit short of the full range.
JavaScript none BigInt has no fixed width; BigInt.asIntN(128, x) wraps a value into 128 bits.
Python none Python’s own int holds any size.

Only names with exactly 128 bits on every platform are listed as the type.

What happens when int128 overflows

In 128 bits, 170,141,183,460,469,231,731,687,303,715,884,105,727 + 1 wraps to −170,141,183,460,469,231,731,687,303,715,884,105,728, and −170,141,183,460,469,231,731,687,303,715,884,105,728 − 1 wraps to 170,141,183,460,469,231,731,687,303,715,884,105,727. The processor keeps the low 128 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:

BigInt.asIntN(128, 170141183460469231731687303715884105727n + 1n) → -170141183460469231731687303715884105728n

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 int128

  • Negating −170,141,183,460,469,231,731,687,303,715,884,105,728 or taking its absolute value. The exact answer, 170,141,183,460,469,231,731,687,303,715,884,105,728, is one past the maximum of 170,141,183,460,469,231,731,687,303,715,884,105,727, so once it is stored as int128 it wraps back to −170,141,183,460,469,231,731,687,303,715,884,105,728: −x and abs(x) of the minimum stay negative wherever the result wraps, and in C and C++ the overflow is undefined behaviour.
  • Expecting the usual tools to handle 128 bits. GCC and Clang have no literal for __int128 and printf has no format for it, so build values from two 64-bit halves and print them yourself. MySQL, PostgreSQL and SQL Server have no 128-bit integer column type either.

Where you meet int128

  • The full signed product of two 64-bit numbers
  • Sums of many 64-bit values that must not overflow

Need no negatives and twice the reach? The unsigned type of the same width is uint128, from 0 to 340,282,366,920,938,463,463,374,607,431,768,211,455.

Every integer type

Type Minimum Maximum
int8 −128 127
uint8 0 255
int16 −32,768 32,767
uint16 0 65,535
int32 −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 this page −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 int128?

170,141,183,460,469,231,731,687,303,715,884,105,727, which is 2¹²⁷ − 1 or 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF in hex. The minimum is −170,141,183,460,469,231,731,687,303,715,884,105,728 (−2¹²⁷).

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

128 bits make 2¹²⁸ patterns. Two’s complement gives the half with the top bit set to the negatives, −170,141,183,460,469,231,731,687,303,715,884,105,728 to −1, and the other half to zero and the positives, 0 to 170,141,183,460,469,231,731,687,303,715,884,105,727. Zero takes one of the non-negative patterns, so there is one more negative number than positive. That is also why negating −170,141,183,460,469,231,731,687,303,715,884,105,728 overflows back to itself.

How many values can int128 hold?

2¹²⁸ = 340,282,366,920,938,463,463,374,607,431,768,211,456 distinct values, from −170,141,183,460,469,231,731,687,303,715,884,105,728 to 170,141,183,460,469,231,731,687,303,715,884,105,727.

What happens when int128 overflows?

On the hardware the result keeps only its low 128 bits, so 170,141,183,460,469,231,731,687,303,715,884,105,727 + 1 becomes −170,141,183,460,469,231,731,687,303,715,884,105,728. C# (outside a checked context) does 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 int128 called in other languages?

C and C++: __int128; C#: Int128; Rust: i128; Swift: Int128. No common SQL database has it as a column type.