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

  • 0000 is at 12 o’clock.
  • Count clockwise for positive numbers: 0001 (1), 0010 (2)… up to 0111 (7).
  • Count counter-clockwise for negative numbers: 1111 (-1), 1110 (-2)… down to 1000 (-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:

  1. Flip all bits.
  2. Add 1. Example: 5 is 0101. Flip 1010. Add 1 1011 (-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.

  1. Bit Size: Small Large (Safe).

    • char short int long.
    • 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.
  2. Type: Int Float.

    • int to float: Possible precision loss (int has 32 bits precision, float has 23).
    • int to double: Exact (double has 53 bits precision).
  3. The Drop: Large Small (Unsafe).

    • int char. 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.