bc

Created: 12 Apr 2024
Updated: 30 Mar 2025
source (C) https://github.com/fivepiece/gnu-bc/
manual https://www.gnu.org/software/bc/manual/html_mono/bc.html
faq http://phodd.net/gnu-bc/bcfaq.html
wiki https://en.wikipedia.org/wiki/Bc_%28programming_language%29
online https://bc.js.org/

cli

bc [OPTIONS] [FILES]
  • use BC_ENV_VARS env var to set cli arguments
  • use BC_LINE_LENGTH env var set to 0(zero) to disable wrapping
  • runs an interactively REPL if you just run it bare "bc"
-q –quiet suppreses welcome message
-l –mathlib enables trigonometric functions, sets scale=20
-s –standard forces use of POSIX bc language
-w –warn warn when using non-POSIX extensions

language

#!/usr/bin/bc -lq
#!/usr/bin/env -S bc -lq
#!/usr/bin/env -S BC_LINE_LENGTH=0 bc -lq
print "Hello\n" # might want that \n
quit            # needs an explicit
  • default scale=0, aka integer division
  • changing the value of scale low will accumulate rounding errors
  • in POSIX mode, functions and variables can only be 1 character long
  • "**" multi line comments
  • accepts bases from 2 to 36
  • 1 is true, 0 is false

arrays

  • index non-negative
  • index start at 0(zero)
  • no syntax sugar for creating
  • no automatic length book-keeping (eg: stats is impossible)
  • cannot be return from a function
  • max length given at compile time by BC_DIM_MAX (eg: 2^24)
  • no support for matrices
  • on a different "namespace" than variables
    • pass by reference

      define fibonacci_next (*array[], n) {
          array[n] = array[n-1] + array[n-2]
          return array[n]
      }
      
    • call by reference

      fibonacci_next(vec[])
      

functions

  • can receive simple variables or arrays
  • arguments passed by value by default

new

define foo (x) {
  auto pi=3.14 # "auto" declares pi a local variable
  print "this is 2 to the power of "; x*1; 2^x; pi*2;
  print "\n"   # ";" and/or \n to separate commands
}

stdlib

fn arg description
length n significant digits, including decimals
scale n significant digits, only decimals
random - returns a random positive? integer
read - reads value from stdin, returns value read
print s,… needs "\n", no (), takes a variadic nr of args
quit -  
sqrt n square root
s n sine of angle n given in radians
c n cosine of angle n given in radians
a n arctangent of angle n given in radians
l n natural logarithm
e n exponential of e to n
j n,m Bessel function of integer order n of x

variables

  • type is infered, not declared
  • undefined variables return 0
  • lowercase (uppercase used for bases >10)
last last command output
. shorthand for "last"
scale number of decimals (default 0)
obase "output base" (default 10)
ibase "input base"

control flow

  • continue/break/halt/return
if (20 > 0) { print "bigger" }
if (20 > 0) { print "bigger" } else { print "smaller" }
for (i=1; i<42; ++i) {
    print i, " | ", fibonacci(i), "\n"
}
while (1) {
}

articles

videos

snippets

  • needed to handle fractional exponents, uses e() and l()

    define pow (b,x) { return e(x*l(b)) }
    
  • getting the integer part of a number

    define int (x) {
        auto s;
        s=scale;
        scale=0; # temporarilly chaing the scale
        x/=1;
        scale=s; # restoring scale
        return x;
    }
    
  • radians <=> degrees conversions

    define radtodeg (x) { return x*(45/a(1)) }
    define degtorad (x) { return x*(a(1)/45) }
    

pi

scale=10
4*a(1)

solve

$ solve "4*49+732"
$ cat /usr/local/bin/solve
  #!/bin/sh
  bc << EOF
  scale=4
  $@
  quit
  EOF

codebases

sergiosgc/AdventOfCode2021

  • day6 part 1

    for (; i>0; i-=1) {
        n = timer[0]
        for (t=0; t<8; t+=1) timer[t] = timer[t+1]
        timer[8] = n
        timer[6] += n
    }
    for (i=0; i<9; i+=1) result += timer[i]
    print result
    print "\n"
    

other implementations