Decisions are steering
Befunge has no if block with a body. Instead, a decision is a cell that sends the pointer in one of two directions, and the two outcomes are simply two different paths across the grid. There are two such cells. The underscore _ is the horizontal if, and the pipe | is the vertical if.
Both pop the top value of the stack and look only at whether it is zero.
| Instruction | Name | Zero | Nonzero |
|---|---|---|---|
_ |
horizontal if | go east | go west |
| |
vertical if | go down | go up |
The popped value is gone afterward. If you need it later, duplicate it with : before the test. A test on an empty stack behaves as though it popped a zero in the common interpreters, so a missing value tends to send the pointer down the zero branch silently rather than failing loudly. That is one reason stack underflow is worth guarding against, since the program may seem to work while quietly taking the wrong path.
Choosing between the two
The choice is about the geometry of your program. Use _ when the two outcomes are naturally to the left and right of the test, and | when they are above and below. The instruction does not care which way the pointer arrived, so what matters is leaving room on both exit sides for a path to begin. Among the usual beginner mistakes is placing a test where one of its exits runs straight into an unrelated instruction.
A complete example
This program tests a hard-coded value and prints N if it is nonzero or Z if it is zero.
v >"N",@
>3 |
>"Z",@
The pointer starts at the top-left on the v and goes down to the > in row 1, which sends it east. It pushes 3, passes over a space, and reaches the |. The 3 is popped. Because it is nonzero, the pointer goes up, into the > in row 0 at the same column, east through the string "N", prints it with , and halts at @.
Change the 3 to 0 and the pointer goes down instead, into the > in row 2, and prints Z. Both outcomes are present on the grid at the same time; the data decides which one the pointer visits. A single character in quotes pushes just that character’s code, so the order problem that affects longer strings does not arise here.
Turning questions into zero and nonzero
The if instructions only know about zero, so most real conditions need a small conversion first. Befunge provides two helpers:
!is logical not. It pops a value and pushes 1 if the value was zero, or 0 otherwise.- The backtick pops two values and pushes 1 if the deeper one is greater than the top one, or 0 if not. With 7 pushed first and then 5, it pushes 1.
Equality is usually tested by subtracting and examining the result: if two numbers are equal, their difference is zero, so a _ or | right after the - sends equal values one way and different values the other. The echo-until-newline loop in the guide on Befunge loops works this way: it subtracts 10 from each character code and treats a result of zero as the signal to stop.
Because zero means one thing and everything else means the other, a negative number counts as nonzero. If you want to test for positive specifically, use the greater-than instruction against zero rather than testing the value directly.
Combining tests
To check two conditions, run one test and let its nonzero exit lead to the second. This is the grid equivalent of nested conditions. You can also combine values with arithmetic first. Multiplying two 0/1 results gives 1 only if both are 1, which acts like a logical and. Adding them and then applying ! twice gives a logical or, because the double not turns any nonzero sum into 1. These tricks keep the number of if cells small, but each one adds cells whose effect on the stack you must track.
Keeping branches readable
A few habits help once programs have more than one test.
- Give each exit its own clean path and avoid crossing branches over each other.
- Make sure both branches either end the program or rejoin at a known cell. If they rejoin, the stack height should be the same on both sides, otherwise later code will see different data depending on the route taken.
- Put a clear marker on each path where possible, such as the character printed in the example above, to help later when you are tracing by hand.
- Leave the cell beyond each exit empty or intentional. An accidental instruction there is the most common source of branching bugs.
The trampoline instruction pairs naturally with these tests. A # placed before a test can let one if cell be approached from two different directions without executing the wrong neighbor, which is how the compact loop in the worked countdown program is built.
One more point on direction
Both ifs change direction, but they never change it to something unexpected: _ always chooses east or west, and | always chooses north or south. If you want a random branch instead of a data-driven one, the question mark instruction picks among all four directions, and the page on random direction describes how it behaves. For ordinary programs, the data-driven ifs are the ones you will use most.