Befunge Techniques

Reading Numeric Input in Befunge

How the ampersand and tilde instructions read numbers and characters in Befunge, how to convert digit characters to values, and what to watch for at end of input.

On this page
  1. Two ways to read
  2. The simplest case: whole numbers
  3. Converting a digit character to a value
  4. Building a multi-digit number
  5. Reading characters until a newline
  6. End of input
  7. Defensive habits

Two ways to read

Out of the whole instruction set, two instructions handle input, and they answer different questions.

  • The ampersand & reads an integer. It consumes digits from the input, up to the first character that cannot be part of the number, and pushes the resulting value.
  • The tilde ~ reads one character and pushes its character code.

Both put exactly one value on the stack. If you ask for a number and the person types 42, & pushes 42. If you use ~ for the same input, you get two values, one for each of the characters 4 and 2, which are the numbers 52 and 50 in ASCII. Most of the technique in this area is knowing which instruction to use and what to do with the value afterward.

How an interpreter treats unusual input, such as letters where a number is expected, differs between implementations. For anything that matters, test with your interpreter, and avoid relying on one interpreter’s quirks.

The simplest case: whole numbers

When you just need a number, & is the easy path. This program reads one and prints twice its value:

&2*.@

The pointer reads an integer, pushes 2, multiplies, prints the result followed by a space, and stops. If the input is 21, the output is 42. The number now on the stack can feed any other technique, such as a counted loop in which the number is the iteration count.

Notice that the program does not need to know how many digits the input has. That is the benefit of &.

Converting a digit character to a value

With ~, you receive character codes. The characters 0 through 9 have consecutive codes, with 0 being 48. So a digit’s value is its code minus 48. Pushing that 48 is easy in quote mode, because "0" pushes the code for the character zero:

~"0"-.@

This reads one character, pushes 48 via the quoted zero, subtracts, prints the value and stops. If the character is 7, its code is 55 and the result is 7. Written this way the program documents itself: the reader sees “subtract zero” and understands the intent.

Using the quoted character is clearer than writing the number 48 with arithmetic. It also avoids a wrong constant.

Building a multi-digit number

Sometimes you need to read digits yourself, for example when the input format is not a plain number. The standard method is accumulate and multiply. Keep a running total on the stack. For each new digit, multiply the total by 10 and add the digit’s value.

For the input 42:

  1. Start with a total of 0.
  2. Read 4, convert to 4. The total becomes 0 times 10 plus 4, which is 4.
  3. Read 2, convert to 2. The total becomes 4 times 10 plus 2, which is 42.

In Befunge the pointer then loops until it sees a character that is not a digit, such as a newline. The loop needs the swap instruction to get the total and the new digit in the right order, and the logic is a good exercise in the stack discipline described under the program stack. Most programs avoid this by using &, but it teaches the technique that every number reader uses.

Also note that only the digits 0 to 9 can be pushed directly. Any other constant, like 10, must be built with arithmetic, such as 55+.

Reading characters until a newline

Conditional loops are a natural fit for input. This program echoes what it reads and stops at the end of the line:

>~:55+-#v_@
^      ,<

Reading it as a flow: ~ reads a character, : duplicates it, 55+ pushes 10, and - subtracts. If the result is zero, the character was a newline code, so _ goes east to the @. Otherwise _ goes west, the v steers down, and the , prints the original character before the loop returns to the start. The grid shows the loop clearly: top row forward, bottom row back.

Whether newline is code 10 or something else depends on the platform, and some interpreters strip or convert line endings. If your loop never ends, print the character codes with . to see what is actually arriving.

End of input

When no more input is available, interpreters behave differently. Some push -1 from ~, some push 0, and some stop the program or reuse the last character. A loop that waits for a newline can therefore run forever if the input has no final newline. If you need robust behavior, check the documentation or test your interpreter, and add a second exit for the end-of-input value you observe.

Defensive habits

  • Decide up front whether a value is a number or a character, and keep the two apart. Mixing them up is one of the classic beginner mistakes and produces results that are off by 48.
  • Print what you read while developing. A temporary . after the input instruction shows what the stack holds.
  • Avoid assuming how many values ~ will deliver. A single digit typed with a newline gives you two characters, not one.
  • Plan for the stack underflow that happens if your loop pops a value it never pushed.

The details of how interpreters deal with input and output at a lower level belong to the interpreter side of the site, in the page on interpreter input output. For now, treat the input instructions as a reliable but implementation-sensitive way to get values onto the stack.

The complete guide to befunge techniques

Befunge Programming Techniques Overview
Read the guide

Keep exploring

Guides from other topics

All topics →