Section 01 · Definition
What is int in Solidity?
An int variable holds a whole number that can be negative as well as positive. It is the second-most-common number type after uint.
Quick answer
What is int? int is short for 'signed integer'. It stores a whole number that uses one bit to record the sign, leaving the remaining bits for magnitude. The default size is int256, which can hold values from approximately negative 5.7 × 10⁷⁶ to positive 5.7 × 10⁷⁶.
The simplest way to picture the difference between uint and int is the number line. uint covers the right half, from zero out to a very large positive. int covers both halves, from a very large negative through zero to a very large positive — but each half is half the size of the corresponding uint.
int256 public pnl; // can be -100 or +250
int128 public delta; // signed shift in some quantity
int64 public timezoneOffset; // -43 200 to +50 400 seconds
int8 public score; // -128 to 127Section 02 · Overflow
Signed overflow is sneakier than unsigned overflow
The compiler checks both directions, but the wraparound point sits in the middle of the range — not at zero — and that surprises people.
Visualise the signed range as a circle, not a line. The maximum (int8 = 127) sits next to the minimum (int8 = -128). One step over the top wraps you straight to the floor. Solidity 0.8 catches this and reverts.
int256 a = type(int256).max;
a + 1; // overflow → revert in Solidity 0.8+
int256 b = type(int256).min;
b - 1; // underflow → revert
// The asymmetric case: -min cannot be represented as +int256
// because there is no +max equivalent. This also reverts.
int256 c = type(int256).min;
-c; // overflow → revertThe classic asymmetric trap
There are 2^256 unsigned values but only 2^256 - 1 distinct positive int256 values, because zero counts in the negative side. Negating int256.min would need a value larger than int256.max, which does not exist. Solidity 0.8 reverts on this; older code used to silently keep the same negative number, which broke many financial calculations.
Section 03 · Real-world uses
When you actually need a signed integer
Most Solidity contracts get away without int, but a few specific shapes need it. Knowing them keeps you from forcing a sign onto uint with hacky encoding.
// 1. Profit and loss tracking
mapping(address => int256) public realisedPnl;
// 2. Voting deltas where downvotes subtract weight
mapping(uint256 => int256) public proposalScore;
// 3. Temperature or other physical sensors
int16 public sensorReadingC; // -32 768 to 32 767
// 4. Geo coordinates as fixed-point degrees * 1e6
int32 public latitudeMicrodegrees; // -90 000 000 to 90 000 000
int32 public longitudeMicrodegrees;
// 5. Index offsets that can move backwards
int256 public cursorDelta;Notice that none of these are token balances, NFT IDs, or amounts of ether. Those should stay uint. Reach for int only when zero is a meaningful midpoint and the value can move on either side of it.
Section 04 · Casting
Casting between int and uint
Mixing signed and unsigned types is one of the few places where Solidity makes you reach for an explicit cast. Doing it carelessly is a common bug.
uint256 u = 100;
int256 s = int256(u); // safe: u fits inside positive int256
int256 t = -42;
uint256 v = uint256(t); // dangerous: produces a huge positive number
// because the bit pattern is reinterpreted.
// Safer pattern
require(t >= 0, "negative");
uint256 safe = uint256(t);Cast deliberately. Read uint256(int256) as "reinterpret these 256 bits as if they were unsigned". If the original int was negative, the unsigned interpretation is enormous and almost never what you wanted. Always require non-negativity first.