Code.RogerHub » bc https://rogerhub.com/~r/code.rogerhub The programming blog at RogerHub Fri, 27 Mar 2015 23:04:04 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.2 A better better calculator with bc https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/ https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/#comments Mon, 25 Mar 2013 20:55:51 +0000 https://rogerhub.com/~r/code.rogerhub/?p=90 GNU/bc is a command-line calculator for linux. It does variables [a-z0-9_]+ and +-*/^ and basic math, all through the terminal, and while it’s somewhat useful by default, it can be made to be a lot better. Reading man bc, you see that the program reads an environmental variable, BC_ENV_ARGS, which refers to a list of command line arguments implicitly appended to every invocation of bc. Quoting the source, those files “typically contain function definitions for functions the user wants defined every time bc is run”.

alias bc='bc -l'

First off, you’ll want to alias bc with the -l command line argument, which loads a bunch of math functions including the following:

s(x) Sine
c(x) Cosine
a(x) Arctangent
l(x) Natural logarithm
e(x) Exponential function
j(n, x) Bessel function

They clearly defined this minimal set with the expectation that you’d extend them, so of course, I did. In ~/.bashrc, I exportd BC_ENV_ARGS=~/.bcrc, and started the following in ~/.bcrc:

/* Config for bc */
scale=39

Scale is a special variable in bc. It determines the number of significant figures that bc will carry in its calculations, and 39 worked well for me. Then I defined some physical constants in the form of k_[a-z]+:

print "\n"
print "Usage: k_[?] with one of: c, g, atm (atmospheric), h, hbar, mu,\n"
print "       ep(silon), e (elementary charge), coulomb, me (electron),\n"
print "       mp, n (avogadro's), b (boltzmann), r (gas), si(gma)\n\n"

k_c = 299792458 /* Speed of Light */
k_g = 6.67384 * 10^-11 /* Universal Gravitation */
k_atm = 100325 /* Atmospheric pressure */
k_h = 6.62606957 * 10^-34 /* Planck's constant */
k_hbar = 1.054571726 * 10^-34 /* H Bar */
k_mu = 1.256637061 * 10^-6 /* Vacuum permeability */
k_ep = 8.854187817 * 10^-12 /* Vacuum permittivity */
k_epsilon = 8.854187817 * 10^-12 /* Vacuum permittivity */
k_e = 1.602176565 * 10^-19 /* Elementary charge */
k_coulomb = 8.987551787 * 10^9 /* Coulomb's constant */
k_me = 9.10938294 * 10^-31 /* Rest mass of an electron */
k_mp = 1.672621777 * 10^-27 /* Rest mass of a proton */
k_n = 6.02214129 * 10^23 /* Avogadro's number */
k_b = 1.3806488 * 10^-23 /* Boltzmann's constant */
k_r = 8.3144621 /* Ideal gas constant */
k_si = 5.670373 * 10^-8 /* Stefan-Boltzmann constant */
k_sigma = 5.670373 * 10^-8 /* Stefan-Boltzmann constant */

pi = 3.1415926535897932384626433832795028841968 /* pi */

And then these:

print "Usage: s(x) c(x) t(x) as(x) ac(x) at(x)\n"
print "       csc(x) sec(x) cot(x) e(x)\n\n"
define t(x) { return s(x)/c(x); }
define as(x) { return 2*a(x/(1+sqrt(1-x^2))); }
define ac(x) { return 2*a(sqrt(1-x^2)/(1+x)); }
define at(x) { return a(x); }
define csc(x) { return 1/s(x); }
define sec(x) { return 1/c(x); }
define cot(x) { return c(x)/s(x); }

I printed the default mathlib functions in the Usage for completeness. Stuff like sqrt() works too. I use bc primarily for physics homework, since built-in GUI calculators often have better base-conversion and visualization abilities for programming.

]]>
https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/feed/ 0