bc doesn't support log and factorial calculation?

bc supports the natural logarithm if invoked with the -l flag. You can calculate the base-10 or base-2 log with it:

$ bc -l
...
l(100)/l(10)
2.00000000000000000000

l(256)/l(2)
8.00000000000000000007

I don't think there's a built-in factorial, but that's easy enough to write yourself:

$ bc
...
define fact_rec (n) { 
  if (n < 0) {
    print "oops";
    halt;
  }
  if (n < 2) return 1;
  return n*fact_rec(n-1);
}
fact_rec(5)
120

Or:

define fact_it (n) {
  if (n < 0) {
    print "oops";
    halt;
  }
  res = 1;
  for (; n > 1; n--) {
    res *= n;
  }
  return res;
}
fact_it(100)
93326215443944152681699238856266700490715968264381621468592963895217\
59999322991560894146397615651828625369792082722375825118521091686400\
0000000000000000000000

To be POSIX compliant, you'd need to write it:

define f(n) {
  auto s, m
  if (n <= 0) {
    "Invalid input: "
    n
    return(-1)
  }
  s = scale
  scale = 0
  m = n / 1
  scale = s
  if (n != m) {
    "Invalid input: "
    n
    return(-1)
  }
  if (n < 2) return(1)
  return(n * f(n - 1))
}

That is: single character function name, no print, no halt, parenthesis required in return(x). If you don't need input validation (here for positive integer numbers), it's just:

define f(n) {
  if (n < 2) return(1)
  return(n * f(n - 1))
}

Orpie is the calculator for calculator and command line geeks. It emulates a modern HP RPN calculator, which is of course the only true way to calculate.

If you are a calculator heretic, raised on TIs, Casios, and such, there are many RPN tutorials online with which you may begin your re-education. The Orpie manual will eventually be of some use to you, once you get the RPN Way of thinking down.

To compute 5! in Orpie, just type it as you'd write it: 5 !. You can press Enter between them to push 5 onto the stack first, but it isn't necessary.

To compute log10(5), type 5 Enter ' l o Enter. You do have to push the 5 onto the stack first in this case, since the next keystroke isn't an operator. That single quote character enters command abbreviation mode, which lets you start typing log10, which you can uniquely identify with just the first two characters. (l alone gets you the natural log function, ln instead.)

As with any RPN calculator, you can get really fast with Orpie, with a bit of practice.

Orpie is in the stock Ubuntu repos. FreeBSD includes it in Ports, as math/orpie. On OS X, you can install it through Homebrew. Third-party packages may be available for other OSes. Building from source may be a bit of a chore, since it is written in OCaml, and you probably don't have an OCaml development environment installed. Getting one set up isn't particularly hard, though.


There's always GNU Octave, the emacs of command-line calculators (for when you want a complete development environment and programming language built-in to your calculator, and thousands of optional add-ons)

or R if stats are more your thing.

I mostly just use bc -l to get the standard math library loaded...I even have bc aliased to bc -l. See Mat's answer for info on defining a factorial function....although the bc man page defines it as:

define f (x) {
  if (x <= 1) return (1);
  return (f(x-1) * x);
}

Checking for <=1 rather than == 1 prevents an endless loop if you happen to feed it a negative number (should be an error) or zero (valid).

Tags:

Calculator