This is the /usr/bin/bc on OpenBSD systems. It has some, but not all, of the features as GNU bc.

OpenBSD bc is an implementation of bc. Other implementations of bc.

These extensions are in OpenBSD bc but not in POSIX:

  • Two new options, bc -c and bc -e.
  • Long names (more than one letter) for variables and functions.
  • # Line comments.
  • Relational operators (== <= >= !- < >) in any expression, not only in 'if', 'while' or 'for'.
  • Boolean operators (! && ||).
  • else branch of an 'if' statement.
  • print statement, with escapes like '\n'.
  • Special variable last, also known as . (a single dot).

The most unique feature of OpenBSD bc is that it runs on top of dc. (The original AT&T bc also did this, but GNU bc does not.) OpenBSD bc translates the entire program from bc to dc, then calls OpenBSD dc /usr/bin/dc to run the program. (OpenBSD dc has several extensions to allow this to work.)

The bc -c option just skips the second step, so we can see how OpenBSD translates a program from bc to dc. Here follows an example with the Fibonacci sequence.

  • Program using bc <lang bc>$ cat prog.bc
  1. compute fib[0] thru fib[19]

fib[0] = 0 fib[1] = 1 for (i = 2; i < 20; i++) { fib[i] = fib[i - 1] + fib[i - 2] }

  1. print fib[a] thru fib[b]

define fib(a, b) { auto i print "fib ", a, "..", b, " = " for (i = a; i <= b; i++) { print fib[i] if (i < b) print ", " else print "\n" } }

  1. assignments to prevent printing of trash

trash = fib(0, 4) trash = fib(15, 19) quit</lang>

  • Translation to dc <lang dc>$ bc -c prog.bc | vis
0 0:\M^?\^A\^A
1 1:\M^?\^A\^A

[li 1-;\M^?\^A\^Ali 2-;\M^?\^A\^A+li:\M^?\^A\^Alid1+sis.li 20>0]s0

2dsis.li 20>0 


[[, ]n]s1 [[ ]n]s2 [li;\M^?\^A\^Ads.nlilb>1e2 lid1+sis.lilb!<0]s0 [0SiSbSa[fib ]nlads.n[..]nlbds.n[ = ]nladsis.lilb!<0 Las.Lbs.Lis.0 1Q]s\M^?\^A\^B



0 4l\M^?\^A\^Bxs\M^?\^A\^C
15 19l\M^?\^A\^Bxs\M^?\^A\^C

q</lang>

  • Output <lang>$ bc -c prog.bc | dc -x # or simply $ bc prog.bc

fib 0..4 = 0, 1, 1, 2, 3 fib 15..19 = 610, 987, 1597, 2584, 4181</lang>