Cyclomatic Complexity Calculator

Enter the number of branches, loops, switch cases, and logical/ternary operators in your code to get its cyclomatic complexity (V(G) = D + 1), minimum test paths, and risk rating.

Quick Facts

Graph formula
V(G) = E − N + 2P
E = edges, N = nodes, P = connected components in the control-flow graph (P = 1 for a single function).
Decision-point shortcut
V(G) = D + 1
D = total decision points: branches, loops, switch cases, catches, ternaries, and &&/|| operators.
Meaning
Minimum independent test paths
V(G) equals both the number of linearly independent paths and the minimum tests needed for full branch coverage.
Risk thresholds (McCabe, 1976)
1–10 simple · 11–20 moderate · 21–50 complex · 50+ untestable
Higher scores correlate with more defects and higher testing/maintenance cost.

Your Results

Calculated
Cyclomatic Complexity V(G)
-
V(G) = D + 1 decision points
Total Decision Points (D)
-
Branches + loops + cases + logical/ternary operators
Minimum Independent Test Paths
-
Equal to V(G); needed for full branch coverage
Risk / Complexity Rating
-
Based on standard McCabe thresholds

Ready

Enter your decision-point counts, then press Calculate.

How Cyclomatic Complexity Is Calculated

Cyclomatic complexity is a software metric introduced by Thomas McCabe in 1976 that measures the number of linearly independent paths through a program's source code, based on a graph-theory model of its control flow. Formally, McCabe defined it from the control-flow graph as V(G) = E − N + 2P, where E is the number of edges, N is the number of nodes, and P is the number of connected components (P = 1 for a single function or procedure with one entry and one exit). In practice, most developers use an equivalent shortcut that avoids drawing the graph: V(G) = D + 1, where D is the total number of decision points in the code. This calculator uses the decision-point method — enter how many branches, loops, switch cases, and logical/ternary operators your code contains, and it returns the cyclomatic complexity, the minimum number of independent test paths, and a standard risk rating.

The decision-point shortcut, step by step

Walk through the code and tally each construct that creates a new branch: an if or else if adds one path; a for, while, or do-while loop adds one (the loop-back edge); each case label in a switch or match statement adds one (the default/else branch is already covered by the baseline complexity of 1, so don't count it separately); a try/catch adds one per catch clause; and each ternary operator (?:) or short-circuit logical operator (&& or ||) adds one, because each one creates an extra branch in the compiled control flow even though it looks like part of a single line. Sum all of these counts to get D, then add 1 — for the single straight-line path through a function with no branches at all — to get V(G).

Why the graph formula gives the same answer

The graph-based formula V(G) = E − N + 2P and the decision-based shortcut V(G) = D + 1 describe the same thing from two directions. A straight-line function with N nodes has N − 1 edges and one connected component, so V(G) = (N − 1) − N + 2(1) = 1. Every decision point splits one node into two outgoing edges, adding exactly one edge without adding a node — so each decision increases V(G) by exactly one over that baseline. That is why counting decisions and adding 1 always matches counting edges, nodes, and components directly.

Reading the risk rating

McCabe's original paper proposed that functions with complexity above 10 were more error-prone and harder to test fully, and later research broadly supports that as a rule of thumb rather than a hard law. This calculator uses the commonly cited bands: 1–10 is simple and low risk, 11–20 is moderately complex, 21–50 is complex and high risk, and above 50 is considered untestable without breaking the function apart. Treat the rating as a prompt to review a function's structure, not an automatic pass/fail gate — some complexity (a long, flat switch mapping codes to labels, for example) is easier to maintain than its raw score suggests.

Common mistakes when counting decision points

  • Forgetting short-circuit operators: each && or || inside a condition adds a branch, even inside a single if statement — if (a && b && c) contains three decision points, not one.
  • Double-counting the default case: the baseline +1 in V(G) = D + 1 already represents the fall-through/default path, so only count explicit case labels, not default or a trailing else.
  • Mixing up complexity with size: a long function with no branching has a complexity of 1 no matter how many statements it contains, while a short function packed with conditionals can score high despite looking compact.

Frequently Asked Questions

What is cyclomatic complexity?
Cyclomatic complexity, developed by Thomas McCabe in 1976, is a software metric that counts the number of linearly independent paths through a program's source code. It is calculated from the control-flow graph as V(G) = E − N + 2P (edges − nodes + 2 × connected components), or equivalently as V(G) = D + 1, where D is the number of decision points.
How do I count decision points (D) for the D + 1 shortcut?
Count every branching construct: each if or else-if, each loop (for, while, do-while), each case label in a switch statement (not counting default), each catch block, each ternary operator (?:), and each short-circuit logical operator (&& or ||). Add these counts together to get D, then add 1 to get the cyclomatic complexity.
What do the cyclomatic complexity risk thresholds mean?
Based on McCabe's original guidance, a score of 1–10 indicates simple, low-risk code; 11–20 is moderately complex; 21–50 is complex and high-risk; and above 50 is considered untestable and should be refactored into smaller functions.
Does cyclomatic complexity equal the number of test cases I need?
Cyclomatic complexity gives the minimum number of test cases required for full branch (decision) coverage — enough to execute every linearly independent path through the function at least once. It does not guarantee coverage of every possible input value or data combination.