Go Integer Overflow in Coding Interviews: Pitfalls and Patterns
- Go integer overflow is silent: the value wraps around with no panic, no error, and no compiler warning — the compiler won't save you.
intis platform-dependent: 64-bit on LeetCode and most 64-bit systems, but 32-bit elsewhere. Useint64explicitly for accumulations and products.- Safe binary search midpoint:
(lo + hi) / 2overflows nearMaxInt64; always writelo + (hi - lo) / 2instead. - Type conversion always compiles:
int32(someInt64)silently drops the high bits with no error, no warning, and wrong output. - Unsigned subtraction wraps up:
uint(3) - uint(5)gives a massive positive number, not -2. Avoiduintarithmetic in interviews. - Apply mod after every multiplication, not at the end — intermediate values can overflow
int64before the final reduction. math.MaxInt64andmath.MinInt64are the idiomatic sentinel values for min/max tracking since Go 1.17.
Go is a popular interview language for backend and systems engineers. It has a clean standard library, fast compilation, and explicit types that make code readable. Go integer overflow is also silent: the value wraps with no error, the int type is platform-dependent, and explicit conversions can quietly truncate your data. None of this comes up in a basic Go tutorial. All of it shows up in coding interviews.
For a broader look at Go's standard library in interview contexts, see the Go for Coding Interviews reference. This guide focuses specifically on numeric safety.
Go Will Not Save You From Yourself
This is the most important thing to internalize before an interview. When a Go integer overflows, the value wraps around with no error, no panic, and no compiler warning. Nothing. Silence. Just a wrong number sitting quietly in your variable while you're busy explaining your approach.
var x int8 = 127 x++ fmt.Println(x) // -128
That -128 is intentional on Go's part. The language designers chose two's-complement wrapping behavior explicitly. There have been proposals to add overflow panics; they were rejected. The spec says integer overflow is defined behavior. So if your intermediate result blows past the type's range, you get garbage output. Your tests might still pass. Your hidden test cases will not.
This is different from how most interview candidates think about overflow. In Python, integers are arbitrary-precision and will grow until your RAM runs out. In Java, overflow wraps but at least you're dealing with a predictable 32-bit int. In Go, you have more rope. You know what rope is for.
The int Type Is Not int64. Sort Of.
Go's int type is platform-dependent: 32 bits on 32-bit systems, 64 bits on 64-bit systems. LeetCode runs on 64-bit, so int is 64 bits there, giving you the full ±9.2 × 10^18 range. Most competitive platforms do the same.
The trap is the assumption, not the range. If you write code treating int as always-64-bit, that code will silently fail when deployed to a 32-bit environment. For interview purposes this rarely matters, but if an interviewer asks about portability or you ever move this to production, the assumption breaks.
The cleaner habit: use int64 explicitly when you need 64-bit guarantees. Use int when you know you're within a safe range and want idiomatic Go.
The Ranges That Will Bite You
Go 1.17 added typed constants to the math package for this:
import "math" math.MaxInt8 // 127 math.MinInt8 // -128 math.MaxInt16 // 32767 math.MaxInt32 // 2147483647 math.MaxInt64 // 9223372036854775807 math.MaxInt // platform-dependent: MaxInt32 or MaxInt64 math.MinInt // platform-dependent: MinInt32 or MinInt64 math.MaxUint8 // 255 math.MaxUint16 // 65535 math.MaxUint32 // 4294967296 - 1 // math.MaxUint64 is a constant but cannot be assigned to int without overflow
A table worth memorizing:
| Type | Bits | Min | Max |
|---|---|---|---|
int32 | 32 | -2,147,483,648 | 2,147,483,647 |
int64 | 64 | -9.2 × 10^18 | 9.2 × 10^18 |
uint32 | 32 | 0 | 4,294,967,295 |
uint64 | 64 | 0 | 1.8 × 10^19 |
int32 caps at about 2.1 billion. Any product of two numbers that could each reach 100,000 will overflow it. That is a common input constraint in interview problems. The general principles behind these ranges are covered in int32 vs int64 if you want the full cross-language comparison.
The Four Overflow Traps That Actually Appear
Trap 1: Multiplying Medium-Sized Numbers
A problem gives you constraints of 1 <= n <= 10^5. You need n * n. That is 10^10, which exceeds int32's max of ~2.1 × 10^9. If your accumulator is int32, it silently wraps to some baffling negative number. No warning. Just vibes.
// Risky if n is int32 total := n * n // Safe total := int64(n) * int64(n)
The fix is two extra casts. The bug costs you a wrong-answer verdict and ten minutes of staring at code that looks completely correct.
Trap 2: The Binary Search Midpoint
This one is famous. If lo and hi are both near math.MaxInt64 / 2, their sum overflows before you divide. This bug was found in Java's standard library in 2006 by Joshua Bloch. It had been in production for nine years. It applies to Go just as much as any other language (see binary search off-by-one and overflow patterns).
// Overflows when lo + hi > MaxInt64 mid := (lo + hi) / 2 // Safe: hi - lo is always non-negative, so no overflow mid := lo + (hi - lo) / 2
The safe form costs you zero extra characters and signals to your interviewer that you've thought about this. Use it by default.
Trap 3: Unsigned Subtraction Underflow
If you use uint arithmetic and subtract a larger number from a smaller one, the result doesn't go negative. It wraps to a very large positive number.
var a, b uint = 3, 5 fmt.Println(a - b) // 18446744073709551614, not -2
Eighteen quintillion. Not minus two. Check the comparison before you subtract, or just use signed types throughout. Unsigned types are almost never necessary in interview problems, and this is why.
Trap 4: Type Conversion That Silently Drops Bits
Go requires explicit type conversion between numeric types. "Explicit" feels safe. It is not.
var big int64 = 3_000_000_000 small := int32(big) // -1294967296, not 3000000000 var f float64 = 3.99 i := int(f) // 3, not 4 (truncates toward zero)
int32(someInt64) never returns an error. It just narrows. The conversion compiles fine and runs fine and produces the wrong number with zero complaints. If you're passing a result into a function that takes int32, verify the value fits before you convert.
When int64 Is Not Enough
Three approaches, ordered by how often you'll actually reach for them.
Option 1: Use int64 from the start. The range is 9.2 × 10^18. This handles 99% of interview overflow problems without any extra code. Don't overthink it.
Option 2: Boundary check before the operation.
func addSafe(a, b int64) (int64, bool) { if b > 0 && a > math.MaxInt64-b { return 0, false // would overflow } if b < 0 && a < math.MinInt64-b { return 0, false // would underflow } return a + b, true }
You'll reach for this when a problem explicitly tests overflow behavior, not as a default.
Option 3: math/big when the problem genuinely requires it. Some problems deal with exact factorials or arbitrary-precision arithmetic that dwarfs int64.
import "math/big" a := new(big.Int).SetInt64(1_000_000_000_000) b := new(big.Int).SetInt64(1_000_000_000_000) product := new(big.Int).Mul(a, b) fmt.Println(product) // 1000000000000000000000000
big.Int is verbose. Most interview problems don't need it. If a problem asks for the answer modulo something (10^9 + 7 is the classic), apply the modulo at each step rather than accumulating a giant intermediate value.
Modular Arithmetic Done Right
Many counting and combinatorics problems ask for the answer modulo 10^9 + 7. The pattern in Go:
const mod = 1_000_000_007 func modMul(a, b int64) int64 { return (a % mod) * (b % mod) % mod } func modAdd(a, b int64) int64 { return (a + b) % mod }
Keep every intermediate value reduced mod mod after each step. Don't accumulate and reduce at the end. The intermediate can overflow even int64 if you multiply large values first.
One useful fact: (10^9 + 7)^2 is about 10^18, which is within int64 range. So one multiplication of two already-reduced values is safe before you reduce again. That's why (a % mod) * (b % mod) % mod works without overflowing.
The Right Way to Initialize Min and Max
The idiomatic Go initialization for tracking a running minimum or maximum:
minVal := math.MaxInt64 maxVal := math.MinInt64 for _, v := range nums { if v < minVal { minVal = v } if v > maxVal { maxVal = v } }
Before Go 1.17, engineers used 1<<63 - 1 as a literal. Now math.MaxInt64 and math.MinInt64 are the clean way to write it. If your code is using int rather than int64, use math.MaxInt and math.MinInt for portability.
The Cheatsheet
Print this out. Tape it to your monitor. Do whatever works.
import "math" // Type safety default var result int64 // use int64 for large accumulations // Safe midpoint (never use the other one) mid := lo + (hi - lo) / 2 // Sentinel values minSoFar := math.MaxInt64 maxSoFar := math.MinInt64 // Modular arithmetic const mod = 1_000_000_007 product := (a % mod) * (b % mod) % mod // Big integers when needed import "math/big" n := new(big.Int).SetInt64(someValue)
Say the Arithmetic Out Loud
Overflow bugs are invisible until they are not. The Go compiler will not warn you. Your test case might not hit the boundary. You'll get a wrong-answer verdict on a hidden test case and spend ten minutes re-reading your algorithm when the bug is in the math, not the logic.
The habit to build: every time you write a multiplication or an addition of potentially large values, pause and ask whether the result can exceed your type's range.
That pause is hard to build from LeetCode practice alone because the feedback loop is slow. Saying "and here I need int64 because n can be 10^5 and n * n would overflow int32" out loud to an interviewer, or to an AI mock interviewer like SpaceComplexity, makes the check happen in real time. You catch the bug before you write it.
What to Carry Into the Interview
- Go wraps silently on overflow. No panic, no error, no warning.
intis 64-bit on LeetCode but do not assume it elsewhere.- Use
int64as your default for accumulations and products. - Use
lo + (hi - lo) / 2for binary search midpoints. Always. - Never subtract unsigned integers without checking which is larger.
int32(someInt64)silently truncates. Explicit conversion does not mean safe conversion.- Apply mod at each multiplication step, not at the end.
- For numbers beyond
int64, reach formath/big.