Computers are finite machines trying to represent an infinite math universe. They cheat.
The Integer Ring (Overflow)
In math, number lines go on forever. In C int, the number line is a circle.
A 32-bit signed integer has a limit: TMax ( billion).
What happens at TMax + 1?
It doesn’t crash. It doesn’t stop. It wraps around the circle to TMin ( billion).
Visualizing Two’s Complement: The Clock Imagine a clock face with 16 ticks (for 4 bits).
0000is at 12 o’clock.- Count clockwise for positive numbers:
0001(1),0010(2)… up to0111(7). - Count counter-clockwise for negative numbers:
1111(-1),1110(-2)… down to1000(-8). The “Cliff” is at the bottom (6 o’clock), between 7 and -8.
Quick Negation Trick (-x)
To find the negative of any number:
- Flip all bits.
- Add 1.
Example:
5is0101. Flip1010. Add 11011(-5).
The “Unsigned” Cast Trap
Comparing signed and unsigned numbers is dangerous. C implicitly promotes the signed number to unsigned for the comparison.
int x = -1;
unsigned int y = 1;
if (x < y) {
// Logic says -1 < 1.
// C says FALSE!
}Why?
-1 in bits is 1111...1111.
Cast to unsigned, that is UMax (4 billion).
Is 4 billion < 1? No.
Floating Point: IEEE 754
If integers are circles, floating-point numbers are scientific notation in binary. Value .
Mental Model: The Variable Grid
Integers are evenly spaced (1, 2, 3…). Floats have variable density.
- Near Zero: Extremely precise (tiny gaps).
- Near Infinity: Extremely sparse (massive gaps).
At large values (), the gap between one representable float and the next might be larger than 1.0. This means x + 1.0 might essentially do nothing because the result falls into the gap and rounds back to x.
Why 0.1 + 0.2 != 0.3?
In decimal, 1/3 is infinite ().
In binary, 1/10 (0.1) is also infinite ().
The computer chops off the tail to fit in 64 bits. Small errors accumulate.
Rule: NEVER check if (f == 0.3). Check if (abs(f - 0.3) < epsilon).
Type Casting hierarchy
When you mix types, C usually promotes “Upwards” to preserve data.
-
Bit Size: Small Large (Safe).
charshortintlong.- Sign Extension: When expanding signed types, the sign bit is copied to fill the new upper bits. (
1110(-2)1111 1110(-2)). - Zero Extension: When expanding unsigned types, zeros are filled.
-
Type: Int Float.
inttofloat: Possible precision loss (int has 32 bits precision, float has 23).inttodouble: Exact (double has 53 bits precision).
-
The Drop: Large Small (Unsafe).
intchar. The top bits are purely truncated. The value changes completely (modulo 256).
Practice: Predict the Output
Q1: int x = TMax; x += 1; printf("%d", x < 0);
A: 1 (True). Overflow wraps to TMin (negative).
Q2: (float)1e20 + 3.14 - 1e20
A: 0.0. The addition 1e20 + 3.14 swallows the small number due to precision gaps. The result is just 1e20. Then we subtract 1e20 and get 0.
Q3: (int) -1.9
A: -1. Casting float to int truncates towards zero. It does not round to -2.