bc

Created: 12 Apr 2024
Updated: 24 Apr 2025
wiki english spanish wikibooks
faq http://phodd.net/gnu-bc/bcfaq.html
gnu source manual online
howard source
posix man
bsd man source
busybox source
toybox source

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"
obase output base ibase input base
scale decimals, default=0    

control flow

  • continue (works only with "for")
  • 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) {
}

snippets

morris88.jpg
Figure 1: Robert H. Morris in 1988
  • mikepierce/GNU-bc-Functions
  • susca/bc-extensions
  • idealvin/bc
  • extensions.bc
  • scientific_constants.bc
  • 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)
    

codebases

solve.sh

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

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"
    

articles

videos