# OpenBSD bc

This is the `/usr/bin/bc` on OpenBSD systems. It has some, but not all, of the features as GNU 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

- 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] }

- 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" } }

- 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>