liveBook · Manning

Stopping criterion

As explained in Modern C, Third Edition

A condition is an expression whose evaluated value controls conditional or iterative execution in C.

Consider `for (size_t i = 0; i < 5; ++i) { /* work */ }`. The condition `i < 5` is checked before each execution of the body. Starting at zero and incrementing after each iteration, `i` takes the values 0 through 4; the loop stops when the condition is false. A stopping criterion may therefore be written as a condition for *continuing*: here, stop when `i` is no longer less than 5. section 2.4.1

C evaluates a numerical condition as false when its value is zero and true when it is nonzero. Thus `for (size_t i = 10; i; --i)` stops when `i` reaches zero; it needs no explicit `i != 0`. An `if` condition uses the same truth rule, but selects whether a block runs once rather than whether iteration continues. section 3.1 section 3.2

TAKEAWAY: place the test where it matches the work being controlled.

  • Use `for` for iteration over a domain: initialize once, test before each body execution, then update after each iteration. Define the iteration variable in the loop’s initial part. section 2.4.1
  • Use `while` when the continuation test belongs before the body; use `do ... while` when it belongs after the body. The latter executes its body before its first test. section 3.2
  • When the stopping test is best made inside the body, test it with `if` and leave with `break`. An unconditional `while (true)` or `for (;;)` needs such an exit in the shown approximation examples. section 3.2
  • Check a recursive function’s termination condition first. Without that check, repeated calls can exhaust system resources. section 7.3

Stop when an approximation is close enough

For an approximation `x` to `1/a`, `fabs(1.0 - a*x) < ε` tests whether the product is close enough to 1. A `while` loop can continue while the error is at least `ε`; alternatively, an `if` inside the loop can `break` when the error is below `ε`. The update must make progress toward the chosen threshold for either form to terminate. section 3.2

while (true) {
  double prod = a*x;
  if (fabs(1.0 - prod) < ε) {       // Stops if close enough
    break;
  }
  x *= (2.0 - prod);                // Heron approximation
}

The precision test is inside an otherwise unconditional loop, so `break` supplies its exit. section 3.2

A wait on a condition variable is different from a successful condition test: the wait can return even though the expression governing the work has not changed. Put the wait inside a loop that rechecks that expression, including any finished-state test. TAKEAWAY: waking up is not, by itself, a stopping criterion. section 20.5

How Modern C, Third Edition covers it

How deep it goes
Works through loop test placement, internal breaks, recursive termination, and condition-variable rechecks without deriving when an approximation converges.
Examples
Uses bounded and countdown loops, a precision-limited inverse approximation, and a recursive greatest-common-divisor function.
What it assumes
Builds on variables and comparisons while defining how zero and nonzero values control execution.
What you can do after
Build it from scratch: choose and place a loop or recursive exit test, then recheck a thread’s condition after waiting.
How it connects
Links numerical truth values with for and while loops, break, recursion, and condition variables.

Also explained in

Compare how 11 books explain stopping criterion →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.