What does this integer puzzle print?
var x int8 = 127
x++
fmt.Println(x) // ?
var u uint8 = 0
u--
fmt.Println(u) // ?
m := int8(-128)
fmt.Println(-m) // ?
fmt.Println(-7/2, -7%2) // ?
// const big = 1 << 62
// fmt.Println(big * 4) // ?
Output: -128, 255, -128, -3 -1. The commented-out line is a compile error (cannot use big * 4 (untyped int constant 18446744073709551616) as int value in argument to fmt.Println (overflows)).
Explanation: at runtime, signed and unsigned integer arithmetic wraps using two's complement. There is no panic and no error. Negating the minimum value gives the minimum value back, so a naive abs is wrong for math.MinInt64. Integer division truncates toward zero, and % takes the sign of the dividend, so use ((a % n) + n) % n for a true modulo. Constants are arbitrary-precision and checked at compile time, so overflow shows up only when the constant is converted to a typed value.
A real bug: len(s)-1 with an unsigned index type when s is empty, or int32(bigInt64) silently truncating an ID. Check with math/bits.Add64 or with explicit bounds checks.
More on Tricky Output & Code-Review Puzzles
- Q503Does the recover in main protect this program?
- Q504A deferred function panics while another panic is in progress. What prints?
- Q506Why do these two floating-point comparisons give different results?
- Q507What does indexing and ranging over a UTF-8 string print?
- Q508This compiles. Why does it panic at runtime?
- Q509Why does errors.Is return different results here?