GNU bc
GNU bc is the useful little calculator program found on most modern Linux
installations that no-one seems to do anything interesting with. The aim of this page
is to try to change that, hopefully for the better. Here you'll find various bits and
pieces to make life with GNU bc simpler or at least more interesting.
Each of the scripts/files/programs/libraries/whatevers below contain
comments explaining exactly what the file is, what it does and what each of the
functions do. It's not the best way of documenting things, but if you intend to
use or learn from these files, putting the documentation in with the code was
- IMHO - the best way to do things.
At some point I might get around to documenting these files and functions properly
in HTML on this page, rather than providing a brief overview. I should probably set
up a wiki or a forum, since there's about 50k of bc code to document.
The forerunner to this page was linked
from the bc articles in both the
English,
German and
Japanese
Wikipedias. Welcome, Wilkommen and Irasshai to readers heading in
from those places!
* If you found this page through an internet search and can't see what you were
looking for, try the bc FAQ page - you might find it
there!
Files, Keywords and Functions
The files linked here contain well over 250 function definitions for GNU bc;
This section should provide some sort of idea as to what kind of functions can be
found in each file, beyond any hint already provided by the filename.
Before we begin...
Before downloading any of these files and to avoid any puzzled moments when reading
this web page, a passing familiarity with bc is recommended. The
official GNU-bc manual
is well worth a read.
Some style notes
There are some conventions that I have tried to stick to in these files to help
identify certain types of function. The main conventions are:
-
Global variable names and function names which end with underscores indicate that
the object is not intended for use outside the file which contains it.
e.g. graph.bc contains a function called
or_
which performs a bitwise OR, but is much more simplified than the version found
in logic.bc.
-
Functions which contain the word "print" in their name write to the console as
well as returning a value. Since bc automatically outputs numbers not assigned
to a variable, it is best to assign these functions to a dummy variable if the
return value is unrequired. See comments in
outputformatting.bc
for an example.
-
Functions whose name begins with
int_ are fast, integer-only
calculations that pay no regard to fractional parts of numbers. Often there
is an equivalent function without the prefix that will work on floating point
numbers. One pair of examples is remainder and
int_remainder which are found in funcs.bc.
-
Functions whose name begins with
is_ determine truth or falsity
and return 1 for true and 0 for false. Many examples of this can be found in
digits.bc.
-
Many functions contain the construct
os=scale; scale=0; /* do something */; scale=os
. This saves the built-in scale variable and switches to
integer-only arithmetic before switching back again. Since bc has no stack to
store system variables, most functions create their own instance of
os, an abbreviation of "old scale" so as not to interfere with
other functions and any interactive session that might be under way.
-
Fairly often in the code, the constant
A appears. This is one of
bc's quirks, in that the capital letters A to F represent the numbers ten to
fifteen regardless of which number base is set within the built-in
ibase variable. Much of bc is designed with base ten in mind,
especially the aforementioned scale variable, which designates
precision in decimal places. Use of A guarantees that
the value obtained is indeed ten and not some other value.
Directory of functions and functionality
- 235.bc
-
Find the sum of powers of 2, 3 and 5 that are closest to a number
- print235(x)
-
The only function in this odd little file. Does exactly as described, although
the implementation isn't perfect and it sometimes misses a nearer answer to the
one given if there isn't an exact solution.
- ack.bc
-
Calculate the hyper-exponential Ackermann function; All but useless given
that bc can't cope with such huge numbers!
- ack(x,y)
-
Tries to calculate the Ackermann function
- ackz(x,y)
-
As above, but works better (when it works at all) for floating point values
- anglepow.bc
-
A semi linear version of exponentiation and logarithm related to the number sequence:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400,
500, 600, 700, 800, 900, 1000, 2000, etc. [See the OEIS's
A037124]
- anglepow10(x)
-
Calculates the x'th entry in the above sequence
- anglelog10(x)
-
Calculates the inverse of the above
- anglepow(b,x)
-
An extension of anglepow10 to all number bases b
- anglelog(b,x)
-
Calculates the inverse of the above
- baselogic.bc
-
An abortive attempt to scale up bitwise functions to bases other than binary;
The well defined and more complete set of binary bitwise functions can be found in
logic.bc,
although all functions herein will return correct results when base 2 is specified.
- asym_mixor(base, x,y)
-
One possible extension of bitwise XOR into other number bases. Is asymmetric
in that asym_mixor(base, x,y) doesn't always equal asym_mixor(base, y,x).
- digitwise_diff(base, x,y)
-
Another possible extension of XOR into other number bases.
- digitwise_max(base, x,y)
-
A logical extension of bitwise OR.
- digitwise_min(base, x,y)
-
A logical extension of bitwise AND.
- digitwise_modmult(base, x,y)
-
Another logical extension of bitwise AND.
- digitwise_tlumdom(base, x,y)
-
Another logical extension of bitwise OR. Note that tlumdom is modmult
backwards; the underlying algorithms are related.
- digitwise_xor_(which, base, x,y)
-
Note the final underscore: This function contains the main engine for
most of the other functions in this file.
- no_borrow_diff(base, x,y)
-
Yet another XOR-like extension
- no_carry_add(base, x,y)
-
A fourth XOR-like extension
- cf.bc
-
A suite of functions for very basic continued fraction analysis. Uses the
global array
cf[] as a work area, and needs to be run along
with funcs.bc as some of the functions there are
required.
- bincf(x)
-
Turns the binary representation of x into a continued fraction-like
structure, e.g. 0.1001000011111101110111 -> [0;1,2,1,4,6,1,3,1,3]
- cf(x)
-
Creates a continued fraction representation of x into global array
cf[]
- cf2bin()
-
Turns a continued fraction into an analogous binary number.
Inverse of
bincf
- cf2num()
-
Turns a continued fraction into its actual value as a number
- cf2num_abs()
-
Turns a continued fraction into a number ignoring any negative signs
that might be in the CF.
- cf2num_abs1()
-
Turns a continued fraction into a number ignoring any negative signs
that might be in the CF and subtracting 1 from each term
- cfalt(x)
-
Creates a continued fraction representation of x into global array
cf[] ensuring that the sign of each CF term is opposite to
the one before. e.g. [1;-2,1,-2,1,-2,1,-2]
- cfnear(x)
-
Creates a continued fraction representation of x into global array
cf[] choosing the sign of each term to move as close to an
approximation as possible at each step.
- printcf()
-
Prints the current contents of the global array
cf[] with
CF-style formatting.
- collatz.bc
-
A suite of functions for very basic experimentation with the Collatz conjecture,
using the slightly modified but equivalent rules of
even x → x/2, odd x → (3x+1)/2
- cz_8tp(x)
-
Eight tree path: Generates a binary number representing a hailstone choice
path. All numbers lead back to 8, this function maps the path as a binary
number with the bit representing 8 as most significant.
(8) => 1, (5 → 8) => 10, (16 → 8) => 11,
(10 → 5 → 8) => 101, etc.
- cz_chain(x)
-
Prints the chain of numbers from x to 1
- cz_chlen(x)
-
Returns the length of the chain
- cz_chmax(x)
-
Returns the maximum number in the chain
- cz_chsum(x)
-
Returns the sum of all numbers in the chain
- cz_i8tp(p)
-
Inverse 8 tree path: Convert an 8-tree path encoded as a binary number
into a hailstone by following the hailstone rules in reverse.
NB: not all binary numbers are valid 8TPs and so do not generate
valid hailstones. This usually means a non-integer return value!
- cz_next(x)
-
Returns the next hailstone in the chain
- cz_prev(x)
-
Returns the lowest possible prior hailstone to x
- complex.bc
-
A hackish attempt at creating and working with complex numbers, mainly as
a demonstration that it is possible to do, but relatively difficult in bc:
A new datatype of complex number had to be created.
- cabs(c)
-
Find the absolute value of a complex number
- cadd(c1,c2)
-
Add two complex numbers
- cconj(c)
-
Return the complex conjugate of a complex number
- cdiv(c1,c2)
-
Divide complex number c1 by c2
- cintpow(c, n)
-
Raise a complex number to an integer power
- cmul(c1,c2)
-
Multiply two complex numbers
- cneg(c)
-
Negate a complex number
- csqrt(c)
-
Take the square root of a complex number
- csquare(c)
-
Square a complex number
- csub(c1,c2)
-
Subtract complex number c2 from c1
- imag(c)
-
Fetch the imaginary part of a complex number
- int(n)
-
Return the integer part of a standard number
- makecomplex(r,i)
-
Make a complex number with standard numbers representing
real and imaginary parts
- mod(n,m)
-
Return n modulo m where n and m are standard numbers
- printc(c)
-
Print a complex number
- read_digit(number, place)
-
Read a decimal digit from a number, specified by place
- real(c)
-
Fetch the real part of an imaginary number
- realimag_(c,f)
-
Internal function
- cosconst.bc
-
The cosine constant to a large number of decimal places, where
x = cos(x)
- None
-
There is only a constant called
cosconst
- describe.bc
-
- Look-and-say
- Numbers describing numbers
- describe_(opt,base,x)
-
Internal function for both modes of describing numbers
- describe_countfirst(base,x)
-
Generates a number (in the specified base) which describes x by putting the
digit count of each digit of x before the actual digit of x.
This is the standard, well known
look-and-say sequence.
e.g. 111 -> 31 (three 1s); 1123 -> 211213 (two 1s, one 2, one 3).
A warning will result if a digit count is too large for the specified base.
- describe_countlast(base,x)
-
Generates a number (in the specified base) which describes x by putting the
digit count of each digit of x after the actual digit of x.
This is the alternative look-and-say sequence.
e.g. 111 -> 13 (1, three times); 1123 -> 122131 (1 twice, 2 once, 3 once)
Again, a warning will result if a digit count is too large for the specified base.
- parserle_(opt,base,x)
-
Internal function for both modes of interpreting the above description numbers.
The name comes from "Parse RLE" or Parse Run Length Encoding. The irony of the
function name being hard to read (parse) has been left uncorrected as it is
amusing to the author as well as the same length (in letters) as "describe".
- parserle_countfirst(base,x)
-
Inverse of describe_countfirst(); Interprets the value in x as a description
(in the specified base) of a number, which is calculated and returned.
A warning will result if x is not interpretable.
- parserle_countlast(base,x)
-
Inverse of describe_countlast(base,x); Interprets the value in x as a description
(in the specified base) of a number, which is calculated and returned.
A warning will result if x is not interpretable.
- digits.bc
-
Treat numbers as strings of digits. Some of the definitions below
are not in strict alphabetical order. This is so that concepts are
introduced in a more logical order
- Digital sum
- Reverse
- Palindromes
- Happy numbers
- Stringification
- Cantor reinterpretation
- Bijective integer cantor reinterpretation
- Miscellaneous
- append_all(base,x)
-
The digit string equivalent of the triangular numbers
or the factorials. Appends all representations
of the numbers from 1 to x in the current base to each other.
e.g. assuming base ten, append_all(10, 15) = 123456789101112131415
- cantor(basefrom, baseto, x)
-
Treat x's representation in basefrom as a representation in baseto and
return the resulting number, i.e. reinterpret the number.
Will always convert successfully to a larger base, but the reverse is
often not possible, and a warning will result when data loss occurs.
Warnings can be turned off by setting the global cantorwarn_
variable to 0. It is set to 1 by default.
x can be interpreted as if basefrom is a
bijective base
(see outputformatting.bc for ways to display
numbers as bijective) if global variable cantorbijective_ is
set to 1. It is set to 0 by default. Note that a warning will result if x is
non-integer in bijective mode; there is no correct way to interpret such a value.
- digit_sum(base,x)
-
Add the digits of x when interpreted in the specified base. Repeated
applications of this function would derive the "digital root".
- digit_product(base,x)
-
As above, but add one to each digit, multiply rather than add then
subtract one from the result. e.g. assuming base ten
235 → (2+1)(3+1)(5+1)-1 = 3*4*6 - 1 = 71
- digit_prodduct(base,x)
-
As above, but perform the transformation n → 2n-1 on each
digit, multiply as before and then invert the transformation on the
result, i.e. n → (n-1)/2. e.g. assuming base ten
13462 → ( (2*1+1)(2*3+1)(2*4+1)(2*6+1)(2*2+1)-1 )/2 =
(3*7*9*13*5 - 1)/2 = 6142
- digits(base,x)
-
Find the number of digits in x's representation in the given base.
- int_catenate(base, x,y)
-
Splice two integer representations together in the specified base so
that x is before y.
- int_left(base, x, count)
-
Returns the leftmost digits of x in the given base,
specified by the given count.
- int_mid(base, x, start, end)
-
Returns digits of x in the given base, counting in from the left,
starting and ending at the given digit positions.
- int_right(base, x, count)
-
Returns the rightmost digits of x in the given base,
specified by the given count.
- is_happy(base,pow,x)
-
Generalised
Happy Numbers:
Returns 1 (true) if x is happy in the given base when each digit is
raised to the given power, 0 (false) otherwise. The original definition
of happiness involves base ten and a power of two (squaring).
- is_palindrome(base,x)
-
Determine whether x reads the same forwards and backwards in the given
base
- is_pseudopalindrome(base,x)
-
Determine whether x reads the same forwards and backwards in the given
base, or could read the same each way if zeroes were prepended
to the number (which wouldn't actually change its value).
- is_negapalindrome(base,x)
-
Determine whether the opposing pairs of digits, (counted in from either
end) sum to one less than the given base. e.g. 147258 is a
negapalindrome in base ten since 1+8 = 4+5 = 7+2 = 9 = 10 - 1
- is_pseudonegapalindrome(base,x)
-
Determine whether x is a negapalindrome in the given base should any
number of zeroes are prepended to the number. These would tie in with
any digits one less than the base found at the end of x, and wouldn't
change x's value.
- is_negapalindrome2(base,x)
-
Alternate definition of negapalindrome, where opposing pairs of digits
must sum to the base itself, rather than one less.
- is_substring(base,large,small)
-
Determine whether the digits of the smaller number appear, in order,
within the digits of the larger number, all in the given base.
- make_even_palindrome(base, x)
-
Turn x into a unique palindrome with an even number of digits in the
given base.
- make_odd_palindrome(base, x)
-
Turn x into a unique palindrome with an odd number of digits in the
given base.
- map_palindrome(base, x)
-
Generate a unique palindrome from x in the given base. This function
maps the integers onto the palindromes on a one-to-one basis.
- map_negapalindrome(base, x)
-
As above but for negapalindromes.
- reverse(base,x)
-
Reverse the digits of x in the current base. Zeroes at the end of
x will be lost.
- sort_digits_asc(base,x)
-
Sort the digits of x into ascending order in the given base.
Zeroes at the end of x will be lost.
- sort_digits_desc(base,x)
-
Sort the digits of x into descending order in the given base.
- stripbm1s_(base,x)
-
Internal function
- unmap_negapalindrome(base, x)
-
Inverse function of
map_negapalindrome; Maps the domain
of negapalindromes in the given base back into the integers.
- unmap_palindrome(base, x)
-
Inverse function of
map_palindrome; Maps the domain
of palindromes in the given base back into the integers.
- digits-calcsegments.bc
-
Counting the segments of a number on a calculator's seven segment display
- calcsegments(base,x)
-
Returns the number of segments that would be 'lit' on a seven-segment-per-number
calculator display. Customised to support bases up as far as 36, although no
calculator goes any further than 16. Adds one for the negative sign since all
calculators need a segment to show that.
- funcs.bc
-
A large suite of functions to complement the bc standard library. Unlike the standard
library (activated with
bc -l), all function names are spelled out in full.
Full name aliases for the standard library functions are provided.
- Integer and Rounding
- Trigonometry
- Hyperbolic Trigonometry
- Exponential / Logarithms
- Powers / Roots
- Lambert W
- Fibonacci / Lucas
- Factorials
- Triangular numbers
- Polygonal numbers
- Arithmetic-Geometric mean
- abs(x)
-
Absolute value of a number
- arccos(x)
-
Inverse cosine
- arccosec(x)
-
Inverse cosecant
- arccosech(x)
-
Inverse hyperbolic cosecant
- arccosh(x)
-
Inverse hyperbolic cosine
- arccotan(x)
-
Inverse cotangent (single variable)
- arccotan2(x,y)
-
Inverse cotangent (two axes)
- arccoth(x)
-
Inverse hyperbolic cotangent
- arcgudermann(x)
-
Inverse of the
Gudermann function
- arcsec(x)
-
Inverse secant
- arcsech(x)
-
Inverse hyperbolic secant
- arcsin(x)
-
Inverse sine
- arcsinh(x)
-
Inverse hyperbolic sine
- arctan(x)
-
Inverse tangent (single variable). This is an alias for bc's own
a() function.
- arctan2(x,y)
-
Inverse tangent (two axes)
- arctanh(x)
-
Inverse hyperbolic tangent
- arigeomean(a,b)
-
Arithmetic-geometric mean
- besselj(n,x)
-
Bessel J function. This is an alias for bc's own
j() function.
- ceil(x)
-
Ceiling function: returns the next integer greater than or equal to x
- combination(n,r), int_combination(n,r)
-
Calculates the binomial coefficient nCr. i.e. How many ways can r objects be
chosen from n objects without regard to order? The non-integer function is slower but
uses the factorial function to a closely approximated
calculation for non integral parameters.
- converse_poly(x,r)
-
converse of poly; solves poly(s,x)=r for s. i.e. if the xth polygonal
number is r, how many sides has the polygon? e.g. if the 5th polygonal number is 15,
converse_poly(5,15) = 3 so the polygon must have 3 sides! (15 is the 5th triangular number)
- cos(x)
-
Cosine; Is an alias for bc's own
c() function.
- cosec(x)
-
Cosecant
- cosech(x)
-
Hyperbolic cosecant
- cosh(x)
-
Hyperbolic cosine
- cotan(x)
-
Cotangent
- coth(x)
-
Hyperbolic cotangent
- exp(x)
-
Exponential function ex.
This is an alias for bc's own
e() function.
- factorial(x)
-
An approximation to the factorial function over the reals. Is accurate as possible for
all integers and half-integers, but interpolates otherwise. As such this is not a true
Gamma function, but is within ten decimal places most of the time.
- fibonacci(n)
-
An extension of the fibonacci numbers over the reals without stepping into complex
numbers, which would be necessary for a true extension.
- floor(x)
-
Floor function. Finds the integer less than or equal to x.
- frac(x)
-
Finds the fractional part of number, discarding the integer part.
Always returns a non-negative answer.
- gcd(x,y), int_gcd(x,y)
-
Calculate the GCD (Greatest Common Divisor) of x and y.
- gfactorial(n)
-
A rough, quick and dirty approximate to the factorial function using the below.
- gosper(x)
-
Gosper's approximation to the natural logarithm of the factorial function.
- gudermann(x)
-
The Gudermann function
which links hyperbolic and common trigonometric functions.
- id_frac_(y)
-
Internal function. Helps determine whether the fractional part of a number is
most likely odd/even, odd/odd,
even/odd or irrational.
- int(x)
-
Finds the integer part of x, always rounding towards zero.
See ceil and floor for more useful functions.
- int_multifactorial(y,x)
-
Quick and dirty function to calculate the y'th multifactorial of x.
- inverse_factorial(x)
-
A very approximate inverse to the factorial function.
Developed from an idea by David W. Cantrell.
- inverse_fibonacci(f)
-
An inverse to the fibonacci function.
Provides incorrect answers for non integer values of f when f < 1.
- inverse_lucas(l)
-
An inverse to the lucas function.
Provides incorrect answers for non integer values of l when l < 2.
- inverse_poly(s, r)
-
"Polygonal root": If a polygonal number with s sides has area r,
how many elements are along each side? For s = 4 this is the same as the square root,
and for s = 3, this is the same as the trirt function.
- lambertw0(x)
-
The zero branch of the Lambert W function, i.e. the inverse of xex.
- lambertw_1(x)
-
The minus one branch of the Lambert W function
- lcm(x,y), int_lcm(x,y)
-
Calculate the LCM (Lowest/least Common Multiple) of x and y.
- ln(x)
-
A verbose alias to bc's own
l() Natural Logarithm function.
Complains when given unexpected values.
- lnfactorial(x)
-
Calculates the logarithm of the factorial function in a way
generally faster than
ln(factorial(x)), but with the same caveats as
before: Is accurate as possible for all integers and half-integers, but interpolates
otherwise.
- log(base,x), int_log(base,x)
-
Find the logarithm of x to the given base.
- lucas(n)
-
Returns the n'th Lucas number. Continuous over the reals, like its cousin the
fibonacci function
- nemes(x)
-
Gergo Nemes' excellent approximation to the natural logarithm of the
factorial function
- nemfactorial(n)
-
Uses the above to calculate an approximation to the
factorial function.
- permutation(n,r), int_permutation(n,r)
-
How many ways can r objects be chosen from n objects when the order of choosing
is important? The non-integer function is slower but uses the
factorial function to
a closely approximated calculation for non integral parameters.
- phi()
-
Gives the golden ratio φ (1.618033...) to the number of decimal places
specified by the current
scale.
- pi()
-
Gives π (3.141592...) to the number of decimal places specified by the
current
scale.
- poly(s, x)
-
Return the x'th s-sided polygonal number, e.g. the 10th triangular number = poly(3,10)
- pow(x,y)
-
Returns an extremely close approximation (completely accurate in the case of integer
parameters) to xy; Copes very well with negative numbers, fractional
exponents etc. always returning a real root where possible.
Will complain and return zero otherwise.
- powroot(x)
-
Solves x = yy for y.
- psi()
-
Gives the alternate golden ratio ψ (-0.618033...) to the number of decimal
places specified by the current
scale.
- pyth(x,y)
-
Pythagoras: Calculates the hypotense of a right angled triangle whose other sides
are x and y.
- pyth3(x,y,z)
-
Pythagoras 3D: Calculates the long diagonal of a cuboid whose sides are x, y and z.
- remainder(x,y), int_remainder(x,y)
-
Calculates the remainder when x is divided by y. The non-integer version works in a
more intuitive manner than bc's built in
% (modulus) operator.
- root(x,y)
-
Returns an extremely close approximation to y√x; Copes very
well with negative numbers, fractional exponents etc. always returning a real root
where possible. Will complain and return zero if there is a problem.
- round( x,y)
-
Round x to the nearest multiple of y.
- round_down(x,y)
-
Round x to the multiple of y less than or equal to x.
- round_up( x,y)
-
Round x to the multiple of y greater than or equal to x.
- sec(x)
-
Secant
- sech(x)
-
Hyperbolic Secant
- semifactorial(x)
-
Calculates the semifactorial (x!! = x.(x-2).(x-4)..{2 or 1}) with the same caveats as
for factorial and other functions: Is accurate as possible
for all integers and half-integers, but interpolates otherwise.
- sgn(x)
-
Returns the sign of x; -1 for negative, 0 for zero, 1 for positive
- sin(x)
-
Sine; Is an alias for bc's own
s() function.
- sinh(x)
-
Hyperbolic sine
- tan(x)
-
Tangent
- tanh(x)
-
Hyperbolic tangent
- tri(x)
-
The x'th triangular number
- tri_pred(t)
-
Given a triangular number t, returns the next triangular number. Works also for
non triangular numbers, providing a continuum.
- tri_step_(t,s)
-
Internal function: Used by the preceding and succeeding entries here...
- tri_succ(t)
-
Given a triangular number t, returns the previous triangular number. Works also
for non triangular numbers, providing a continuum.
- trirt(x)
-
"Triangular root": Given a triangular number, returns its index in the sequence of
triangular numbers.
- w(x)
-
In the manner of bc's own single-letter functions
s(), c(), a(), l(), e() and j(), this provides access to
the lambertw... functions, choosing the most logical
branch; Minus one for negative x, Zero for positive and zero x.
- graph.bc
-
A rudimentary console-based graphics package. Uses a global array called
screen[] to store a very simple 'bitmap' made up of characters.
The x and y dimensions are set with global variables screen_x
and screen_y.
- or_(x,y)
-
Internal function: Bitwise OR. See logic.bc for the
fully fledged version of this function.
- screen_clear()
-
Blanks out the global
screen[] array.
- screen_axes(xx,yy)
-
Draws axes with an origin at coordinates (xx,yy) into
screen[]
Returns 0 if (xx,yy) is out of bounds and 1 otherwise
- screen_plot(x,y,c)
-
Put the character specified by c into
screen[] the coordinates (x,y).
If c is negative, an attempt is made to combine any character already at (x,y)
with the character specified by -c. e.g. screen_axes(xx,yy) uses this feature
to combine the y-axis "|" character with the x-axis "-" character to form a "+"
sign at the origin. Character values have been chosen for c so that reasonable
combinations will form using negative c.
Returns 0 if (x,y) is out of bounds and 1 otherwise.
- screen_print()
-
Actually display the intended interpretation of the contents of
screen[] onto the console.
- screen_printchar_(c)
-
Internal function: Prints a character specified by c.
- intdiff.bc
-
Perform numerical integration and differentiation of a single variable function.
- Numerical Integration
- Numerical Differentiation
- Guessing convergence limits
- f(x)
-
All ?fxdx functions here automatically look for a function called f to perform
their operations upon. Since bc allows re-definition of functions, redefining f(x)
to be an alias of the function to be used is recommended before using the other
functions. e.g.
define f(x){return sqrt(x)}; ifxdx(2,3)
- dfxdx(x)
-
Return the value of the first derivative of f at x.
- glai(p,q,r)
-
Guess Limit At Infinity: given three convergents to a limit, this function attempts
to extrapolate the limit at infinity. e.g.
glai(63.9, 63.99, 63.999)
returns 64. Uses global variable glaitalk to comment on and warn about
interesting situations. Set this to 0 to turn it off.
- ifxdx(a,b)
-
Return the indefinite integral (i.e the area under the curve) of f between a and b.
A global variable called
depth is used here (akin to bc's own
scale variable), which determines how deep the calculation should go.
It is set at an acceptable (for 2010) value already. The user changes it at their
own risk as calculation time grows exponentially in proportion to it.
- ifxdx_g(a,b)
-
As above but uses glai to save on calculations.
- logic.bc
-
A large suite of functions to perform bitwise functions such as
AND, OR, NOT and XOR. Uses twos complement for negative numbers, unlike previous
versions of this file, which had no support at all.
Some of the functions here will use the global
bitwidth variable,
which itself is initialised as part of this file, to emulate byte/word sizes
found in most computers. If this variable is set to zero, an infinite bitwidth
is assumed.
- Fixed word size
- Infinite word size
- Common bitwise
- Twos complement
- Bit shifting
- Gray code
- 'Multiplication'
- Floating point
- Floating point + 'Multiplication'
- Gray code + Floating Point
- bitwidth(x)
-
This function determines the minimal bitwidth needed to contain the value of x.
Effectively an integer logarithm function.
- bw_mult_(sc)
-
Internal function: Used along with internal global variables
bw_mult_ml_ and bw_mult_sc_ to help manage
the floating point bitwise functions.
- checkbitwidth_()
-
Internal function: Used to check, before use, that the global
bitwidth variable has not been set to an invalid value.
- and(x,y)
-
Performs a bitwise logical AND of x and y.
At present, does not use base 4 like or() and xor()
so may be slightly slower than these.
- andf(x,y)
-
As above but includes any floating point portion which may be present.
- andm(x,y)
-
'Multiplies' x and y in a no-carry, bitwise manner using logical AND.
This function would return zero all the time but has been tweaked to
return values where possible by starting out with a substrate of 1s.
- andmf(x,y)
-
As above but includes any floating point portion which may be present.
- bitrev(x)
-
Reverse the bits in x. Uses
bitwidth if it is nonzero.
- graycode(x)
-
Convert x into its Gray code equivalent
- graycodef(x)
-
As above but includes any floating point portion which may be present.
NB: Since floating point allows carries of bits over to fractional
bit positions, this function will not necessarily return the same answer
as the above, being greater by 0.5 in those cases
- inverse_graycode(x)
-
Converts Gray encoded x back into its original bit pattern
- inverse_graycodef(x)
-
Floating point inverse Gray code.
All the caveats of the above two functions apply.
- not(x)
-
Perform a bitwise logical NOT of x. Since these functions use twos
complement, this function returns -1-x which has an exactly
flipped bit representation in 2C.
- or(x,y)
-
Perform a bitwise logical OR of x and y.
Uses base 4 internally for faster calculation.
- orf(x,y)
-
As above but includes any floating point portion which may be present.
- orm(x,y)
-
'Multiplies' x and y in a no-carry, bitwise manner using logical OR
in place of addition.
- ormf(x,y)
-
As above but includes any floating point portion which may be present.
- resign(x)
-
Despite an apparently pessimistic name, this actually RE-applies a SIGN to x,
with the assumption that the current
bitwidth is valid. e.g.
if bitwidth is 8, resign(254) is -2. C programmers
will recognise this as effectively casting an unsigned value into a signed
variable of the same size.
- rol(x,n)
-
Roll Left: Familiar to assembly programmers, this shifts x left by n places
within the current
bitwidth and adds the carried left hand bits
back on the right. e.g. 10010011 rolled left by 3 is 10011100
assuming a bitwidth of 8.
- ror(x,n)
-
Roll Right: As above but shifts to the right, placing lost right hand bits
back on the left. May well complain if
bitwidth is 0 (i.e. implied
infinite), as right hand bits would have to be placed in infinite positions.
- shl(x,n)
-
Shift Left: Shifts the bits in x left by n places. Bits carried from the left
hand side are lost if x cannot be kept within the current
bitwidth.
- shr(x,n)
-
Shift Right: Shifts the bits in x right by n places. Bits from the right hand
side are lost
- unsign(x)
-
Interpret a negative number as a positive number within the current
bitwidth. Again, C programmers will recognise this as a cast from
signed to unsigned.
- xor(x,y)
-
Perform a bitwise logical XOR (EXCLUSIVE OR) of x and y.
Uses base 4 internally for faster calculation.
- xorf(x,y)
-
As above but includes any floating point portion which may be present.
- xorm(x,y)
-
'Multiplies' x and y in a no-carry, bitwise manner using logical XOR
in place of addition.
- xormf(x,y)
-
As above but includes any floating point portion which may be present.
- logic-striping.bc
-
A family of functions related to the bitwise functions which may be useful
for encryption and hashing. Then again they might not. See the
text documentation
for more technical information.
These were separated from the main logic.bc due to being of questionable
worth, but were given their own file as they are still interesting functions.
- stripe_(b,x,y)
-
Internal function: Engine for striped_and and striped_or
- striped_and(x,y)
-
Performs a bitwise logical 'STRIPED AND' of x and y
- striped_andf(x,y)
-
As above but includes any floating point portion which may be present.
- striped_andm(x,y)
-
'Multiplies' x and y in a no-carry, bitwise manner using logical
'STRIPED AND' in place of addition.
- striped_andmf(x,y)
-
As above but includes any floating point portion which may be present.
- striped_or(x,y)
-
Performs a bitwise logical 'STRIPED OR' of x and y
- striped_orf(x,y)
-
As above but includes any floating point portion which may be present.
- striped_orm(x,y)
-
'Multiplies' x and y in a no-carry, bitwise manner using logical
'STRIPED OR' in place of addition.
- striped_ormf(x,y)
-
As above but includes any floating point portion which may be present.
- genstripe(override,repeat,x,y)
-
A generalisation of the concept behind 'STRIPED AND' and 'STRIPED OR'
creating an infinite class of related bitwise functions.
- genstripef(o,r,x,y)
-
As above but includes any floating point portion which may be present.
- genstripem(override,repeat,x,y)
-
'Multiplication' as seen many times before here.
- genstripemf(o,r,x,y)
-
As above but includes any floating point déjà vu which may be present.
- outputformatting.bc
-
Powerful formatting tools for GNU bc. Most functions here should have their
return value assigned to a variable, and unless otherwise specified here,
will return the value of the number they were asked to print.
- Bases ≤ 36
- Base 27 (and others) with letters
- Bijective representations
- Fractions
- PrintF (C-like)
- Commas
- Truncation / Rounding
- comma_(x,gp)
-
Internal function: Engine for commaprint.
- commaprint(x,g)
-
Print a x with groups of digits of size g, separated by commas.
e.g. commaprint(1020304,3) prints 1,020,304
- intprint(w, n)
-
Print integer n within a field width of w characters.
- letter_(a) / letter2_(a)
-
Internal functions which print specific letters given particular values of a.
- newline()
-
Prints a newline
- printbase(x)
-
By default bc will use decimal groups for 'digits' when outputting
numbers with
obase set above 16.
When obase ≤ 16, letters are used as digits.
This function outputs using letters right up to base 36 which uses
Z as the one-less-than-base digit. Uses obase, so no base
need be specified as a parameter.
- printbase_letters(x)
-
Similar to the above, but uses the underscore symbol '_' for zero and
the letters A to Z for the digits 1 onwards. This means that it will
only work correctly for bases up to 27, at which point it defers to
the above.
- printbijective(bbase,x)
-
Display x in the
bijective base
specified by bbase. A special format has been devised to show - albeit invalidly
- the fractional part of x. The value of zero is represented by a single dot,
which doubles as the invalidating, bijection-breaking, basimal point.
Note that printbijective(), unlike printbase(), requires the specification of
the output base. bc's own obase, used by printbase(), cannot support
base 1 (unary) whereas this function is perfectly capable, therefore the base
must be specified.
- printbijective_letters(bbase,x)
-
Similar to the above, the letters A to Z for the digits 1 onwards.
This means that it will only work correctly for bases up to 26.
- printdms(x)
-
Treat x as a number of hours and print it in hh:mm:ss format.
- printff(width, precision, n)
-
A function styled after the C syntax:
printf("%*.*f",width,precision,n);
There are some minor differences however:
-
If width is negative, n is aligned to the left hand side of the field
-
If precision is a non-integer, and alignment is set to the right hand
side (i.e. width is positive) leading zeroes will fill the field prior
to n.
-
If precision is set to zero, no decimal point nor fractional part of n
will be displayed.
-
If precision is 0.0 (bc can tell the difference between 0 and 0.0), the
above two features are combined.
- printfe(width, precision, n)
-
A function styled after the C syntax:
printf("%*.*e",width,precision,n);
In addition to having the same features as for printff, above:
-
If precision is negative, the exponent will be set in engineering
notation, i.e. will always be a multiple of 3 (assuming decimal output)
It will, for example, choose to print 123.4e+00 rather than 1.234e+02,
or 56.124e+06 rather than 5.6124e+07. The exponent multiple is
calculated from the current
obase, and so is not always 3.
- printfrac(improper, maxdenom, x)
-
Prints x as the most accurate fraction possible under the restraint of
a maximum denominator. Can choose improper fraction style if required.
Will always choose a/b (proper fraction )style for fractions less than one.
Output can be copy/pasted back into bc as valid syntax. Returns the
value of the fraction printed and not the original value of x.
- printsft(a,b)
-
Prints a and b as an improper fraction in Smallest Fractional Terms.
Requires the GCD function from funcs.bc
- printspc(n)
-
Prints the specified number of spaces.
- printtabs(n)
-
Prints the specified number of tabs.
- trunc(x)
-
Returns x with all trailing zeroes truncated, working around bc's habit
of keeping them stored in the variable. Will also round up trailing
nines (or "base-minus-one"s in other bases). Of course this latter case
means that the return value is not always guaranteed to be equal to x,
but may well have rounded x to the "correct" value.
- pdhi.bc
-
Pan Digital Halving Index; Determine how many times a number must be halved
before it is pandigital. This could quite easily be an offshoot of
digits.bc; Both functions use
ibase
in part to determine pandigitalcy.
- pdhi(x)
-
The eponymous function. Warning: May hang for some values of x
- pdmi(x,m)
-
Pan digital multiplying index: Determine how many times x must be
multiplied by m before it is pandigital.
Warning: May hang for some values of x and m
- primes.bc
-
A mostly naive implementation of prime number handling, with one exception:
Contains a relatively powerful primality checker.
- fac(x)
-
Semi-naively attempt to print the prime factorisation of x
- genprimes(g)
-
Fill the global
primes[] array with the primes up to g.
- has_freedom(x,y)
-
Naively determine whether x is y'th power free. y=2 → squarefree, etc.
- int_modpow(x,y,m)
-
Quickly determine the value of xy mod m for
x, y and m all positive integers.
- int_modpow_(x,y,m)
-
Internal function, used by the above.
- is_perrin_pseudoprime(p)
-
Determine whether p is a
Perrin pseudoprime.
- is_prime(x)
-
A powerful primality checker which combines the pseudoprime tests herein
to determine whether x is extremely probably prime. Probabilistically,
this function should not misidentify any number with less than 300 digits:
If this function returns 0 (not prime), it is assuredly correct.
If it returns 1 (prime) there is a less than 1 in 10300 chance
that it is wrong and the number is actually composite.
- is_prime_td(x)
-
Determine whether p is prime solely using trial division. Uses the Perrin
test as a shortcut, but uses trial division to check. May need years to
run, but is guaranteed to return a right answer.
- is_rabin_miller_pseudoprime(p)
-
Determine whether p is a
Rabin-Miller pseudoprime
.
Performs multiple RM tests, to achieve high certainty of primality.
- is_small_division_pseudoprime(x)
-
Confirms that x is indivisible by a significant number of small primes
- prevprime(n)
-
Returns the nearest prime < n; Relies on the
is_prime() function
when searching for candidates, so may take a while to find an answer.
- primorial(n)
-
Returns the primorial of all primes ≤ n
- nextprime(n)
-
Returns the nearest prime > n; Relies on the
is_prime() function
when searching for candidates, so may take a while to find an answer.
- primes-other.bc
-
The chaff of interesting but unnecessary functions that would otherwise be
included in the above. Also, all functions here require funcs.bc
in order to run.
- aprimepi(x)
-
An approximation to the prime counting function, π(x);
Gives an estimate of the number of primes ≤ x
- aq(x)
-
A Questionable (prime): Turns x into either 2, 3 or base 6 pseudoprime.
All primes are of form 2, 3 or 6n±1 for some integer n.
- iaq(x)
-
Inverse of the above; Guaranteed to return a unique value for every prime x.
- aq30(x)
-
A Questionable (prime; base) 30: Turns x into 2, 3, 5 or a base 30 pseudoprime.
All primes are of form 2, 3, 5 or 30n±{1,7,11,13}
for some integer n.
- iaq30(x)
-
Inverse of the above; Guaranteed to return a unique value for every prime x.
- rand.bc
-
A floating-point based random number generator. Since bc has no method of
obtaining an initial seed, use of randbc
is highly recommended. For a sample guessing game which uses this library
see guess.bci
- rand(x)
-
For values of x < 0, this will call the srand function with -x as a parameter.
For values of x < 1, will return the previous random number, i.e. the same as
the last time the function was called. This is 0 if not previously called.
If x is exactly 1, will return a random floating point number between zero and
one (non-inclusive), with as many decimals as the current scale.
For integer values of x > 1, will return an integer between 1 and x.
If x has a floating point portion, this will return an integer between 1 and
x+1, with a bias such that floor(x)+1 occurs with the frequency of the
fractional part of x.
- srand(x)
-
Resets the internal random seed based on the value of x
- srr.bc
-
The Sum of Repeated Roots function
The mathematical formula for this interesting function is:
Or as simply as possible: srr(x) = sum[n=1..oo] x^(2^(-n))-1
- srr(x)
-
The function as described above.
- srr_n(n,x)
-
A generalisation of srr, which uses the nth root rather than the square root.
srr_n(2,x) is equivalent to srr(x)
- thermometer.bc
-
Temperature scale conversions amongst the five most common scales.
- Celcius / centigrade
- Farenheit
- Rankin
- Réamur
- Kelvin
- kelvin_to_celcius(k)
- kelvin_to_farenheit(k)
- kelvin_to_rankine(k)
- kelvin_to_reamur(k)
- reamur_to_celcius(r)
- reamur_to_farenheit(r)
- reamur_to_kelvin(r)
- reamur_to_rankine(r)
- celcius_to_farenheit(c)
- celcius_to_kelvin(c)
- celcius_to_rankine(c)
- celcius_to_reamur(c)
- rankine_to_celcius(r)
- rankine_to_farenheit(r)
- rankine_to_kelvin(r)
- rankine_to_reamur(r)
- farenheit_to_celcius(f)
- farenheit_to_kelvin(f)
- farenheit_to_rankine(f)
- farenheit_to_reamur(f)
- These functions are - hopefully - self explanatory.
General Notes
More information here as and when I think of it...
Disclaimer
Being something of a maths geek, not necessarily on a par with anyone famous or
actually intelligent, these files have been created mainly for the fun of it, and
also in the hope that someone finds them useful. They have been cobbled together
over the years on a sporadic basis. Checks have been made to some degree or another
to make sure they work in some fairly unusual conditions, including where
scale is set to 0 or where ibase - which affects the
interpretation bc code(!) - has been set to a value other than ten (I would type '10'
here, but '10' is the representation of the value of the current number base,
whichever base that might be; ten, twelve, sixteen, four hundred and thirty-seven,
etc. you see my point.), as well as a reasonable amount of sanity testing.
Before putting this page live, I removed as many bugs as I could find, and hopefully
provided enough warnings in the above information and the comments in the files
themselves about where unusually loose approximations might come about. That said:
I accept no responsibility for any incorrect calculations or otherwise unexpected
behaviour, including the consequences thereof, that result(s) from errors that may
still exist in these files, whether that be during what would be considered to be
sensible use - as part of an interactive bc session, included along with user-written
bc code as part of a larger project, etc. - or during any misuse to which they may
be put.
Furthermore, I reserve the right to change, update or add to these files at any time,
without prior notification, as I see fit.
If you use these files and find an error, bug, SNAFU, typo or anything else that
makes the function you're trying to use behave strangely or just plain wrong,
let me know
and I'll look into fixing the problem. If you have code suggestions or bug fixes or
even questions about bc, feel free to
drop me a line.
-- phodd