Files
bc/index.html
2016-04-22 12:14:22 -04:00

3439 lines
198 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head><title>
:: phodd.net :: GNU bc programming ::
</title>
<xlink rel="shortcut icon" href="../favicon.ico"></xlink>
<link rel="stylesheet" href="./bc.css"></link>
<script src="./addlinks.js"></script>
</head>
<body>
<div id="watermark"></div>
<a id="go-home" href="/"></a>
<h1>
GNU bc
</h1>
<p>
GNU bc is a fairly ubiquitous, useful and powerful calculator that few people seem to
know much about or do anything interesting with.
</p><p>
It can be found on most versions of Linux and BSD, and there are at least two
versions available for Windows: As a
<a href="http://gnuwin32.sourceforge.net/packages/bc.htm">standalone executable</a>
and also available as part of <a href="http://www.cygwin.com">Cygwin</a>.
</p>
<div id="toc">
<ul>
<li> <a href="#toc_about">About this page</a> </li>
<li>
<a href="#toc_files">Files, Keywords and Functions</a>
<ul>
<li> <a href="#toc_before">Before we begin...</a> </li>
<li> <a href="#toc_sites">... some other sites of interest</a> </li>
<li> <a href="#toc_style">Some style notes</a> </li>
<li> <a href="#toc_howuse">How to use these files</a> </li>
<li> <a href="#toc_archive">Archive of all files</a> </li>
<li> <a href="#toc_fastnav">Directory of functions and functionality</a> </li>
</ul>
</li>
<li> <a href="#toc_notes">General Notes</a> </li>
<li>
<a href="#toc_dclaim">Disclaimer</a>
<ul>
<li> <a href="#toc_contact">Contact</a> </li>
</ul>
</li>
</ul>
</div>
<h2> <a name="toc_about"></a> About this page </h2>
<p>
This page exists to raise the profile of bc, to supply pre-written code for performing
precision calculations (for the most part at any rate) and investigation into various
areas of mathematics, as well as being an ongoing hobby project where I show off my
coding and mathematical talents... or disappointing lack thereof.
</p><p>
Each of the scripts / files / programs / libraries
- whatever you wish to call them -
contain sizeable comments explaining exactly what the file is, what it does and
what each of the functions do. This is not the best way of providing documentation,
but the expectation is that people should use and learn from these files, and so putting
some documentation in with the code is good first step.
</p><p>
Below you will find slightly better documentation than in the file comments, and perhaps
the occasional example, but I admit that this isn't ideal; There is the intention to
set up a wiki or a forum, since there's over 250kB of bc code here; Watch this space.
</p><p>
A <a href="../cyrek/gnu-bc/index.old.php">forerunner</a> to this page was linked
from the bc articles in both the
<a href="http://en.wikipedia.org">English</a>,
<a href="http://de.wikipedia.org">German</a> and
<a href="http://jp.wikipedia.org">Japanese</a>
Wikipedias. Welcome, <em>Wilkommen</em> and <em>Irasshai</em> to readers heading in
from those places!
</p>
<ul id="attention">
<li> If you found this page through an internet search and can't see what you are
looking for, check out the <a href="#toc">contents box</a> or keep scrolling down.
<em>This page has grown very long and even then some parts are hidden* until they
are activated.</em>
<p class="subnote">
* If you have Javascript disabled, or you're a search engine, everything is visible by
default. This not only allows search engines to classify the page, it allows text-only
HTML renderers like <code>links</code>, <code>lynx</code>, <code>curl</code> and
<code>wget</code> to read the page directly from a terminal - the spiritual home of bc.
</p>
<li> Alternatively try the <a href="./bcfaq.html"> bc FAQ</a> page - you might find
what you are looking for there!
</ul>
<h2> <a name="toc_files"></a> Files, Keywords and Functions</h2>
<p>
The files linked here contain well over 500 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.
</p>
<h3> <a name="toc_before"></a> Before we begin... </h3>
<p>
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
<a href="http://www.gnu.org/software/bc/manual/html_mono/bc.html">official GNU-bc manual</a>
is well worth a read.
</p>
<h3> <a name="toc_sites"></a> ...some other sites of interest </h3>
<p>
Very occasionally I run across other sites with GNU bc code available for download.
So far there are only three in this list, but if you know of a site, or have your own
and would like to be listed here,
<a href='mailto:gnu-bc[change this to an at sign]phodd[change this to a dot]net?subject=GNU bc link exchange: [more detail here]'>let me know</a>.
</p>
<dl>
<dt> <a href="http://www.numbertheory.org/gnubc/gnubc.html"> BC Number Theory programs</a> <dd>
The programs found here have some overlap with <a href="#funcs">funcs.bc</a>,
<a href="#primes">primes.bc</a> and <a href="#cf">cf.bc</a>, although the latter
pale in comparison. In short, if you're doing number theory in bc, the above is the
place to look if I don't have what you need.
<dt> <a href="http://x-bc.sourceforge.net">X-bc</a> <dd>
Provides a graphical interface to bc on X-Window supporting platforms,
as well as providing various extra functions, many of which are equivalent
to ones found here. <em>Disclaimer: X-bc appears to have not been updated
since 2003, and I have not used the graphical interface myself.</em>
<dt>
<a href="http://marcmmw.freeshell.org/esp/programacion/bc.html">
C&aacute;lculo num&eacute;rico con bc
</a>
<dd>
Marc Mel&eacute;ndez Schofield's Spanish language gnu-bc page has many things
similar to those found on this site, as well as a few things that aren't.
For example, the site serves as a tutorial to help those new to bc, and
there are some innovative ideas, such as using bc to generate PPM images
(supported by many graphics packages) as output, which makes this site's
<a href="#output_graph">output_graph.bc</a> look like a toy in comparison.
</dl>
<h3> <a name="toc_style"></a> Some style notes </h3>
<p>
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:
</p>
<ul>
<li>
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. <a href="#output_graph">output_graph.bc</a> contains a function called <code>or_</code>
which performs a bitwise OR, but is much more simplified than the version found
in <a href="#logic">logic.bc</a>.
</li>
<li>
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
<a href="#output_formatting">output_formatting.bc</a>
for an example.
</li>
<li>
Functions whose names begin with <code>int_</code> 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 <code>remainder</code> and
<code>int_remainder</code> which are found in <a href="#funcs">funcs.bc</a>.
<li>
Functions whose names begin with <code>is_</code> determine truth or falsity
and return 1 for true and 0 for false. Many examples of this can be found in
<a href="#digits">digits.bc</a>.
<li>
Functions whose names begin with <code>fast</code> are fast but return
highly approximate results. Often there is an equivalent function lacking the
'fast' in the name which provides better - though not guaranteed perfect -
results, all for the price of a little extra time.
<li>
Many functions contain the construct
<code> os=scale; scale=0; /* do something */; scale=os </code>
. This saves the built-in <code>scale</code> 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
<code>os</code>, an abbreviation of "old scale" so as not to interfere with
other functions and any interactive session that might be under way.
</li>
<li>
Fairly often in the code, the constant <code>A</code> 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
<code>ibase</code> variable. Much of bc is designed with base ten in mind,
especially the aforementioned <code>scale</code> variable, which designates
precision in <em>decimal</em> places. Use of <code>A</code> guarantees that
the value obtained is indeed ten and not some other value.
</li>
</ul>
<h3> <a name="toc_howuse"></a> How to use these files </h3>
<p>
You're a busy person, and perhaps as a result you've not had time to read the
<a href="http://www.gnu.org/software/bc/manual/html_mono/bc.html">official GNU-bc manual</a>.
That's understandable. All you need to do is create a directory on your computer which
contains the file or files you'd like to use
- put your own code in there along with them if necessary -
open a command or shell window on that directory (or cd to it) then type the command
</p><blockquote><code>
/path/to/bc -l file1.bc file2.bc file3.bc </code><em>... etc.</em>
</blockquote><p>
Of course, you'll need to use the right path to the bc executable and exchange file1,
file2 and so on for actual .bc filenames. You could also put the path to the bc executable
into your shell's <code>PATH</code> variable, removing the need to type the path, but
system configuration help is outside the scope of this page.
</p><p>
Personally, I keep all my bc files in the same folder, and since my system is set up with
the aforementioned <code>PATH</code> entry, all I need type is:
</p><blockquote><code>
bc -l *.bc
</code></blockquote><p>
...and bc launches with all my functions ready to use.
</p><p>
<em>For reasons that are not entirely clear, sometimes loading files in a particular order
will cause the bc interpreter to crash with an error, despite no error existing in any one
file of the loading code. This then means that the above trick does not work.
</em>
</p><p>
<em>To work around this, loading the files in a different order, or even loading some files
more than once (!) will prevent the error from happening, for example:
</em>
</p><blockquote><code>
bc -l [a-oq-z]*.bc p*.bc
</code></blockquote><p>
<em>... which loads the files in alphabetical order, skipping all files beginning with p,
only to load them last, may well work when the previous example does not.
</em>
</p><p>
Filenames here have underscores in them so that, due to ASCII ordering, parent files
load before their similarly named children when using the <code>*.bc</code> shortcut.
</p><p>
You can also take advantage of bc's standard input acceptance and perform tricks like:
</p><blockquote><code style='white-space: nowrap'>
echo '.=divisors_store(a[],2520)+asort0(a[])+aprint0(a[])' | bc -l primes.bc array.bc
</code></blockquote><p>
Which, if you have those two files in particular, should spit out:
</p><blockquote><code>
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 18, 20, 21, 24, 28, 30, \<br />
35, 36, 40, 42, 45, 56, 60, 63, 70, 72, 84, 90, 105, 120, 126, 140, \<br />
168, 180, 210, 252, 280, 315, 360, 420, 504, 630, 840, 1260, 2520}
</code></blockquote><p>
The above example also goes to show some of the power of the functions which can be
found on this page.
</p>
<h3> <a name="toc_archive"></a> Archive of all files </h3>
<p>
For the lazy and/or curious, most of the files below can be downloaded in one ZIP
archive:
</p>
<ul>
<li style="font-weight: bold;">
Recommended download of this site and code:<br />&nbsp;&nbsp;
<a href="./phodd.net-gnu-bc-201302202200+html.zip">
phodd.net-gnu-bc-201302202200+html.zip</a>
(172kB)
</li>
<li>
Everything including the large prime database files:<br />&nbsp;&nbsp;
<a href="./phodd.net-gnu-bc-201302202200+pdb+html.zip">
phodd.net-gnu-bc-201302202200+pdb+html.zip</a>
(8575kB)
</li>
</ul>
<p>
This filename should update whenever a change is made to one or more of the
files below.
</p>
<h3> <a name="toc_fastnav"></a> Directory of functions and functionality </h3>
<p>
<strong>Update, February 2013:</strong> Removal of some bugs introduced in the
last update as well as some minor speed improvements and modified algorithms.
More new functions and some new files.
</p>
<div id="fastnav">
<h4> Quick navigation to main sections </h4>
<ul>
<li> <a href="#array">array.bc</a> - Advanced array handling </li>
<li> <a href="#cf">cf.bc</a> - Continued fractions </li>
<li> <a href="#collatz">collatz.bc</a> - Collatz conjecture </li>
<li> <a href="#complex">complex.bc</a> - Complex numbers </li>
<li> <a href="#digits">digits.bc</a> - Digital manipulation </li>
<li> <a href="#factorial">factorial.bc</a> - Factorials / Gamma function</li>
<li> <a href="#funcs">funcs.bc</a> - Main functions library </li>
<li> <a href="#intdiff">intdiff.bc</a> - Numerical calculus </li>
<li> <a href="#interest">interest.bc</a> - Compound interest </li>
<li> <a href="#logic">logic.bc</a> - Bitwise / Digitwise logic </li>
<li> <a href="#melancholy">melancholy.bc</a> - Melancholy numbers </li>
<li> <a href="#output_formatting">output_formatting.bc</a> - Printing to screen </li>
<li> <a href="#primes">primes.bc</a> - Prime numbers / Number theory</li>
<li> <a href="#rand">rand.bc</a> - Random numbers </li>
<li> <a href="#thermometer">thermometer.bc</a> - Temperature conversion </li>
</ul>
</div>
<dl class="allfiles">
<!-- ==================== A ==================== -->
<dt class="filename"><a title="download file" name="array" href="./code/array.bc">array.bc</a><dd>
<strong> Updated for February 2013 </strong><br />
A large number of functions for managing different array formats in bc.
<em><strong> This file uses the undocumented <nobr>pass-by-reference</nobr> feature for
arrays </strong></em>.
<ul class="keywords">
<li> Comparison
<li> Reversal
<li> Searching
<li> Sorting
<li> Unique values
<li> Run-length counting
<li> Format conversion
</ul>
<p>
Function names have various suffixes or none at all for dealing with many
different array formats:
</p>
<ul>
<li> Without a suffix, the function expects a count of items to work upon.
<li> A suffix of <code>0</code> suggests the function expects zero-terminated arrays.
<li> <code>r</code> and <code>2r</code> indicate that a range or ranges of items are to be given.
<li> <code>b</code> functions expect to be given an end-of-array terminator (which may or may not be zero).
<li> <code>l</code> functions expect that the arrays contain their length as the first element.
</ul>
<dl class="functions">
<dt> aequals(a__[],b__[],count) <dd>
Boolean function; Returns whether the two arrays are equal for the
number of entries specified by <code>count</code>.
<dt> aequals0(a__[],b__[]) <dd>
Boolean function; Returns whether two zero-terminated arrays are equal
<dt> aequals2r(a__[],astart,aend,b__[],bstart,bend) <dd>
Boolean function; Returns whether the specified ranges of the two arrays are equal
<dt> aequalsb(a__[],b__[],x) <dd>
Boolean function; Returns whether two arrays, terminated by <code>x</code> are equal.
When <code>x</code> is 0, this is equivalent to <code>aequals0()</code>.
<dt> aequalsl(a__[],b__[]) <dd>
Boolean function; Returns whether two arrays, whose lengths are specified as the
first element of the array, are equal.
<dt> aequalsr(a__[],b__[],start,end) <dd>
Boolean function; Returns whether two arrays are equal for the given range of elements.
<dt> aappend(*a__[],aend,b__[],count) <dd>
Appends <code>count</code> elements of the second array to the first.
Note that the index of the end of the first array must be specified.
<dt> aappend0(*a__[],b__[]) <dd>
Appends the contents of the second array to the first.
Both arrays are treated as zero-terminated. Zero-termination is maintained.
<dt> aappendb(*a__[],b__[],x) <dd>
Appends the contents of the second array to the first.
Both arrays are expected to be terminated by whatever is specified by <code>x</code>.
<dt> aappendl(*a__[],b__[]) <dd>
Appends the contents of the second array to the first.
Both arrays should have their length as their first element
<dt> aappendr(*a__[],aend,b__[],bstart,bend) <dd>
Appends the contents of the given range of the second array to the first array.
Note that the index of the end of the first array must be specified.
<dt> aappendelem(*a__[],aend,e) <dd>
Appends a single element, that is, a number to the end of an array.
<dt> aappendelem0(*a__[],e) <dd>
Appends a single element to the end of a zero-terminated array. Zero-termination is maintained.
<dt> aappendelemb(*a__[],x,e) <dd>
Appends a single element to the end of an <code>x</code>-terminated array.
<dt> aappendeleml(*a__[],e) <dd>
Appends a single element to the end of an array which knows its own length.
<dt> acompare(a__[],b__[],count) <dd>
<dt> acompare0(a__[],b__[]) <dd>
<dt> acompare2r(a__[],astart,aend,b__[],bstart,bend) <dd>
<dt> acompareb(a__[],b__[],x) <dd>
<dt> acomparel(a__[],b__[]) <dd>
<dt> acomparer(a__[],b__[],start,end) <dd>
Comparison functions; Return -1 if the first array is logically before the second
in lexographic order, 0 if they are equal and 1 otherwise. Behaviour and parameters
are as for the <code>aequal...()</code> functions.
<dt> aconv0fromr(*a__[], b__[],start,end) <dd>
Conversion function; Creates zero-terminated array a from the specified range
of array b.
<dt> aconvbfromr(*a__[],x,b__[],start,end) <dd>
Conversion function; Creates array a, terminated by x, from the specified range
of array b.
<dt> aconvlfromr(*a__[], b__[],start,end) <dd>
Conversion function; Creates an array whose length is the first element, a, from
the specified range of array b.
<dt> aconvrfrom0(*a__[],start,end,b__[]) <dd>
Conversion function; Sets the specified range of array a with the values from the
zero-terminated array, b.
<dt> aconvbfrom0(*a__[],x, b__[]) <dd>
Conversion function; Sets the specified range of array a with the values from the
array b, which is terminated by the value specified by x.
<dt> aconvlfrom0(*a__[], b__[]) <dd>
Conversion function; Creates an array whose length is the first element, a, using
the values from zero-terminated array, b.
<dt> aconv0fromb(*a__[], b__[],x) <dd>
Conversion function; Creates zero-terminated array a from the values of the
array b, which is terminated by the value specified by x.
<dt> aconvrfroml(*a__[],start,end,b__[]) <dd>
Conversion function; Sets the specified range of array a with the values from
the array b, whose length is specified by its first element.
<dt> aconv0froml(*a__[], b__[]) <dd>
Conversion function; Creates zero-terminated array a from the values of the
array b, whose length is specified by its first element.
<dt> aconvbfroml(*a__[],x, b__[]) <dd>
Conversion function; Creates array a, which is terminated by the value in x,
from the values of the array b, whose length is specified by its first element.
<dt> acopy(*a__[],b__[],count) <dd>
Overwrites the first array with <code>count</code> elements from the second.
<dt> acopy0(*a__[],b__[]) <dd>
Turns the first array into a clone of the second, assuming both are zero-terminated arrays.
<dt> acopy2r(*a__[],astart,aend,b__[],bstart,bend) <dd>
Overwrites the specified range of the first array with the specified range of the second.
<dt> acopyb(*a__[],b__[],x) <dd>
Turns the first array into a clone of the second, assuming both are <code>x</code>-terminated arrays.
<dt> acopyl(*a__[],b__[]) <dd>
Turns the first array into a clone of the second, assuming the second array contains the length
as its first element.
<dt> acopyr(*a__[],b__[],start,end) <dd>
Overwrites those elements first array with elements of the second which are specified by the given range.
<dt> ainsertat(*a__[],acount,pos,b__[],bcount) <dd>
Experimental. Inserts elements of the second array into the first, where both array's
lengths are specified in the <code>?count</code> parameters, and the <code>pos</code>ition
within the first is given.
<dt> ainsertat0(*a__[],pos,b__[]) <dd>
Experimental. Inserts the contents of the second array into the first at the given <code>pos</code>ition.
Both arrays are expected to be zero-terminated.
<dt> ainsertatb(*a__[],pos,b__[],x) <dd>
Experimental. As above, only the array terminator is specified by <code>x</code>.
<dt> ainsertatl(*a__[],pos,b__[]) <dd>
Experimental. Inserts the contents of the second array into the first at the given <code>pos</code>ition.
Both arrays should have their length stored as their first element.
<dt> ainsertatr(*a__[],astart,aend,pos,b__[],bstart,bend) <dd>
Experimental. Inserts the specified range of the second array at the given <code>pos</code>ition
within the specified range of the first.
<dt> ainsertelemat(*a__[],count,pos,e) <dd>
Experimental. Inserts a single number into an array of length <code>count</code>
at the given <code>pos</code>ition.
<dt> ainsertelemat0(*a__[],pos,e) <dd>
Experimental: Inserts a single number into a zero-terminated array
at the given <code>pos</code>ition.
<dt> ainsertelematb(*a__[],x,pos,e) <dd>
Experimental: Inserts a single number into an <code>x</code>-terminated array
at the given <code>pos</code>ition.
<dt> ainsertelematl(*a__[],pos,e) <dd>
Experimental: Inserts a single number into an array at the given <code>pos</code>ition.
The array will contain its length as its first element.
<dt> ainsertelematr(*a__[],start,end,pos,e) <dd>
Experimental: Inserts a single number at the given <code>pos</code>ition within the specified
range of the array.
<dt> amatcharray(small__[],scount,large__[],lcount) <dd>
Returns the position, if present, of the smaller array within the larger.
Array lengths are specified in the <code>?count</code> parameters.
<dt> amatcharray0(small__[],large__[]) <dd>
Returns the position, if present, of the smaller array within the larger.
Both arrays assumed to be zero-terminated.
<dt> amatcharray2r(small__[],astart,aend,large__[],bstart,bend) <dd>
Returns the position, if present, of the given range of the smaller array
within the given range of the larger.
<dt> amatcharrayb(small__[],large__[],x) <dd>
Returns the position, if present, of the smaller array within the larger.
Both arrays assumed to be <code>x</code>-terminated.
<dt> amatcharrayl(small__[],large__[]) <dd>
Returns the position, if present, of the smaller array within the larger.
Both arrays assumed to have their length as their first element.
<dt> amatchelement(e,a__[],count) <dd>
Returns the position, if present, of a number within an array.
Array length is specified by the <code>count</code> parameter.
<dt> amatchelement0(e,a__[]) <dd>
Returns the position, if present, of a number within a zero-terminated array.
<dt> amatchelementb(e,a__[],x) <dd>
Returns the position, if present, of a number within an <code>x</code>-terminated array.
<dt> amatchelementl(e,a__[]) <dd>
Returns the position, if present, of a number within an array whose length is stored as
the first element.
<dt> amatchelementr(e,a__[],start,end) <dd>
Returns the position, if present, of a number within the given range of an array.
<dt> aparts3r(*a__[],astart,aend,b__[],bstart,bend,c__[],cstart,cend) <dd>
Overwrites the first array with the given ranges of itself and two further arrays,
either of which may also be the original array.
<dt> aprint(*a__[],count) <dd>
Prints the first <code>count</code> elements of an array.
<dt> aprint0(*a__[]) <dd>
Prints all elements of an array up to, but not including, the first zero
(zero-terminated array).
<dt> aprintb(*a__[],x) <dd>
Prints all elements of an array up to, but not including, the first instance of <code>x</code>.
<dt> aprintl(*a__[]) <dd>
Prints all elements (but not the length itself) of an array whose length is stored as its first element.
<dt> aprintr(*a__[],start,end) <dd>
Prints the given range of an array.
<dt> aprintu(*a__[],x) <dd>
Prints all elements of an array up to <em>and including</em> the first instance of <code>x</code>.
Useful for showing the terminator on terminated arrays. <code>x</code> can, of course, be zero.
<dt> areverse(*a__[],n) <dd>
Reverse the first <code>n</code> elements of an array.
<dt> areverse0(*a__[]) <dd>
Reverse a zero-terminated array.
<dt> areverseb(*a__[],x) <dd>
Reverse an <code>x</code>-terminated array.
<dt> areversel(*a__[]) <dd>
Reverse an array whose length is stored in its first element.
<dt> areverser(*a__[],start,end) <dd>
Reverse the given range of an array.
<dt> arunlength(*v__[],*r__[], a__[], n) <dd>
Fills the first array with the <code>v</code>alues from the first <code>n</code> values
of the third, filling the second array with an associated count (<code>r</code>un-length)
of consecutive values. Returns the length of the first two arrays (which is necessarily
the same number). Note that this will be less than or equal to <code>n</code>.
<em> Works best on a sorted array </em>
<dt> arunlength0(*v__[],*r__[], a__[]) <dd>
Fills the first array with the <code>v</code>alues from the third array, which is
zero-terminated. The second array is filled with the associated count (<code>r</code>un-length)
of consecutive values. Both of the first two arrays are then zero-terminated like the third.
Returns the number of elements in these arrays (before the terminator).
<em> Works best on a sorted array </em>
<dt> arunlengthb(*v__[],*r__[], a__[],x) <dd>
Fills the first array with the <code>v</code>alues from the third array, which is
terminated by the value given in <code>x</code>. The second array is filled with the
associated count (<code>r</code>un-length) of consecutive values.
Both of the first two arrays are then terminated like the third.
Returns the number of elements in these arrays (before the terminator).
<em> Works best on a sorted array </em>
<dt> arunlengthl(*v__[],*r__[], a__[]) <dd>
Fills the first array with the <code>v</code>alues from the third array, whose length is
given in its first element. The second array is filled with the associated count
(<code>r</code>un-length) of consecutive values.
Both of the first two arrays are set to be in the same format as the third, having their
length as their first element.
Returns the number of elements in these arrays, which is the same as the aforementioned length.
<em> Works best on a sorted array </em>
<dt> arunlengthr(*v__[],*r__[], a__[],start,end) <dd>
Fills the first array with the <code>v</code>alues from the values found in the third array
between the <code>start</code> and <code>end</code> indexes inclusive. The second array is filled with the associated count (<code>r</code>un-length) of consecutive values.
Returns the length of the first two arrays.
<em> Works best on a sorted array </em>
<dt> asanerange_(), asanerange2_() <dd>
Internal function for checking and repairing the sanity of ranges in functions
that use them.
<dt> aset8(*a__[],start,a,b,c,d,e,f,g,h) <dd>
<dt> aset16(*a__[],start,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) <dd>
Since bc has no means of assigning to an array quickly, these functions allow the
setting of 8 or 16 elements of an array in a single function call.
The start parameter is the location that the first parameter will be set;
The rest will then be assigned to subsequent elements.
<dt> asort(*a__[],n) <dd>
Sort the first <code>n</code> elements of an array.
The sorting algorithm is a fast, non-recursive, run-finding mergesort.
<dt> asort0(*a__[]) <dd>
Sort all elements of an array up to, but not including, the first zero (zero-terminated array).
<dt> asortb(*a__[],x) <dd>
Sort all elements of an array up to, but not including, the first instance of <code>x</code>.
<dt> asortl(*a__[]) <dd>
Sort all elements of an array whose length is stored as its first element.
<dt> asortr(*a__[],start,end) <dd>
Sort the given range of an array.
<dt> asortr_old(*a__[],start,end) <dd>
An older version of the above which implements a recursive, non-run-finding mergesort.
It is slower than the main <code>asort...()</code> functions but was used as a benchmark
and known-correct test platform during the creation of the faster algorithm.
<dt> auniq(*v__[], a__[],n) <dd>
Fills the first array with the <code>v</code>alues from the first <code>n</code> values
of the second array, removing any adjacent duplicate values. Returns the number of items in the
first array. Note that this will be less than or equal to <code>n</code>.
<em> Works best on a sorted array </em>
<dt> auniq0(*v__[], a__[]) <dd>
Fills the first array with the <code>v</code>alues from the second array, which is
zero-terminated, removing any adjacent duplicate values. The first array is then terminated
with a zero.
Returns the number of items in the first array.
<em> Works best on a sorted array </em>
<dt> auniqb(*v__[], a__[],x) <dd>
Fills the first array with the <code>v</code>alues from the second array, which is
terminated by the value given in <code>x</code>, removing any adjacent duplicate values.
The first array is then terminated with the same terminator value.
Returns the number of items in the first array.
<em> Works best on a sorted array </em>
<dt> auniql(*v__[], a__[]) <dd>
Fills the first array with the <code>v</code>alues from the second array, whose length is
given in its first element.
The first array is then set to be in the same format as the second, having its
length as its first element.
Returns the number of elements in the first array, which is the same as the aforementioned
length.
<em> Works best on a sorted array </em>
<dt> auniqr(*v__[], a__[],start,end) <dd>
Fills the first array with the <code>v</code>alues from the values found in the second array
between the <code>start</code> and <code>end</code> indexes inclusive.
Returns the number of elements in the first array.
<em> Works best on a sorted array </em>
</dl>
<!-- ==================== B ==================== -->
<!-- ==================== C ==================== -->
<dt class="filename"><a title="download file" name="cf" href="./code/cf.bc">cf.bc</a><dd>
<strong> Rewritten for June 2012 </strong><br />
A suite of functions for basic continued fraction analysis. Uses the
undocumented pass-by-reference feature of arrays where necessary.
<ul class="keywords">
<li> Continued fractions
<li> Rational approximation
<li> Upscale / increase rational number accuracy
</ul>
<dl class="functions">
<dt> cf_new_(near) <dd>
Internal function; Main engine for creating continued fractions.
Used by the below.
<dt> cf_tidy_() <dd>
Internal function; Main finalisation routine for tidying up after
<code>cf_new_()</code> and others
<dt> cf_new(*cf__[],x) <dd>
Puts the continued fraction of x into the given array. For positive x,
terms are always positive.
<dt> cfn_new(*cf__[],x) <dd>
Puts a better approximation continued fraction of x into the given
array. Terms are positive or negative, depending on which of these
obtains a closer approximation to x at each step. In this library,
this form of continued fraction is referred to as a CFN
(Continued Fraction Nearer).
<dt> cf_copy(*cfnew__[],cf__[]) <dd>
Make a copy of the right hand array in the left, with respect to the
storage rules used by this library. Some metadata may be stored in the
CF arrays which ordinary array copies may lose.
<dt> cf_toggle(*cf__[],cf2__[]) <dd>
Converts one type of CF into the other, i.e. CF into CFN and
vice-versa, or in other words, converts the type of array created by
<code>cf_new()</code> into the type of array created by
<code>cfn_new()</code>. <em> Warning: Some accuracy may be lost. </em>
<dt> cf_value(cf__[]) <dd>
Convert the continued fraction in the given array into a number
<dt> frac_from_cf(*f__[],cf__[],improper) <dd>
Fills the array <code>f</code> with the denominator and numerator
(in that unusual order) as element 0 and element 1. If the
<code>improper</code> flag is zero then element 2 of
the array is set to be the integer part. e.g. the array would contain
<code>{2,1,5}</code> if the specified continued fraction contained a
representation of 5<sup>1</sup>/<sub>2</sub>.
<dt> cf_get_convergent(cf__[],c) <dd>
Returns the <i>c</i>-th convergent of the given continued fraction.
e.g. if the continued fraction array contains a representation of an
irrational number, these convergents will represent particular
approximations to that number.
<dt> get_convergent(x,c) <dd>
Finds the <i>c</i>-th convergent of the number <i>x</i>.
This bypasses the need to generate a continued fraction array, but
therefore can have the consequence of having to recalculate the
continued fraction of <i>x</i> every time this function is called.
<dt> upscale_rational(x) <dd>
If <i>x</i> contains a rational value that was calculated with a less
accurate <code>scale</code>, this function attempts to bring that
value to full accuracy in the current <code>scale</code>.
<dt> cf_print(cf__[]) <dd>
Displays the contents of the given array in continued fraction style.
When the array contains what appears to be a representation of a
quadratic irrational, will insert semicolons rather than commas after
the pattern repeats, or before any pattern begins for the first time.
If the global variable <code>cf_shortsurd_</code> is set to non-zero
this function will truncate the output of the aforementioned
quadratic irrationals at the end of the first occurrence of the
otherwise repeating pattern.
<br />
<em>NB: Quadratic irrational detection
is not done directly by this function, and metadata will need to be
added to third-party arrays for this to work. This library adds its
own metadata when putting continued fractions into arrays.</em>
<br />
Will display an ellipsis at the end of the output if the CF is
believed to be of infinite length (or at least of length beyond
the current accuracy as set by <code>scale</code>).
<dt> cf_print_convergent(cf__[],c) <dd>
Prints a fraction representing the <i>c</i>-th convergent of the
given array. If <i>c</i> is negative, will print <em>all</em>
convergents upto and including the <i>c</i>-th.
<dt> cf_print_frac(cf__[],improper) <dd>
Prints a fraction representing the value of the continued fraction
stored in the given array. When the <code>improper</code> flag is
non-zero, the value displayed will, where necessary, take the form
of a 'top-heavy' or improper fraction.
<dt> print_as_cf(x) <dd>
Print <i>x</i> as a continued fraction. This saves on creating an
intermediate array if only this one output is required. Consider
using other functions if other work on the continued fraction
of <i>x</i> is required.
<dt> print_as_cfn(x) <dd>
As above, but using the CFN 'nearest sign' continued fraction format.
<dt> print_convergent(x,c) <dd>
Prints the <i>c</i>-th approximation to the value of x as a rational
number or fraction If <i>c</i> is negative, prints all approximations
up to the <i>c</i>-th.
<dt> print_frac(x,improper) <dd>
Displays x as a fraction (rational number). As in other functions
the <code>improper</code> flag specifies whether the number is to
be an improper fraction or not.
<dt> print_frac2(x,improper) <dd>
As above, but interally uses a CFN. This has the interesting
side-effect of causing proper fractions with integer parts and
a fractional part greater than <sup>1</sup>/<sub>2</sub> to be
displayed with positive integer part and negative fractional part.
e.g. 1 <sup>2</sup>/<sub>3</sub> would display as
2-<sup>1</sup>/<sub>3</sub>.
</dl>
<dt class="filename"><a title="download file" name="cf_engel" href="./code/cf_engel.bc">cf_engel.bc</a><dd>
<strong> New for June 2012 </strong><br />
Functions for generating, printing and interpreting
<a href="http://en.wikipedia.org/wiki/Engel_expansion">
Engel Expansions</a>
in a similar manner to ordinary continued fractions.
Sister library to <a href="cf_sylvester">cf_sylvester.bc</a>
<ul class="keywords">
<li> Engel Expansions
<li> Infinite Egyptian Fraction
</ul>
<dl class="functions">
<dt> engel_new_(mode) <dd>
Internal function used by the following three functions.
<dt> engel_new(*en__[],x) <dd>
Generate a classic EE in the given array with terms the same sign
as <i>x</i>.
<dt> engelfall_new(*en__[],x) <dd>
Generate a secondary EE in the given array with all terms except
the first having the opposite sign to <i>x</i>. This results in the
implied Egyptian fraction having alternating signs in the sum.
<dt> engelalt_new(*en__[],x) <dd>
Generate a third kind of EE in the given array where terms alternate
in sign within the EE itself. This results in the implied Egyptian
fraction having pairwise alternating signs in the sum.
<dt> engel_value(en__[]) <dd>
Interpret the given array as an Engel expansion and return the value
that it represents.
<dt> engel_print(en__[]) <dd>
Displays the contents of the given array in Engel expansion style.
<br />
Will display an ellipsis at the end of the output if the CF is
believed to be of infinite length (or at least of length beyond
the current accuracy as set by <code>scale</code>).
<dt> print_as_engel(x) <dd>
Displays <i>x</i>'s form as a classic or primary Engel expansion.
<dt> print_as_engelfall(x) <dd>
Displays <i>x</i>'s form as a secondary Engel expansion.
<dt> print_as_engelalt(x) <dd>
Displays <i>x</i>'s form as the third kind of EE described above.
</dl>
<dt class="filename"><a title="download file" name="cf_misc" href="./code/cf_misc.bc">cf_misc.bc</a><dd>
<strong> New for June 2012 </strong><br />
Miscellaneous functions that would otherwise be in the main
<a href="#cf">cf.bc</a> library.
<ul class="keywords">
<li> Conway Box
<li> Minkowski Question-mark
<li> Continued fraction transformation
</ul>
<dl class="functions">
<dt> cf_value_abs(cf__[]) <dd>
Returns the value of the continued fraction stored in the array
as if all terms in the continued fraction were positive.
<dt> cf_value_abs1(cf__[]) <dd>
As above, but reduces all terms by 1 after making them positive.
This function is written with CFNs in mind, which never have a term
whose absolute value is less than 2. Will complain if a term is
found to have become zero.
<dt> cf_abs_terms(*cf__[]) <dd>
Irrevocably sets all terms in the given continued fraction array to
their absolute value.
<dt> cf_abs1_terms(*cf__[]) <dd>
Irrevocably sets all terms in the given continued fraction array to
their absolute value, less one. Will complain if a term is
found to have become zero.
<dt> cfn_flip_abs(x) <dd>
Transforms x through the CFN and absolute algorithms to return an
alternate value.
<dt> cfn_flip_abs1(x) <dd>
As above but subtracts 1 from the absolute terms. Since this uses
the CFN algorithm, no error should result.
<dt> cf_conway_box(*cf__[],x) <dd>
The inverse of the below
<a href="http://en.wikipedia.org/wiki/Minkowski%27s_question_mark_function">
Minkowski question mark function</a>, this is the Conway box function
&#9633;(<i>x</i>).
This function stores the lengths of the runs of 1s and 0s into the
given array and formats said array as if it were the continued fraction
of another number instead.
<dt> conway_box(x) <dd>
Transforms a number using the above.
<dt> cf_question_mark(cf__[]) <dd>
The <a href="http://en.wikipedia.org/wiki/Minkowski%27s_question_mark_function">
Minkowski question mark function</a> <b>?</b>(<i>x</i>).
Transforms a continued fraction into a binary string by treating the
terms as lengths of runs of 1s or 0s in a new number. Since quadratic
irrationals have repeating continued fraction expansions, their
question-mark transformations have repeating binary expansions and are
therefore necessarily transformed into rational numbers.
<dt> question_mark(x) <dd>
As above but transforms a number rather than parsing a continued
fraction.
</dl>
<dt class="filename"><a title="download file" name="cf_sylvester" href="./code/cf_sylvester.bc">cf_sylvester.bc</a><dd>
<strong> New for June 2012 </strong><br />
Functions for generating, printing and interpreting
<a href="http://en.wikipedia.org/wiki/Fibonacci%E2%80%93Sylvester_expansion">
Sylvester Expansions</a>
in a similar manner to ordinary continued fractions.
Sister library to <a href="#cf_engel">cf_engel.bc</a>
<ul class="keywords">
<li> Greedy Egyptian fractions
<li> Sylvester Expansions
</ul>
<dl class="functions">
<dt> sylvester_new_(mode) <dd>
Internal function used by the two following
<dt> sylvester_new(*sy__[],x) <dd>
Create a greedy egyptian fraction of <i>x</i> also known as a
Sylvester expansion in the given array.
<dt> sylvester2_new(*sy__[],x) <dd>
As above but creates a secondary kind of SE where all terms after the
first are of opposite sign to <i>x</i>.
<dt> sylvester_value(sy__[]) <dd>
Interpret the given array as a Sylvester expansion and return the value
that it represents.
<dt> sylvester_print(sy__[]) <dd>
Displays the contents of the given array in an easily readable style.
<br />
Will display an ellipsis at the end of the output if the CF is
believed to be of infinite length (or at least of length beyond
the current accuracy as set by <code>scale</code>).
<dt> print_as_sylvester(x) <dd>
Displays <i>x</i>'s form as a classic or primary Sylvester expansion.
<dt> print_as_sylvester2(x) <dd>
Displays <i>x</i>'s form as a secondary Sylvester expansion.
</dl>
<dt class="filename"><a title="download file" name="collatz" href="./code/collatz.bc">collatz.bc</a><dd>
<strong> Rewritten for June 2012 </strong><br />
A suite of functions for very basic experimentation with the Collatz conjecture.
<br />
All functions here use the global variable <code>collatz_mode_</code> to
determine which Collatz ruleset is to be used.
<br />
By default this is set to 1 and the rules are the standard Collatz rules
of:
<blockquote>
<i>even x &rarr; x/2, odd x &rarr; 3x+1</i>.
</blockquote>
When set to 2, the rules become the condensed rules:
<blockquote>
<i>even x &rarr; x/2, odd x &rarr; (3x+1)/2</i>.
</blockquote>
When set to zero, the rules become:
<blockquote>
<i>even x &rarr; oddpart(x), odd x &rarr; oddpart(3x+1)</i>, where
<i>oddpart</i> is what remains of a number when it is divided by 2
until it cannot be divided further.
</blockquote>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> collatz_next(x) <dd>
Returns the next hailstone on from x
<dt> collatz_prev(x) <dd>
Returns one of the possible previous hailstones from x,
choosing the lower of the available options.
<dt> is_collatz(x) <dd>
If the Collatz conjecture is true, this function will return 1 (true)
for all positive integers. Will return -1 (true but negative) if a
negative number reaches -1, though many negative numbers reach a loop
and so, where detected, this function may return 0 (false)!
<dt> collatz_print(x) <dd>
Displays all hailstones from x down to 1 or -1, or until a loop is
found. <em>NB: This function fits with the system used elsewhere in
these files and so should have its value assigned to a variable in
order to avoid printing its return value, which is 0.</em>
<dt> collatz_root(x) <dd>
Returns the lowest number reached by the Collatz iteration whether
that be 1, -1 or the smallest member of the loop. Note that all
positive integers are thought to reach 1.
<dt> collatz_loopsize(x) <dd>
Returns the size of the loop that that Collatz iteration eventually
becomes caught within when starting from <i>x</i>. For positive
integers under the standard Collatz iteration, this loopsize is 3
because of the 4 &rarr; 2 &rarr; 1 &rarr; 4 cycle.
<dt> collatz_chainlength(x) <dd>
Returns the number of iterations before reaching a loop or a
terminating condition.
<dt> collatz_magnitude(x) <dd>
Returns the highest point reached during the Collatz iteration.
<dt> collatz_sum(x) <dd>
A hold-over from a previous version of this library. Returns the sum
of all hailstones reached during the iteration.
<dt> is_collatz_sg(x) <dd>
A combination of all of the above functions, setting global variables
by same names. In the case of <code>collatz_print</code>, this must be
set by the user, zero for disabled, and non-zero if this function is
to print all hailstones on the way to the terminating condition.
Returns the same value as would <code>is_collatz()</code>
</dl>
<dt class="filename"><a title="download file" name="collatz_continuous" href="./code/collatz_continuous.bc">collatz_continuous.bc</a><dd>
<strong> New for June 2012 </strong><br />
Most functions in this library have two versions; One which relies
on the global <code>collatz_mode_</code> variable as described in
<a href="#collatz">collatz.bc</a> and another which has a secondary
parameter for otherwise specifying the power of two of the divisor
(if any) on the odd step. See notes in code for more details.
<br />
Each of the non-inverse functions is designed to provide a continuous
version of the single Collatz iteration function. This necessarily
means that each of mappings has fixed points at certain non-integer
values of their first parameter. i.e. <i>x = f(x)</i>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> collatz_arccos(y) <dd>
Inverse of <code>collatz_cos(x)</code>
<dt> collatz_arccos_(y,k) <dd>
Inverse of <code>collatz_cos_(x,k)</code>
<dt> collatz_arcpcos(y) <dd>
Inverse of <code>collatz_pcos(x)</code>
<dt> collatz_arcpcos_(y,k) <dd>
Inverse of <code>collatz_pcos_(x,k)</code>
<dt> collatz_cos(x) <dd>
A continuous version of the single Collatz iteration function using
cosine interpolation to obtain values for non integer <i>x</i>.
<dt> collatz_cos_(x,k) <dd>
As above but with more control over the divisor on the odd step.
<i>k</i> may take any value, integer or otherwise.
<dt> collatz_pcos(x) <dd>
A continuous version of the single Collatz iteration function using
a clumsier, piecewise cosine interpolation to obtain values for
non-integer <i>x</i>.
<dt> collatz_pcos_(x,k) <dd>
As above but with more control over the divisor on the odd step.
<i>k</i> may take any value, integer or otherwise.
<dt> collatz_invlin(y) <dd>
Inverse of <code>collatz_lin(x)</code>
<dt> collatz_invlin_(y,k) <dd>
Inverse of <code>collatz_lin_(x,k)</code>.
Is used by all other inverse functions as a starting point.
<dt> collatz_invlinb(y) <dd>
Inverse of <code>collatz_linb(x)</code>
<dt> collatz_invlinb_(y,k) <dd>
Inverse of <code>collatz_linb_(x,k)</code>
<dt> collatz_lin(x) <dd>
Piecewise linear interpolation of the single Collatz iteration
function allowing for the generation of 'iterations' for non-integer
<i>x</i>. Unlike for cosine interpolation, piecewise is a better
choice for linear interpolation.
<dt> collatz_lin_(x,k) <dd>
As above but with more control over the divisor on the odd step.
<i>k</i> may take any value, integer or otherwise.
<dt> collatz_linb(x) <dd>
An alternative, non-piecewise, pseudo-linear interpolation of the
single Collatz iteration function. While this has an arguably
beautiful closed form, much like the non-piecewise cosine
interpolation, this function, when graphed, does not follow a straight
path between the integer values either side of <i>x</i>.
<dt> collatz_linb_(x,k) <dd>
As above but with more control over the divisor on the odd step.
<i>k</i> may take any value, integer or otherwise.
<dt> collatz_piecewise__(y,k) <dd>
Internal function; Used by the inverse functions for solving
piecewise transformations.
</dl>
<dt class="filename"><a title="download file" name="complex" href="./code/complex.bc">complex.bc</a><dd>
A second attempt at creating and working with complex numbers in bc. Uses arrays
and the undocumented <nobr>pass-by-reference</nobr> feature to store the real
and imaginary parts of a number. The downside to this method is that the syntax
is somewhat unwieldy: When a complex return value is required, the first parameter
is always <code>*c__[]</code> and the return value is stored within the first
two elements of the supplied array, rather than being returned in the usual bc way.
<p>
Some 'constants' are predefined by this library; These are <code>complex0[]</code>,
<code>complex1[]</code>, <code>complex2[]</code>, <code>complexi[]</code>,
<code>complexomega[]</code> and <code>complexomega2[]</code>. These are zero, one,
two, imaginary unit <i>i</i> and roots of positive unity
&omega; and &omega;<sup>2</sup>.
</p>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> arctan2(x,y) <dd>
Two-parameter inverse tangent; Takes two ordinary numbers and returns an
ordinary number. This is used by a few of the below functions.
<dt> cabs(c__[]) <dd>
Returns an ordinary number which is the absolute value or magnitude of the
complex number stored in the first two elements of the given array.
<dt> cadd(*c__[],a__[],b__[]) <dd>
Stores the sum of the second and third parameters into the first; i.e. c = a + b
<dt> caddassign(*c__[],b__[]) <dd>
Adds the value of the second parameter to the value already stored in the first; i.e. c += b
<dt> carccis(*c__[],x__[]) <dd>
Inverse of <code>ccis()</code>; If <i>x</i> is of form <i>cos(c)+i.sin(c)</i>,
calculate a possible value for <i>c</i>.
<dt> carccos(*c__[],x__[]) <dd>
Stores the inverse cosine of x in c.
<dt> carccosec(*c__[],x__[]) <dd>
Stores the inverse cosecant of x in c.
<dt> carccosech(*c__[],x__[]) <dd>
Stores the inverse hyperbolic cosecant of x in c.
<dt> carccosh(*c__[],x__[]) <dd>
Stores the inverse hyperbolic cosine of x in c.
<dt> carccotan(*c__[],x__[]) <dd>
Stores the inverse cotangent of x in c.
<dt> carccotanh(*c__[],x__[]) <dd>
Stores the inverse hyperbolic cotangent of x in c.
<dt> carcsec(*c__[],x__[]) <dd>
Stores the inverse secant of x in c.
<dt> carcsech(*c__[],x__[]) <dd>
Stores the inverse hyperbolic secant of x in c.
<dt> carcsin(*c__[],x__[]) <dd>
Stores the inverse sine of x in c.
<dt> carcsinh(*c__[],x__[]) <dd>
Stores the inverse hyperbolic sine of x in c.
<dt> carctan(*c__[],x__[]) <dd>
Stores the inverse tangent of x in c.
<dt> carctanh(*c__[],x__[]) <dd>
Stores the inverse hyperbolic tangent of x in c.
<dt> carg(c__[]) <dd>
Returns an ordinary number which is the angle or argument of the complex number in c.
<dt> carrayget(*c__[],a__[],i) <dd>
Rudimentary complex array handling; Second parameter is treated as an array of complex numbers,
which in bc terms is an array of numbers that for each pair of elements, a complex number is
represented. This function stores the i-th complex entry in the array into c.
i.e. <code>c = a[i]</code>
<dt> carrayset(*a__[],i,c__[]) <dd>
Rudimentary complex array handling; First parameter is treated as an array of complex numbers,
which in bc terms is an array of numbers that for each pair of elements, a complex number is
represented. This function stores the complex number found in c into the i-th complex entry
of that array. i.e. <code>a[i] = c</code>
<dt> cassign(*c__[],x__[]) <dd>
Stores a copy of the first two elements of x into the first two elements of c.
i.e. set one complex number equal to another.
<dt> ccis(*c__[],x__[]) <dd>
Stores <i>cos(x)+i.sin(x)</i> into c. To calculate the same for x as an ordinary bc number,
see the <code>cis()</code> function.
<dt> cconj(*c__[],x__[]) <dd>
Stores the complex conjugate of x into c.
<dt> cconjself(*c__[]) <dd>
Turn a complex number into its conjugate.
<dt> ccos(*c__[],x__[]) <dd>
Stores the cosine of x in c.
<dt> ccosec(*c__[],x__[]) <dd>
Stores the cosecant of x in c.
<dt> ccosech(*c__[],x__[]) <dd>
Stores the hyperbolic cosecant of x in c.
<dt> ccosh(*c__[],x__[]) <dd>
Stores the hyperbolic cosine of x in c.
<dt> ccotan(*c__[],x__[]) <dd>
Stores the cotangent of x in c.
<dt> ccotanh(*c__[],x__[]) <dd>
Stores the hyperbolic cotangent of x in c.
<dt> cdiv(*c__[],a__[],b__[]) <dd>
Stores the result of dividing the second parameter by the third into the first; i.e. c = a / b
<dt> cdivassign(*c__[],b__[]) <dd>
Divides the value stored in the first parameter by the value in the second; i.e. c /= b
<dt> cequal(a__[],b__[]) <dd>
Boolean function; Returns 1 if the complex numbers represented by the parameters are equal.
<dt> cexp(*c__[],x__[]) <dd>
Stores the x-th power of e into c. Exponential.
<dt> cexpself(*c__[]) <dd>
Raises e to the power of the parameter and then stores it back there.
<dt> cintpow(*c__[], z[], n) <dd>
Stores the nth power of z in c; i.e. c = z^n (where n is integer).
<em>This is faster than using the <code>cpow()</code> function.</em>
<dt> cintpowassign(*c__[],n) <dd>
Raises c to the nth integer power; i.e. c = c^n
<em>This is faster than using the <code>cpowassign()</code> function.</em>
<dt> cis(*c__[],x) <dd>
Stores <i>cos(x)+i.sin(x)</i> into c. To calculate the same for x as a complex number,
see the <code>ccis()</code> function.
<dt> cln(*c__[],x__[]) <dd>
Stores the natural logarithm of x in c.
<dt> clnself(*c__[]) <dd>
Takes the natural logarithm of c and replaces the original value with it.
<dt> cmul(*c__[],a__[],b__[]) <dd>
Stores the product of the second and third parameters into the first; i.e. c = a.b
<dt> cmulassign(*c__[],b__[]) <dd>
Multiplies the value stored in the first parameter by the value in the second; i.e. c = c.b
<dt> cneg(*c__[],x__[]) <dd>
Stores the value of -1 times x in c.
<dt> cnegself(*c__[]) <dd>
Inverts the sign of the given complex number.
<dt> cpow(*c__[],a__[],b__[]) <dd>
Stores the result of raising the second parameter to the power of the third into
the first; i.e. c = a^b
<dt> cpowassign(*c__[],b__[]) <dd>
Raises the first parameter to the power of the second; i.e. c = c^b
<dt> csec(*c__[],x__[]) <dd>
Stores the secant of x in c.
<dt> csech(*c__[],x__[]) <dd>
Stores the hyperbolic secant of x in c.
<dt> csgn(*c__[],x__[]) <dd>
Stores the complex sign, or unit circle intersection point of x in c.
<dt> csgnself(*x__[]) <dd>
As above but performs the operation on the given number and overwrites.
<dt> csin(*c__[],x__[]) <dd>
Stores the sine of x in c.
<dt> csinh(*c__[],x__[]) <dd>
Stores the hyperbolic sine of x in c.
<dt> csqrt(*c__[],x__[]) <dd>
Stores the principle square root of x in c.
<dt> csqrtself(*c__[]) <dd>
Overwrites the parameter with its principle square root.
<dt> csquare(*c__[],x__[]) <dd>
Stores the square of x in c. Faster than the <code>...pow...()</code> functions or multiplying.
<dt> csquareself(*c__[]) <dd>
Overwrites the parameter with its square.
<dt> csub(*c__[],a__[],b__[]) <dd>
Stores the result of subtracting the third parameter from the second into the first;
i.e. c = a - b
<dt> csubassign(*c__[],b__[]) <dd>
Subtracts the values of the second parameter from the value held in the first;
i.e. c = c - b
<dt> ctan(*c__[],x__[]) <dd>
Stores the tangent of x in c.
<dt> ctanh(*c__[],x__[]) <dd>
Stores the hyperbolic tangent of x in c.
<dt> imag(c__[]) <dd>
Returns, as a standard bc number, the imaginary part of c.
<dt> int(n) <dd>
Returns the integer part of an ordinary bc number.
<dt> makecomplex(*c__[],r,i) <dd>
Creates a complex number in c from real and imaginary parameters r and i, repectively.
<dt> makeomega() <dd>
Technically an internal function. Sets the values of intentionally predefined array-based
complex numbers. These are <code>complexomega[]</code> and <code>complexomega2[]</code>
which are the complex third roots of unity. This function should be called if these two
arrays are corrupted for some reason.
<dt> mod(n,m) <dd>
Returns n modulo m. Return value and parameters are all standard bc numbers, and indeed
should all be integers.
<dt> printc(c__[]) <dd>
Prints the complex number stored in c in a human readable format.
<dt> real(c__[]) <dd>
Returns, as a standard bc number, the real part of c.
</dl>
<dt class="filename"><a title="download file" name="cosconst" href="./code/cosconst.bc">cosconst.bc</a><dd>
The cosine constant to a large number of decimal places, where <code>x = cos(x)</code>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> None <dd>
There is only a constant called <code>cosconst</code>
</dl>
<!-- ==================== D ==================== -->
<dt class="filename"><a title="download file" name="digits" href="./code/digits.bc">digits.bc</a><dd>
<strong> Minor update for February 2013 </strong><br />
Treat numbers as strings of digits. <em>Some of the definitions below
are not in strict alphabetical order. This is so that concepts are
introduced in a more logical order.</em>
<p>
Many functions will operate with bijective (zero-less) number bases, which
can be activated through use of the new global <code>bijective</code> flag.
By default this is zero. Set to non-zero to alter the behaviour of those
functions which support it.
<p>
Some functions operate correctly with negative number bases, e.g. negabinary.
<ul class="keywords">
<li> Digital sum
<li> Reverse
<li> Palindromes
<li> Stringification
<li> Cantor reinterpretation
<li> Bijective (zero-less) numeration
<li> Negative integer bases (negabase)
</ul>
<dl class="functions">
<dt> base_check_() <dd>
Internal function; used by most functions to check the sanity of the <code>base</code>
parameter which most of these have.
<dt> bmod_(x,y) <dd>
Internal function; Returns x modulo y and sets global variable <code>bdiv_</code> to the
value of the division which found the modulus. In bijective mode the return range is
1..y rather than 0..y-1, and <code>bdiv_</code> is one less than the true division when
the modulus is equal to y.
For positive x and y, <code>x == bmod_(x,y)+y*bdiv_</code> is always true.
<dt> cantor(basefrom, baseto, x) <dd>
Treat x's representation in basefrom as a representation in baseto and
return the resulting number, i.e. reinterpret the number.<br />
Will always convert successfully to a larger base, but the reverse is
often not possible, and a warning will result when data loss occurs.<br />
Warnings can be turned off by setting the global <code>cantorwarn_</code>
variable to 0. It is set to 1 by default.<br />
Some warnings can be mitigated through use of the similar global
<code>cantormod_</code> variable. If this is set to 1, calculated digits are
truncated, modulo baseto, meaning some information will be lost, but no
left-carries will occur.<br />
x can be interpreted as if basefrom is a
<a href="http://en.wikipedia.org/wiki/Bijective_numeration">bijective base</a>
(see <a href="#output_formatting">output_formatting.bc</a> for ways to <em>display</em>
numbers as bijective) if global variable <code>bijective</code> is
set to 1. <em>Note that a warning will result if x is non-integer in bijective mode;
there is no correct way to interpret such a value.</em>
<dt> cantor_trans(basefrom, baseto, mul, cons, x) <dd>
As above, but an extra linear transform can be applied to the digits as they are
converted between the bases. They will be multiplied by the given
<code>mul</code>tiplier and then added to the given <code>cons</code>tant.
<dt> cantor_trans_(d) <dd>
Internal function; Acts as an error checker / reporter for the above.
<dt> cantor_trans_negabase_(basefrom, baseto, mul, cons, x) <dd>
Internal function; Used by <code>cantor_trans</code> to be able
to handle negative integer bases. Note that the parameters match.
<dt> digit_sum(base,x) <dd>
Add the digits of x when interpreted in the specified base. Repeated
applications of this function would derive the "digital root".
<dt> digit_product(base,x) <dd>
As above, but multiply rather than add. e.g. 235 -> 2*3*5 = 30 in base ten.
In non-bijective bases this function returns zero much of the time since there
is a strong chance that one or more of the digits in the number is a zero. See
<a href="#digits_misc">digits_misc.bc</a> for two alternatives to this function
which do not have this disadvantage.
<dt> digit_distance_(base,x,y,sh) <dd>
Internal function: Engine used by both of the below
<dt> digit_distance(base,x,y) <dd>
Adds the differences of respective digits of x and y in the given base and returns
the result. e.g. 246(-)176 ->|2-1|+|4-7|+|6-6| = 1+3+0 = 4 in base ten.
This can be considered an extension to the concept of
<a href="http://en.wikipedia.org/wiki/Hamming_distance">Hamming distance</a>,
which merely counts the number of differences. See also <code>base_hamming()</code>
in <a href="#logic_otherbase">logic_otherbase.bc</a> and <code>hamming()</code>
in <a href="#logic">logic.bc</a> for pure difference functions.
<dt> digit_sdistance(base,x,y) <dd>
In modular arithmetic, there it can be argued that there are often two possible
positive solutions to |<i>x</i>-<i>y</i>|; One of these matches the usual
definition, but the other has a value of <i>modulus</i>-|<i>x</i>-<i>y</i>|.
e.g. modulo ten, |1-8|=7, but wrapping around zero, we can move 8 to 9, 9 to 0 and
0 to 1, which is only three steps.<br />
This function therefore, is the same as the above but uses the smaller of the two
options in the summation for the distance between digits.
<dt> digits(base,x) <dd>
Find the number of digits in x's representation in the given base.
<dt> int_catenate(base, x,y) <dd>
Splice two integer representations together in the specified base so
that x is before y.
<dt> int_left(base, x, count) <dd>
Returns the leftmost digits of x in the given base,
specified by the given count.
<dt> int_mid(base, x, start, end) <dd>
Returns digits of x in the given base, counting in from the left,
starting and ending at the given digit positions.
<dt> int_right(base, x, count) <dd>
Returns the rightmost digits of x in the given base,
specified by the given count.
<dt> is_palindrome(base,x) <dd>
Determine whether x reads the same forwards and backwards in the given
base
<dt> is_pseudopalindrome(base,x) <dd>
Determine whether x reads the same forwards and backwards in the given
base, or <em>could</em> read the same each way if zeroes were prepended
to the number (which wouldn't actually change its value).
<dt> is_substring(base,large,small) <dd>
Determine whether the digits of the smaller number appear, in order,
within the digits of the larger number, all in the given base.
<dt> make_even_palindrome(base, x) <dd>
Turn x into a unique palindrome with an even number of digits in the
given base.
<dt> make_odd_palindrome(base, x) <dd>
Turn x into a unique palindrome with an odd number of digits in the
given base.
<dt> map_palindrome(base, x) <a name="map_palindrome"></a> <dd>
Generate a unique palindrome from x in the given base. This function
maps the integers onto the palindromes on a one-to-one basis.
<dt> reverse(base,x) <dd>
Reverse the digits of x in the current base. <em>Zeroes at the end of
x will be lost.</em>
<dt> unmap_palindrome(base, x) <dd>
Inverse function of
<a href="#map_palindrome">map_palindrome</a>; Maps the domain
of palindromes in the given base back into the integers.
</dl>
<dt class="filename"><a title="download file" name="digits_describe" href="./code/digits_describe.bc">digits_describe.bc</a><dd>
<ul class="keywords">
<li>Look-and-say
<li>Numbers describing numbers
</ul>
<dl class="functions">
<dt> describe_(opt,base,x) <dd>
Internal function for both modes of describing numbers
<dt> describe_countfirst(base,x) <dd>
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
<a href="http://en.wikipedia.org/wiki/Look-and-say_sequence">look-and-say sequence</a>.
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.
<dt> describe_countlast(base,x) <dd>
Generates a number (in the specified base) which describes x by putting the
digit count of each digit of x <em>after</em> 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.
<dt> parserle_(opt,base,x) <dd>
Internal function for both modes of interpreting the above description numbers.
<em>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".</em>
<dt> parserle_countfirst(base,x) <dd>
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.
<dt> parserle_countlast(base,x) <dd>
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.
</dl>
<dt class="filename"><a title="download file" name="digits_happy" href="./code/digits_happy.bc">digits_happy.bc</a><dd>
<strong> Very minor update for February 2012 </strong><br />
A suite of functions for investigating the so-called
<a href="http://en.wikipedia.org/wiki/Happy_number"> Happy Numbers</a>.
This library supports the <code>bijective</code> global variable used
elsewhere in these files. When this variable is non-zero (and thus
bijective mode is enabled), numbers are also considered to be happy if the
iteration reaches the <em>base</em> and not just 1.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> base_check_happy_() <dd>
Internal function; used by most functions to check the sanity of the <code>base</code>
parameter which most of these have.
<dt> is_happy(base,pow,x) <dd>
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).
<dt> happy_chainlength(base,pow,x) <dd>
Returns the number of iterations required to reach happiness for the given
<i>x</i>. Will return a negative number of iterations if <i>x</i> is
unhappy, which is the number of iterations required before the algorithm
"realises" that the number is unhappy.
<dt> happy_loopsize(base,pow,x) <dd>
Should probably be called <em>un</em>happy_loopsize, since this will return
the number of iterations in the loop encountered by numbers that are not happy.
<dt> happy_print(base,pow,x) <dd>
Shows all the iterations down to 1 if the number is happy, or else stops once
a loop is detected.
<dt> happy_root(base,pow,x) <dd>
Shows 1 if the number is happy, or else the smallest number in the loop that
an unhappy number becomes trapped within.
<dt> is_happy_sg(base,pow,x) <dd>
sg = "set globals": This function is all of the above rolled into one, and will
set global variables by the names of the above functions (e.g. happy_root)
for the parameters given. If the global variable happy_print is set to 1, then
this function will also behave as the happy_print() function and display the
value of the iterations. Set to 0 to turn the feature off again.
Like is_happy(), returns 1 if <i>x</i> is happy and 0 otherwise.
</dl>
<dt class="filename"><a title="download file" name="digits_misc" href="./code/digits_misc.bc">digits_misc.bc</a><dd>
<strong> Very minor update for February 2012 </strong><br />
Some of the more obscure digit stringification functions you may wish to encounter,
removed from <a href="#digits">digits.bc</a> as interesting but unnecessary, or rolled
in from various old bc files long removed from this page.
<ul class="keywords">
<li> Counting calculator display segments
<li> Multiply digits
<li> Count digits into arrays
<li> Negapalindromes
<li> Pan digital halving index
</ul>
<dl class="functions">
<dt> base_check_misc_() <dd>
Internal function; used by most functions to check the sanity of the <code>base</code>
parameter which most of these have.
<dt> append_all(base,x) <dd>
The digit string equivalent of the <a href="#tri">triangular</a> numbers
or the <a href="#factorial">factorials</a>. 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
<dt> calcsegments(base,x) <dd>
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.
<dt> count_digit(base,x,digit) <dd>
Returns the number of occurrences of a given digit within an integer, x, in the
given base. e.g. 52726620 has 3 occurrences of the digit 2 in base ten.
<dt> count_digits(*d__[],base,x) <dd>
Uses the undocumented <nobr>pass-by-reference</nobr> for arrays to store a count
of all types of digit in the given base that can be found in an integer, x.
e.g. 10110101010010101 in binary would result in d containing {8,9} because there
are eight zeroes and nine ones.
<dt> digit_product1(base,x) <dd>
An alternative to <code>digit_product()</code> in <a href="#digits">digits.bc</a>.
Rather than multiply the digits immediately, one is added to each before the
multiplication and then one is subtracted from the final product, ensuring a
non-zero result. e.g. 235 -> (2+1)(3+1)(5+1)-1 = 3*4*6 - 1 = 71 in base ten.
<dt> digit_product2(base,x) <dd>
Another alternative to <code>digit_product()</code> and the above.
All digits are translated into their corresponding odd number, multiplied and then
mapped back from the odd integers to the integers again.
e.g. 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
in base ten.
<dt> is_negapalindrome(base,x) <dd>
Determine whether the opposing pairs of digits, (counted in from either
end) sum to one less than the given base. e.g. <i>147258</i> is a
negapalindrome in base ten since <i>1+8 = 4+5 = 7+2 = 9 = 10 - 1</i>
<dt> is_pseudonegapalindrome(base,x) <dd>
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.
<dt> is_negapalindrome2(base,x) <dd>
Alternate definition of negapalindrome, where opposing pairs of digits
must sum to the base itself, rather than one less.
<dt> map_negapalindrome(base, x) <a name="map_negapalindrome"></a> <dd>
Generate a unique negapalindrome from x in the given base. This function
maps the integers onto the negapalindromes on a one-to-one basis.
<dt> pdhi(x) <dd>
Pan digital halving index. Determine the number of times that x must be halved
before its decimal expansion (or the expansion in the base specified by
<code>ibase</code>) contains all possible digits.
<em>Warning: May hang for some values of x</em>
<dt> pdmi(x,m) <dd>
Pan digital multiplying index: Determine how many times x must be
multiplied by m before it is pandigital.
<em>Warning: May hang for some values of x and m</em>
<dt> sdp(base,x) <dd>
Swap Digit Pairs: Takes the representation of x in the given base and
reverses every pair of digits.
<dt> sort_digits_asc(base,x) <dd>
Sort the digits of x into ascending order in the given base.
<em>Zeroes at the end of x will be lost.</em>
<dt> sort_digits_desc(base,x) <dd>
Sort the digits of x into descending order in the given base.
<dt> split_digits(*d__[],base,x) <dd>
Using the given base, store x into the given array in an unambiguous manner
which does not lose any information. For more details, see the source code.
<dt> join_digits(d__[]) <dd>
Returns the number which has been stored into an array by the
<code>split_digits</code> function. Basimal point and original base are store
within the array hence only one parameter being required.
<dt> stripbm1s_(base,x) <dd>
Internal function used by the negapalindrome family.
<dt> unmap_negapalindrome(base, x) <dd>
Inverse function of
<a href="#map_negapalindrome">map_negapalindrome</a>; Maps the domain
of negapalindromes in the given base back into the integers.
</dl>
<!-- ==================== E ==================== -->
<!-- ==================== F ==================== -->
<dt class="filename"><a title="download file" name="factorial" href="./code/factorial.bc">factorial.bc</a><dd>
<strong> Updated for February 2013 </strong><br />
A suite of functions for calculations involving the factorial and its relatives. Migrated from
<a href="#funcs">funcs.bc</a> and then expanded upon. Still requires funcs.bc to work correctly.
<ul class="keywords">
<li> Factorial
<li> Combination (Binomial Coefficients)
<li> Permutation
<li> Derangements
<li> LCM factorial / LCMultorial
<li> Euler gamma constant
</ul>
<dl class="functions">
<dt> factorial(x) <a name="factorial_func"></a> <dd>
An approximation to the factorial function over the reals. Is accurate as possible for
all integers and half-integers, but interpolates otherwise.
Accuracy versus speed can be balanced by changing the value of the global
<code>factorial_substrate_</code> variable. Set to 0, will use the cheapest approximation
for interpolation. Values of 1, 2 (default) and 3, are increasingly slower but more accurate.
A value of 4 (the maximum) will ensure calculations take as long as necessary to find an
accurate answer.
<dt> lncombination(n,r) <dd>
Calculates the logarithm of the <code>combination()</code> function using the
<code>lnfactorial()</code> function so that larger values of n and r may
be calculated for more quickly.
<dt> lnpermutation(n,r) <dd>
Calculates the logarithm of the <code>permutation()</code> function using the
<code>lnfactorial()</code> function so that larger values of n and r may
be calculated for more quickly.
<dt> lnfactorial(x) <dd>
Calculates the logarithm of the <code>factorial()</code> function in a way
generally faster than <code>ln(factorial(x))</code>, but with the same caveats as
before: Is accurate as possible for all integers and half-integers, but interpolates
otherwise.
<dt> catalan(n) <dd>
Returns the nth <a href="http://en.wikipedia.org/wiki/Catalan_number">Catalan number</a>
<dt> combination(n,r), int_combination(n,r) <dd>
Calculates the binomial coefficient n<b>C</b>r. 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 <a href="factorial">factorial</a> function to a closely approximated
calculation for non integral parameters.
<dt> double_factorial(x) <dd>
Calculates the so-called double factorial (x!! = x.(x-2).(x-4)..{2 or 1}) with the same
caveats as for the <code>factorial()</code> and other functions: Is accurate as
possible for all integers and half-integers, but interpolates otherwise.
<dt> eulergamma() <dd>
Gives Euler's <i>&gamma;</i> (0.5772156...) to the number of decimal places specified by the
current <code>scale</code>. Uses global variable <code>eulergamma_</code> to cache the value
to save on recalculating every time this is called. The variable always contains a value
of accuracy greater or equal to the current <code>scale</code>. <em> Caution: this function
will be very slow on first running as it calculates the value in real time. </em>
<dt> factorial_substrate_(n), lnfactorial_substrate_(n) <dd>
Internal functions. These derive an appropriate approximation specified by the
aforementioned global <code>factorial_substrate_</code> variable, and return the result.
<dt> fast_inverse_factorial(x) <dd>
A <em>very</em> approximate inverse to the <code>factorial()</code> function.
Developed from an idea by David W. Cantrell.
<dt> fast_inverse_lnfactorial(x) <dd>
A <em>very</em> approximate inverse for the <code>lnfactorial()</code> function.
<dt> gfactorial(n) <dd>
A rough, quick and dirty approximate to the factorial function using the below. [Substrate 0]
<dt> gosper(x) <dd>
Gosper's approximation to the natural logarithm of the factorial function. [Substrate 0]
<dt> int_multifactorial(y,x) <dd>
Quick and dirty function to calculate the y'th multifactorial of x.
<dt> inverse_factorial(f) <dd>
Uses and improves on the result given by <code>fast_inverse_factorial(x)</code> to give a
an almost exact inverse. Much slower than the latter, but useful at high substrates for
providing as accurate an answer as possible.
<dt> inverse_lnfactorial(x) <dd>
Uses and improves on the result given by <code>fast_inverse_lnfactorial(x)</code> to give a
an almost exact inverse. Much slower than the latter, but useful at high substrates for
providing as accurate an answer as possible.
<dt> lcmultorial(x) <dd>
Calculate the lowest common multiple of all integers from 1 to x. This is an integer-only function.
For an attempt at a more continuous function, see <code>lcmultorialc()</code> in
<a href="#orialc">orialc.bc</a>.
<dt> nemes(x) <dd>
Gergo Nemes' excellent approximation to the natural logarithm of the
<a href="#factorial_func">factorial</a> function. [Substrate 1]
<dt> nemfactorial(n) <dd>
Uses the above to calculate an approximation to the
<a href="#factorial_func">factorial</a> function. [Substrate 1]
<dt> permutation(n,r), int_permutation(n,r) <dd>
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
<a href="factorial">factorial</a> function to
a closely approximated calculation for non integral parameters.
<dt> spouge(n) <dd>
John L. Spouge's approximation to the natural logarithm of the Gamma function,
adjusted to be an lnfactorial approximation;
This version calculates to within <code>scale</code> significant figures.
[Substrate 3]
<dt> spougefactorial(n) <dd>
John L. Spouge's approximation to the Gamma function,
adjusted to be a factorial approximation;
This version calculates to within <code>scale</code> significant figures.
[Substrate 3]
<dt> spougefactorialx(n) <dd>
John L. Spouge's approximation to the Gamma function,
adjusted to be a factorial approximation;
This version calculates to within <code>scale</code> decimal places, which may
take much longer than the x-less counterpart above. [Substrate 4]
<dt> spougex(n) <dd>
John L. Spouge's approximation to the natural logarithm of the Gamma function,
adjusted to be an lnfactorial approximation;
This version calculates to within <code>scale</code> decimal places, which may
take much longer than the x-less counterpart above. [Substrate 4]
<dt> spouge_(n,l,exact) <dd>
Internal function used by the other Spouge functions. [Substrate >3]
<dt> stielfactorial(n) <dd>
Thomas J. Stieltjes' approximation to the Gamma function,
adjusted to be a factorial approximation. [Substrate 2]
<dt> stieltjes(n) <dd>
Thomas J. Stieltjes' approximation to the natural logarithm of the Gamma function,
adjusted to be an lnfactorial approximation. [Substrate 2]
<dt> subfactorial(n) <dd>
Subfactorial / Derangement counting function; Gives how many ways a number of items
can be rearranged such that no item is in its original place
</dl>
<dt class="filename"><a title="download file" name="factorial_gamma" href="./code/factorial_gamma.bc">factorial_gamma.bc</a><dd>
<strong> New for February 2013 </strong><br />
Near-aliases for some functions in <a href="#factorial">factorial.bc</a>, giving
the functions more classical function names.
<ul class="keywords">
<li> Gamma function
<li> Beta function
</ul>
<dl class="functions">
<dt> gamma(x) <dd>
An approximation to the Gamma function over the reals. Is accurate as possible for
all integers and half-integers, but interpolates otherwise. Accuracy versus speed
can be balanced by changing the value of the global
<dt> lngamma(x) <dd>
Calculates the logarithm of the <code>gamma()</code> function in a way
generally faster than <code>ln(gamma(x))</code>, but with the same caveats as
before: Is accurate as possible for all integers and half-integers, but interpolates
otherwise.
<dt> inverse_gamma(f) <dd>
Relatively slow but accurate calculation of the inverse of the Gamma function for positive
real values.
<dt> inverse_lngamma(x) <dd>
Relatively slow but accurate calculation of the inverse of the lnGamma function for positive
real values.
<dt> beta(x,y) <dd>
Euler's Beta function
<dt> lnbeta(x,y) <dd>
Calculates the logarithm of the <code>beta()</code> function in a way
generally faster than <code>ln(beta(x,y))</code>
</dl>
<dt class="filename"><a title="download file" name="fibonacci" href="./code/fibonacci.bc">fibonacci.bc</a><dd>
Fibonacci and Lucas functions; Originally part of <a href="#funcs">funcs.bc</a>
Still requires funcs.bc to work correctly.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> fibonacci(n) <a name="fibonacci"></a> <dd>
An extension of the fibonacci numbers over the reals without stepping into complex
numbers, which would be necessary for a true extension.
<dt> inverse_fibonacci(f) <dd>
An inverse to the <a href="#fibonacci">fibonacci</a> function.
Provides incorrect answers for non integer values of f when f < 1.
<dt> inverse_lucas(l) <dd>
An inverse to the <a href="#lucas">lucas</a> function.
Provides incorrect answers for non integer values of l when l < 2.
<dt> lucas(n) <dd>
Returns the n'th Lucas number. Continuous over the reals, like its cousin the
<a href="#fibonacci">fibonacci</a> function
</dl>
<dt class="filename"><a title="download file" name="funcs" href="./code/funcs.bc">funcs.bc</a><dd>
<strong> Minor update for February 2013 </strong><br />
A large suite of functions to complement the bc standard library. Unlike the standard
library (activated with <code>bc -l</code>), all function names are spelled out in full.
Full name aliases for the standard library functions are provided.
<ul class="keywords">
<li> Integer and Rounding
<li> Trigonometry
<li> Hyperbolic Trigonometry
<li> Exponential / Logarithms
<li> Powers / Roots
<li> Lambert W
<li> Triangular numbers
<li> Polygonal numbers
<li> Tetrahedral numbers
<li> Arithmetic-Geometric mean
</ul>
<dl class="functions">
<dt> abs(x) <dd>
Absolute value of a number
<dt> arccos(x) <dd>
Inverse cosine
<dt> arccosec(x) <dd>
Inverse cosecant
<dt> arccosech(x) <dd>
Inverse hyperbolic cosecant
<dt> arccosh(x) <dd>
Inverse hyperbolic cosine
<dt> arccotan(x) <dd>
Inverse cotangent (single variable)
<dt> arccotan2(x,y) <dd>
Inverse cotangent (two axes)
<dt> arccoth(x) <dd>
Inverse hyperbolic cotangent
<dt> arcgudermann(x) <dd>
Inverse of the
<a href="http://en.wikipedia.org/wiki/Gudermannian_function">Gudermann function</a>
<dt> arcsec(x) <dd>
Inverse secant
<dt> arcsech(x) <dd>
Inverse hyperbolic secant
<dt> arcsin(x) <dd>
Inverse sine
<dt> arcsinh(x) <dd>
Inverse hyperbolic sine
<dt> arctan(x) <dd>
Inverse tangent (single variable). This is an alias for bc's own <code>a()</code> function.
<dt> arctan2(x,y) <dd>
Inverse tangent (two axes)
<dt> arctanh(x) <dd>
Inverse hyperbolic tangent
<dt> arigeomean(a,b) <dd>
Arithmetic-geometric mean
<dt> besselj(n,x) <dd>
Bessel J function. This is an alias for bc's own <code>j()</code> function.
<dt> ceil(x) <a name="ceil"></a> <dd>
Ceiling function: returns the next integer greater than or equal to x
<dt> converse_poly(x,r) <dd>
converse of <a href="#poly">poly</a>; 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)
<dt> cbrt(x) <dd>
Cube root; Specific and streamlined version of <code>root(x,3)</code>, included by
popular demand. Will always find an integer cube root without loss of accuracy no
matter how large is x.
<dt> cos(x), c(x) <dd>
Cosine; Uses the <code>pi()</code> function below in order to provide faster calculation
than bc's library c() function. Overrides that same function due to the speed increase.
<dt> cosec(x) <dd>
Cosecant
<dt> cosech(x) <dd>
Hyperbolic cosecant
<dt> cosh(x) <dd>
Hyperbolic cosine
<dt> cotan(x) <dd>
Cotangent
<dt> coth(x) <dd>
Hyperbolic cotangent
<dt> evenpart(x) <dd>
Find the largest power of two within x, i.e. the even part of x
<dt> exp(x) <dd>
Exponential function <i>e<sup>x</sup></i>.
This is an alias for bc's own <code>e()</code> function.
<dt> fastfracpow_(x,y) <dd>
Internal function for faster / alternative methods of raising a number
to powers between 0 and 1.
<dt> fastintpow_(x,y), fastintpow__(x,y) <dd>
Internal functions for faster / alternative methods of raising bc numbers to integer powers.
See source code for more information. Used by the <code>pow()</code> function below.
<dt> fastintroot_(x,y) <dd>
Internal function for finding integer roots in a faster and less <code>scale</code>-reliant
way than other internal functions. As above, is used by <code>pow()</code>.
<dt> floor(x) <a name="floor"></a> <dd>
Floor function. Finds the integer less than or equal to x.
<dt> frac(x) <dd>
Finds the fractional part of number, discarding the integer part.
Always returns a non-negative answer.
<dt> gcd(x,y), int_gcd(x,y) <dd>
Calculate the GCD (Greatest Common Divisor) of x and y.
<dt> gudermann(x) <dd>
The <a href="http://en.wikipedia.org/wiki/Gudermannian_function">Gudermann function</a>
which links hyperbolic and common trigonometric functions.
<dt> id_frac2_(y) <dd>
Internal function. Helps determine whether the fractional part of a number is
most likely <sup>odd</sup>/<sub>even</sub>, <sup>odd</sup>/<sub>odd</sub>,
<sup>even</sup>/<sub>odd</sub> or irrational. See comments in code for more.
<dt> int(x) <dd>
Finds the integer part of x, always rounding towards zero.
See <a href="#ceil">ceil</a> and <a href="#floor">floor</a> for more useful functions.
<dt> inv_arigeomean(n, y) <dd>
Inverse of the arithmetic-geometric mean; Given the arithmetic-geometric mean of two numbers,
<i>n</i>, and one of the two numbers, <i>y</i>, finds the value of the unknown number.
<dt> inverse_poly(s, r) <dd>
"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 <a href="#trirt">trirt</a> function.
<dt> lambertw0(x) <a name="lambertw"></a> <dd>
The zero branch of the Lambert W function, i.e. the inverse of <i>xe<sup>x</sup></i>.
<dt> lambertw0_exp(x) <dd>
Faster, more advisable alternative for calculating <code>lambertw0(exp(x))</code>.
<dt> lambertw_1(x) <dd>
The minus one branch of the Lambert W function
<dt> lcm(x,y), int_lcm(x,y) <dd>
Calculate the LCM (Lowest/least Common Multiple) of x and y.
<dt> ln(x) <dd>
A speed improvement to bc's own <code>l()</code> Natural Logarithm function,
though the latter is still used by this function.
Complains when given unexpected values.
<dt> log(base,x), int_log(base,x) <dd>
Find the logarithm of x to the given base.
<dt> oddpart(x) <dd>
Finds the odd part of a number, removing any powers of two, e.g. the odd part of 60 is 15
<dt> phi() <dd>
Gives the golden ratio <i>&phi;</i> (1.618033...) to the number of decimal places
specified by the current <code>scale</code>.
<dt> pi() <dd>
Gives <i>&pi;</i> (3.141592...) to the number of decimal places specified by the
current <code>scale</code>. Uses global variable <code>pi_</code> to cache the value
to save on recalculating every time this is called. The variable always contains a value
of accuracy greater or equal to the current <code>scale</code>.
<dt> poly(s, x) <a name="poly"></a> <dd>
Return the x'th s-sided polygonal number, e.g. the 10th triangular number = poly(3,10)
<dt> pow(x,y) <dd>
Returns an extremely close approximation (completely accurate in the case of integer
parameters) to <i>x<sup>y</sup></i>; Copes very well with negative numbers, fractional
exponents etc. always returning a real or exact integer root where possible.
Will complain and return zero otherwise.
<dt> powroot(x) <dd>
Solves <i>x = y<sup>y</sup></i> for y.
<dt> psi() <dd>
Gives the alternate golden ratio <i>&psi;</i> (-0.618033...) to the number of decimal
places specified by the current <code>scale</code>.
<dt> pyth(x,y) <dd>
Pythagoras: Calculates the hypotense of a right angled triangle whose other sides
are x and y.
<dt> pyth3(x,y,z) <dd>
Pythagoras 3D: Calculates the long diagonal of a cuboid whose sides are x, y and z.
<dt> remainder(x,y), int_remainder(x,y) <dd>
Calculates the remainder when x is divided by y. The non-integer version works in a
more intuitive manner than bc's built in <code>%</code> (modulus) operator.
<dt> root(x,y) <dd>
Returns an extremely close approximation to <i><sup>y</sup>&radic;x</i>; Copes very
well with negative numbers, fractional exponents etc. always returning a real or
integer root where possible. Will complain and return zero if there is a problem.
<dt> round( x,y) <dd>
Round x to the nearest multiple of y.
<dt> round_down(x,y) <dd>
Round x to the multiple of y less than or equal to x.
<dt> round_up( x,y) <dd>
Round x to the multiple of y greater than or equal to x.
<dt> sec(x) <dd>
Secant
<dt> sech(x) <dd>
Hyperbolic Secant
<dt> sgn(x) <dd>
Returns the sign of x; -1 for negative, 0 for zero, 1 for positive
<dt> sin(x) <dd>
Sine; Is an alias for bc's own <code>s()</code> function.
<dt> sinh(x) <dd>
Hyperbolic sine
<dt> tan(x) <dd>
Tangent
<dt> tanh(x) <dd>
Hyperbolic tangent
<dt> tet(n) <dd>
The n'th tetrahedral number
<dt> tetrt(t) <dd>
"Tetrahedral root": Given a tetrahedral number, returns its index in the sequence
of tetrahedral numbers. Akin to a cube root.
<dt> tri(x) <a name="tri"></a> <dd>
The x'th triangular number
<dt> tri_pred(t) <dd>
Given a triangular number t, returns the next triangular number. Works also for
non triangular numbers, providing a continuum.
<dt> tri_step_(t,s) <dd>
Internal function: Used by the preceding and succeeding entries here...
<dt> tri_succ(t) <dd>
Given a triangular number t, returns the previous triangular number. Works also
for non triangular numbers, providing a continuum.
<dt> trirt(x) <a name="poly"></a> <dd>
"Triangular root": Given a triangular number, returns its index in the sequence of
triangular numbers. Akin to a square root.
<dt> w(x) <dd>
In the manner of bc's own single-letter functions
<code>s(), c(), a(), l(), e()</code> and <code>j()</code>, this provides access to
the <a href="#lambertw">lambertw...</a> functions, choosing the most logical
branch; Minus one for negative x, Zero for positive and zero x.
<dt> w_e(x) <dd>
A shorthand alias for the <code>lambertw0_exp()</code> function, i.e. a better
alternative to <code>w(e(x))</code>.
</dl>
<!-- ==================== G ==================== -->
<!-- ==================== H ==================== -->
<!-- ==================== I ==================== -->
<dt class="filename"><a title="download file" name="intdiff" href="./code/intdiff.bc">intdiff.bc</a><dd>
Perform numerical integration and differentiation of a single variable function.
<ul class="keywords">
<li> Numerical Integration
<li> Numerical Differentiation
<li> Guessing convergence limits
</ul>
<dl class="functions">
<dt> f(x) <dd>
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. <code>define f(x){return sqrt(x)}; ifxdx(2,3)</code>
<dt> dfxdx(x) <dd>
Return the value of the first derivative of f at x.
<dt> glai(p,q,r) <dd>
Guess Limit At Infinity: given three convergents to a limit, this function attempts
to extrapolate the limit at infinity. e.g. <code>glai(63.9, 63.99, 63.999)</code>
returns 64. Uses global variable <code>glaitalk</code> to comment on and warn about
interesting situations. Set this to 0 to turn it off.
<dt> ifxdx(a,b) <dd>
Return the indefinite integral (i.e the area under the curve) of f between a and b.
A global variable called <code>depth</code> is used here (akin to bc's own
<code>scale</code> 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.
<dt> ifxdx_g(a,b) <dd>
As above but uses glai to save on calculations.
</dl>
<dt class="filename"><a title="download file" name="interest" href="./code/interest.bc">interest.bc</a><dd>
Early in 2011, Randy Rysavy, a visitor to this site, contacted me enquiring about the
possibility of adding financial functions to GNU bc. He included some of his own
sample code, which gave me the impetus to produce this suite. Randy's own functions
aren't included here, although there are equivalents and many more besides.<br />
As in other places on this site, the list of functions is not entirely in alphabetical
order so to introduce concepts in a more logical order.<br />
Functions here rely fairly heavily on exponential related functions found in
<a href="#funcs">funcs.bc</a>.
<ul class="keywords">
<li> Interest
<li> Savings & Loan
<li> Amortisation / Mortgage
<li> Financial
</ul>
<dl class="functions">
<dt> fraction_to_rate(fraction) <dd>
This library expects interest rates to be given to functions in the form of 1+percentage/100,
that is, as a number greater than or equal to 1 and less than 2 (for the most part at least).
As such, fractional representations of interest rates (usually given as a decimal number
between 0 and 1 need to be converted before use. This function converts those decimal
fractions into the right range.
<dt> percentage_to_rate(percent) <dd>
This library expects interest rates to be given to functions in the form of 1+percentage/100,
that is, as a number greater than or equal to 1 and less than 2 (for the most part at least).
As such, percentage representations of interest rates (usually given as a decimal number
between 0 and 100 need to be converted before use. This function converts those percentages
into the right range.
<dt> rate_to_fraction(rate) <dd>
Converts the interest rate format used by this library into a decimal fraction.
<dt> rate_to_percentage(rate) <dd>
Converts the interest rate format used by this library into a percentage.
<dt> compound_fc(ic,rate,nt) <dd>
Basic compound interest; Find final capital (fc) from initial (ic) at given rate
and number of terms (nt). e.g. �50 at 3.4% for 20 years (interest added once per year)
becomes <code>compound_fc(50, 1.034, 20)</code> which yields an answer of approximately
�97.58
<dt> compound_ic_from_fc(fc,rate,nt) <dd>
Inverting basic compound interest; Find the initial capital (ic) given the final capital (fc),
the interest rate and the number of terms. e.g. if after 20 years at 3.4%, we have �97.58,
what was the initial investment. This becomes <code>compound_ic_from_fc(97.58, 1.034, 20)</code>
which gives the answer of 49.9977, which is �50 when rounded up to the nearest penny.
<dt> compound_nt_from_fc(fc,ic,rate) <dd>
Inverting basic compound interest; Find the number of interest-adding terms if given the
final capital (fc), initial capital (fc) and the interest rate.
<dt> compound_rate_from_fc(fc,ic,nt) <dd>
Inverting basic compound interest; Find the interest rate given the final capital (fc),
the initial capital (ic) and the number of terms.
<dt> loan_paym(ic,rate,nt) <dd>
Loan amortisation; Determine the payment per term in order to pay off the initial capital (ic)
of a loan given the interest rate and the number of terms (nt). Assumes that interest is always
added before a payment is subtracted from the remaining capital, and that this is done only
once per term. Given that terms are generally years, this is unusual, but not unheard of.
<dt> loan_apaym(*a__[],ic,rate,nt) <dd>
Loan amortisation; Uses the undocumented <nobr>pass-by-reference</nobr> feature of bc in order
to create an array of term-by-term values showing remaining balance when the optimal payment
is taken. To actually determine the optimal term payment, use the related <code>loan_paym</code>
function which, other than the array reference, has the same parameter layout.
<dt> loan_paym_split(ic,rate,nt,spt) <dd>
Loan amortisation; Determine the payment per sub-term (sub-terms tend to be months within a year)
in order to pay off the initial capital (ic) of a loan given the interest rate per term
(terms tend to be years) and the number of terms (nt). Assumes that interest is always
added before a payment is subtracted from the remaining capital.
e.g. To calculate the monthly payment on a mortgage of �125,000 over 25 years at 5.66% APR with
interest and payments being applied and taken monthly, use
<code>loan_paym_split(125000, 1.0566, 25, 12)</code>. This yields a suggested monthly payment
of �768.98 when advantageously (for the borrower) rounding up to the next penny.
<dt> loan_apaym_split(*a__[],ic,rate,nt,spt) <dd>
Loan amortisation; Uses the undocumented <nobr>pass-by-reference</nobr> feature of bc in order
to create an array of subterm-by-subterm values showing remaining balance when the optimal payment
is taken. To actually determine the optimal subterm payment, use the related <code>loan_paym_split</code>
function which, other than the array reference, has the same parameter layout.
<dt> loan_tpaym(ic,rate,nt) <dd>
Loan amortisation; Determine the total payment (tpaym) once the initial capital (ic) has been
fully paid off when given the interest rate and the number of terms (nt). Assumes that interest
is always added before a payment is subtracted from the remaining capital, and that this is done
only once per term. Given that terms are generally years, this is unusual, but not unheard of.
<dt> loan_tpaym_split(ic,rate,nt,spt) <dd>
Loan amortisation; Determine the total payment (tpaym) once the initial capital (ic) has been
fully paid off when given the interest rate per term, the number of terms (usually years) and
number of subterms per term (usually 12 months).
e.g. To calculate sum of all 300 monthly payments on a mortgage of �125,000 over 25 years at
5.66% APR with, use
<code>loan_tpaym_split(125000, 1.0566, 25, 12)</code>. This yields a value suggesting that over
that time, the borrower will have to pay back a total of �230,692.14.
<dt> loan_ic_from_paym(paym,rate,nt) <dd>
Inverting loan amortisation; Given the term payment (paym), the interest rate and
the number of terms, determine what the initial capital (ic) must have been.
<dt> loan_ic_from_paym_split(paym,rate,nt,spt) <dd>
Inverting loan amortisation; Given the sub-term payment (paym), the interest rate per term,
and the number of terms and subterms per term (nt and spt),
determine what the initial capital (ic) must have been.
<dt> loan_ic_from_tpaym(tpaym,rate,nt) <dd>
Inverting loan amortisation; Given the total payment over all terms (tpaym), the interest rate,
and the number of terms (nt), determine what the initial capital (ic) must have been.
<dt> loan_ic_from_tpaym_split(tpaym,rate,nt,spt) <dd>
Inverting loan amortisation; Given the total payment over all sub-terms (tpaym), the interest rate,
the number of terms and subterms per term (nt and spt),
determine what the initial capital (ic) must have been.
<dt> loan_nt_from_paym(paym,ic,rate) <dd>
Inverting loan amortisation; Given the preferred payment per term (paym),
the initial capital borrowed (ic) and the interest rate, determine how many terms
are required to pay off the loan. Given that terms are usually years, this is somewhat unusual
but terms can also be months if a monthly payment is given.
<dt> loan_nt_from_paym_split(paym,ic,rate,spt) <dd>
Inverting loan amortisation; Given the preferred payment per subterm (paym),
the initial capital borrowed (ic), the interest rate and the number of subterms per term (spt),
determine the number of full terms are required to pay off the loan.
<dt> loan_nt_from_tpaym(tpaym,ic,rate) <dd>
Inverting loan amortisation; Given the maximum preferred total payment over all terms (tpaym),
the initial capital borrowed (ic) and the interest rate, determine how many terms
are required to pay off the loan.
<dt> loan_nt_from_tpaym_split(tpaym,ic,rate,spt) <dd>
Inverting loan amortisation; Given the maximum preferred total payment over all subterms (tpaym),
the initial capital borrowed (ic), the interest rate and the number of subterms per term (spt),
determine how many full terms are required to pay off the loan.
<dt> loan_rate_from_paym(paym,ic,nt) <dd>
Inverting loan amortisation; Given the preferred payment per term (paym),
the initial capital borrowed (ic) and the required number of terms (nt),
determine the optimal interest rate which best fits these options.
<dt> loan_rate_from_paym_split(paym,ic,nt,spt) <dd>
Inverting loan amortisation; Given the preferred payment per subterm (paym),
the initial capital borrowed (ic), the required number of terms (nt),
and the number of subterms per term (spt)
determine the optimal interest rate (for a term; usually a year)
which best fits these options.
<dt> loan_rate_from_tpaym(tpaym,ic,nt) <dd>
Inverting loan amortisation; Given the preferred total payment over all terms (tpaym),
the initial capital borrowed (ic) and the required number of terms (nt),
determine the optimal interest rate which best fits these options.
<dt> loan_rate_from_tpaym_split(tpaym,ic,nt,spt) <dd>
Inverting loan amortisation; Given the preferred total payment over all subterms (paym),
the initial capital borrowed (ic), the required number of terms (nt),
and the number of subterms per term (spt)
determine the optimal interest rate (for a term; usually a year)
which best fits these options.
<dt> loan_spt_from_paym(paym,ic,rate,nt) <dd>
Inverting loan amortisation; Given the preferred payment per subterm (paym),
the initial capital borrowed (ic), the interest rate and the number of terms (nt),
determine the required number of subterms per term (spt) in order to correctly pay
off the loan. This function is unlikely to see much use, except as a curiosity;
Most loans are paid back monthly, meaning that given most actual loan data, this
is likely to return an answer somewhere around 12.
<dt> loan_spt_from_tpaym(tpaym,ic,rate,nt) <dd>
Inverting loan amortisation; Given the preferred total payment over all subterms (tpaym),
the initial capital borrowed (ic), the interest rate and the number of terms (nt),
determine the required number of subterms per term (spt) in order to correctly pay
off the loan. As above, this function is included as a curiosity, and will return an answer
somewhere around 12 (months per year) when given actual loan data.
<dt> saving_fc(ic,paym,rate,nt) <dd>
Savings with compound interest; Given a starting amount, that is,
some initial capital (ic), as well as a term-wise (terms here are usually years)
single saving payment (paym) the financial institution's interest rate
and a number of payment terms (nt),
determine the final capital (fc) after those terms are over.
<dt> saving_afc(*a__[],ic,paym,rate,nt) <dd>
Savings with compound interest;
Uses the undocumented <nobr>pass-by-reference</nobr> feature of bc in order
to create an array of term-by-term values showing current balance after interest and payment
have been added. Is otherwise identical to the <code>saving_fc()</code> function.
<dt> saving_fc_split(ic,paym,rate,nt,spt) <dd>
Savings with compound interest; Given a starting amount, that is,
some initial capital (ic), as well as a subterm-wise (subterms here are usually months)
single saving payment (paym) the financial institution's interest rate per term (~yearly)
the number of payment terms (nt), and the number of subterms per term (usually 12 if monthly)
determine the final capital (fc) at the end of that time.
e.g. A prudent saver opens a 3.2% savings account with a lump sum of �5,000,
and then pays in �260 per month over ten years. To find the final capital amount, we use
<code>saving_fc_split(5000, 260, 1.032, 10, 12)</code> which reveals that the final amount
should be somewhere around �43,476.14. With no interest, this would be merely
�5,000 + 10*12*�260 or �36,200.
<dt> saving_afc_split(*a__[],ic,paym,rate,nt,spt) <dd>
Savings with compound interest;
Uses the undocumented <nobr>pass-by-reference</nobr> feature of bc in order
to create an array of subterm-by-subterm values showing current balance after interest and payment
have been added. Is otherwise identical to the <code>saving_fc_split()</code> function.
<dt> saving_ic_from_fc(fc,paym,rate,nt) <dd>
Inverse calculations for savings with compound interest;
Given the final capital (fc) required, the preferred term-wise payment (paym),
the financial institution's interest rate and the preferred number of terms that
the savings are to occur over (nt), determine what initial capital (ic) would be
required in order to make it a reality.
<dt> saving_ic_from_fc_split(fc,paym,rate,nt,spt) <dd>
Inverse calculations for savings with compound interest;
Given the final capital (fc) required, the preferred subterm-wise payment (paym),
the financial institution's interest rate, the preferred number of terms that
the savings are to occur over (nt), and the number of subterms per term (spt)
determine what initial capital (ic) would be required in order to make it a reality.
e.g. in a previous example, an investor started with initial capital of �5,000;
If they wished to have exactly �50,000 at the end of the ten years, how much should they
have started with? This is answered with
<code>saving_ic_from_fc_split(50000,260,1.032,10,12)</code> yielding an answer of �9761.11
when rounded up to the next penny.
<dt> saving_nt_from_fc(fc,ic,paym,rate) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the preferred
term-wise payment and the financial institution's interest rate, determine how many terms (nt),
that is, how long to continue investing, until the requirement is met.
<dt> saving_nt_from_fc_split(fc,ic,paym,rate,spt) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the preferred
term-wise payment, the financial institution's interest rate and the number of subterms per term (spt)
determine how many terms (nt), that is, how long to continue investing, until the requirement is met.
<dt> saving_paym_from_fc(fc,ic,rate,nt) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the
financial institution's interest rate and the number of terms of investment (nt),
determine the optimal term-wise payment (paym) in order to meet the target.
This is unusual as it assumes one lump sum per term, and terms here are usually considered to be years.
<dt> saving_paym_from_fc_split(fc,ic,rate,nt,spt) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the
financial institution's interest rate, the number of terms of investment (nt),
and the number of subterms per term (spt)
determine the optimal subterm-wise (usually monthly) payment in order to meet the target.
<dt> saving_rate_from_fc(fc,ic,paym,nt) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the
preferred term-wise payment (paym) and number of terms of investment (nt),
determine what interest rate would be required from the financial institution in order
to reach the goal. [A pipe dream for sure, as no-one gets to set their own interest rate!]
<dt> saving_rate_from_fc_split(fc,ic,paym,nt,spt) <dd>
Inverse calculations for savings with compound interest;
Given the required final capital (fc), and the initial capital (ic) as well as the
preferred term-wise payment (paym),number of terms of investment (nt),
and number of subterms per term (usually 12 for months per year)
determine what term-wise interest rate would be required from the financial institution
in order to reach the goal.
<dt> saving_spt_from_fc(fc,ic,paym,rate,nt) <dd>
Inverse calculations for savings with compound interest; Another curiosity function
included for the sake of completeness. Given preferred final capital (fc), initial capital (ic),
preferred subterm-wise payment, an interest rate and a number of terms of investment (nt)
determine the number of hypothetical payment and interest increment steps, that is, subterms per term
(spt) required in order to reach the goal. Most ordinary financial data will cause this function to
return 12 (months per year), but pathological cases may cause strange errors or impossible answers.
</dl>
<!-- ==================== J ==================== -->
<!-- ==================== K ==================== -->
<!-- ==================== L ==================== -->
<dt class="filename"><a title="download file" name="logic" href="./code/logic.bc">logic.bc</a><dd>
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.
<p>Some of the functions here will use the global <code>bitwidth</code> 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.
<p>Many functions will display a warning if there is suspicion that a secondary
floating point representation of a number has been generated, e.g. 1.1111... is an
SFPR of 10.0000...; These warnings can be disabled by setting the global variable
<code>sfpr_warn</code> to 0 (default is 1).
<ul class="keywords">
<li> Fixed word size
<li> Infinite word size
<li> Common bitwise
<li> Twos complement
<li> Bit shifting
<li> Gray code
<li> 'Multiplication'
<li> Floating point
<li> Floating point + 'Multiplication'
<li> Gray code + Floating Point
</ul>
<dl class="functions">
<dt> bitwidth(x) <dd>
This function determines the minimal bitwidth needed to contain the value of x.
Effectively an integer logarithm function.
<dt> bw_mult_(sc) <dd>
Internal function: Used along with internal global variables
<code>bw_mult_ml_</code> and <code>bw_mult_sc_</code> to help manage
the floating point bitwise functions.
<dt> checkbitwidth_() <dd>
Internal function: Used to check, before use, that the global
<code>bitwidth</code> variable has not been set to an invalid value.
<dt> and(x,y) <dd>
Performs a bitwise logical AND of x and y.
Uses base 4 internally for faster calculation.
<dt> andf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> bitrev(x) <dd>
Reverse the bits in x. Uses <code>bitwidth</code> if it is nonzero.
<dt> graycode(x) <dd>
Convert x into its Gray code equivalent
<dt> graycodef(x) <dd>
As above but includes any floating point portion which may be present.
<em>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</em>
<dt> hamming(x,y) <dd>
Find the binary <a href="http://en.wikipedia.org/wiki/Hamming_distance">Hamming distance</a>
between two numbers.
<dt> inverse_graycode(x) <dd>
Converts Gray encoded x back into its original bit pattern
<dt> inverse_graycodef(x) <dd>
Floating point inverse Gray code.
All the caveats of the <code>graycodef()</code> function apply.
<dt> is_sfpr_(x) <dd>
Internal function to determine whether <i>x</i> is a secondary floating
point representation (see above).
<dt> is_any_sfpr3_(x,y,z) <dd>
Internal function to determine whether one or more of <i>x</i>, <i>y</i>
or <i>z</i> is a secondary floating point representation (as above).
<dt> not(x) <dd>
Perform a bitwise logical NOT of x. Since these functions use twos
complement, this function returns <em>-1-x</em> which has an exactly
flipped bit representation in 2C.
<dt> or(x,y) <dd>
Perform a bitwise logical OR of x and y.
Uses base 4 internally for faster calculation.
<dt> orf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> orm(x,y) <dd>
'Multiplies' x and y in a no-carry, bitwise manner using logical OR
in place of addition.
<dt> ormf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> resign(x) <dd>
Despite an apparently pessimistic name, this actually RE-applies a SIGN to x,
with the assumption that the current <code>bitwidth</code> is valid. e.g.
if <code>bitwidth</code> is 8, <code>resign(254)</code> is -2. C programmers
will recognise this as effectively casting an unsigned value into a signed
variable of the same size.
<dt> rol(x,n) <dd>
Roll Left: Familiar to assembly programmers, this shifts x left by n places
within the current <code>bitwidth</code> and adds the carried left hand bits
back on the right. e.g. <u>100</u>10011 rolled left by 3 is 10011<u>100</u>
assuming a <code>bitwidth</code> of 8.
<dt> ror(x,n) <dd>
Roll Right: As above but shifts to the right, placing lost right hand bits
back on the left. May well complain if <code>bitwidth</code> is 0 (i.e. implied
infinite), as right hand bits would have to be placed in infinite positions.
<dt> sfpr_warn_msg_() <dd>
Internal function to display the aforementioned warning about SFPRs.
<dt> shl(x,n) <dd>
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 <code>bitwidth</code>.
<dt> shr(x,n) <dd>
Shift Right: Shifts the bits in x right by n places. Bits from the right hand
side are lost
<dt> ungraylike1(x) <dd>
Self-inverse binary permutation of x. At first glance resembles a Graycode style
transformation, but this is not the case, hence "ungraylike".
Reverses the order of all bits after the first.
<dt> ungraylike2(x) <dd>
Another self-inverse binary permutation of x. Also resembles a Graycode style
transformation, but is also not the case.
Reverses the order of and flips all bits after the first.
<dt> unsign(x) <dd>
Interpret a negative number as a positive number within the current
<code>bitwidth</code>. Again, C programmers will recognise this as a cast from
signed to unsigned.
<dt> xor(x,y) <dd>
Perform a bitwise logical XOR (EXCLUSIVE OR) of x and y.
Uses base 4 internally for faster calculation.
<dt> xorf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> xorm(x,y) <dd>
'Multiplies' x and y in a no-carry, bitwise manner using logical XOR
in place of addition.
<dt> xormf(x,y) <dd>
As above but includes any floating point portion which may be present.
</dl>
<dt class="filename"><a title="download file" name="logic_andm" href="./code/logic_andm.bc">logic_andm.bc</a><dd>
Various attempts to create bitwise AND 'multiplication' functions that do not result in zero
<ul class="keywords">
</ul>
<dl class="functions">
<dt> andm(x,y) <dd>
'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.
<dt> andmf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> x1andm(x,y) <dd>
One method of combining the equivalences between AND, OR & XOR alongside their
multiplicative equivalents in order to emulate AND-multiplication
<dt> x1andmf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> x2andm(x,y) <dd>
Second method of combining the equivalences between AND, OR & XOR alongside their
multiplicative equivalents in order to emulate AND-multiplication
<dt> x2andmf(x,y) <dd>
As above but includes any floating point portion which may be present.
</dl>
<dt class="filename"><a title="download file" name="logic_inverse" href="./code/logic_inverse.bc">logic_inverse.bc</a><dd>
<strong> New for February 2013 </strong><br />
Calculation of possible inputs to bitwise AND and OR functions in order to achieve a specific
output, i.e. find inverses, where possible, to bitwise functions.
<ul class="keywords">
<li> Inverse bitwise functions
</ul>
<dl class="functions">
<dt> dand_sor_(which, z,y ,n) <dd>
Internal function; The engine which finds all inverse solutions in this library.
<dt> dand(z,y ,n) <a name="dand"></a> <dd>
"Division AND" / "De-AND";
Attempts to find solutions to bitwise <code>z = and(x,y)</code> for <code>x</code>.
Often, there are multiple solutions or even none at all and so the <code>n</code>
parameter determines the kind of return value to be given by the function.
This can either be a coded representation of all possible solutions; one of the solutions,
should one exist; or even an error code of -1 if there are no solutions. A warning will
also be issued if there are no solutions when a single solution is requested and the
<code>dand_sor_warn_</code> variable is non-zero. This is enabled by default.
Values for <code>n</code> are: <dl>
<dt> n = -4 <dd>
Requests the return of a base 4 (quartal) codification of all solution bits. For the
quartal digits in the return value:
<p> <strong>0</strong> represents the fact that no solution bit is possible for the
respective binary position in a potential solution. Any zero quartal digits in this
codification therefore mean that no solution is possible for the other parameters.
<p> <strong>1</strong> represents that a zero bit and only a zero bit is possible
at the respective binary position in a potential solution.
<p> <strong>2</strong> represents that a one bit and only a one bit is possible at
the respective binary position in a potential solution. Note that in this representation,
zero and one are not represented by their own values, despite there otherwise being some
logic to the assignation of the quartal digits.
<p> <strong>3</strong> represents a don't-care state in that either a zero or a one
bit is suitable for the respective binary position in a potential solution. For every
3 in this representation, the potential number of solutions doubles.
<dt> n = -3 <a name="nem3"></a> <dd>
Requests the return of a base 4 (quartal) codification of all solution bits. For the
quartal digits in the return value:
<p> <strong>0</strong> represents that a zero bit and only a zero bit is possible
at the respective binary position in a potential solution.
<p> <strong>1</strong> represents that a one bit and only a one bit is possible at
the respective binary position in a potential solution. Note that in this representation,
zero and one are represented by their own values, making any direct quartal output
easier to read.
<p> <strong>2</strong> represents a don't-care state in that either a zero or a one
bit is suitable for the respective binary position in a potential solution. For every
2 in this representation, the potential number of solutions doubles.
<p> <strong>3</strong> represents the fact that no solution bit is possible for the
respective binary position in a potential solution. Any '3' quartal digits in this
codification therefore mean that no solution is possible for the other parameters.
<p><em>This quartal representation choice is the default in this library, not least
because the mnemonic is simple: 0 is 0, 1 is 1, and 2 doubles the solution count.</em>
<dt> n = -2 <dd>
Requests the return of the number of possible solutions. Doing this will produce no
warnings as zero solutions is a valid and expected answer in some cases.
<dt> n = -1 <dd>
Requests the return of the number of don't-care states, which is log2 of the number of
solutions. Also does not warn if there are no solutions, but will cause the return of
the more sensible -1, rather than negative infinity, when no solutions exist.
<dt> n &ge; 0 <dd>
Requests the return of the <i>n</i>th solution (Counting from 0 and modulo the number
of solutions. This will be a power of two if any exist.) for the other parameters.
If there are no solutions, a warning will result (assuming the <code>dand_sor_warn_</code>
variable is non-zero) and -1 will be returned instead of a solution.
<p> Note that setting n to 0 guarantees that a solution is returned should one exist.
</dl>
<dt> sor(z,y ,n) <dd>
"SubtractOR" / "SubtORct";
Attempts to find solutions to bitwise <code>z = or(x,y)</code> for <code>x</code>.
Often, there are multiple solutions or even none at all and so the <code>n</code>
parameter determines the kind of return value to be given by the function.
See the definition of <code><a href="#dand">dand</a>()</code> for an explanation of the
values <code>n</code> can take.
<dt> striped_dand(z,y ,n) <dd>
Striped "Division AND" / "De-AND";
Attempts to find solutions to bitwise <code>z = striped_and(x,y)</code> for <code>x</code>.
Often, there are multiple solutions or even none at all and so the <code>n</code>
parameter determines the kind of return value to be given by the function.
See the definition of <code><a href="#dand">dand</a>()</code> for an explanation of the
values <code>n</code> can take.
<p> For an explanation and definition of "striped AND", see this site's
<a href="#logic_striping">logic_striping.bc</a> section.
<dt> striped_sor(z,y ,n) <dd>
Striped "SubtractOR" / "SubtORct";
Attempts to find solutions to bitwise <code>z = striped_or(x,y)</code> for <code>x</code>.
Often, there are multiple solutions or even none at all and so the <code>n</code>
parameter determines the kind of return value to be given by the function.
See the definition of <code><a href="#dand">dand</a>()</code> for an explanation of the
values <code>n</code> can take.
<p> For an explanation and definition of "striped OR", see this site's
<a href="#logic_striping">logic_striping.bc</a> section.
<dt> print_01dx_(x) <dd>
Internal output driver for interpreting and then printing the default
<a href="#nem3"><code>n = -3</code></a> quartal solutions pattern.
<dt> dand_print(z,y) <dd>
Prints a specially formatted quartal string to aid in identifying, by sight, any and all
possible solutions to bitwise <code>z = and(x,y)</code> for <code>x</code>. Output contains
"0" for "position must be 0", "1" for "position must be 1", "d" for "don't care / 0 or 1 is fine"
and "X" for "impossible / fail bit". Any "d"s in an output indicate multiple solutions.
Any "X"es indicate that no solution is possible.
<dt> sor_print(z,y) <dd>
Prints a specially formatted quartal string to aid in identifying, by sight, any and all
possible solutions to bitwise <code>z = or(x,y)</code> for <code>x</code>.
<dt> striped_dand_print(z,y) <dd>
Prints a specially formatted quartal string to aid in identifying, by sight, any and all
possible solutions to bitwise <code>z = striped_and(x,y)</code> for <code>x</code>.
<dt> striped_sor_print(z,y) <dd>
Prints a specially formatted quartal string to aid in identifying, by sight, any and all
possible solutions to bitwise <code>z = striped_or(x,y)</code> for <code>x</code>.
</dl>
<dt class="filename"><a title="download file" name="logic_otherbase" href="./code/logic_otherbase.bc">logic_otherbase.bc</a><dd>
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
<a href="#logic">logic.bc</a>,
although all functions herein will return correct results when base 2 is specified.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> asym_parity(base,x,y) <dd>
A possible XOR extension;
Inverts (i.e. subtracts from base-1) those digits in x which are flagged as to be
flipped by the digits in y.
In even bases, this amounts to "invert digit in x if digit in y is odd."
Is asymmetric in that <code>asym_parity(base, x,y)</code> almost never equals
<code>asym_parity(base,y,x)</code>.
<dt> asym_mixor(base, x,y) <dd>
A second, similarly asymmetric possible extension of bitwise XOR into other number bases;
A blend of <code>no_borrow_diff()</code> and <code>no_carry_add()</code>.
<dt> base_graycode(base,x), inverse_base_graycode(base,x) <dd>
An extension to Graycode into other number bases, preserving the requirement that in
the sequence of Gray codes, no two adjacent codes differ by more than one digit.
<dt> base_hamming(base,x,y) <dd>
As with binary, this is a difference-counting function, returning the total number of
differences between two numbers in a given base. e.g. the number of differences between
1234 and 9284 in base ten is 2, since they differ in the first and third positions (when
read left-to-right). For an alternative to this function which sums the actual
difference, which would be <em>thirteen</em> in this example, see the
<code>digit_distance()</code> function in <a href="#digits">digits.bc</a>.
<dt> digitwise_diff(base, x,y) <dd>
Another possible extension of XOR into other number bases. Akin to, but not to be confused
with the above, as this returns a number rather than a sum of differences.
<dt> digitwise_sdiff(base, x,y) <dd>
A variant of the above, so XOR again. In modulo arithmetic, there are two solutions to
finding the difference between two numbers. e.g. |1-7| modulo ten could be 6 or 4.
This function chooses the lower of the two.
<dt> digitwise_max(base, x,y) <dd>
A logical extension of bitwise OR.
<dt> digitwise_min(base, x,y) <dd>
A logical extension of bitwise AND.
<dt> digitwise_modmult(base, x,y) <dd>
Another logical extension of bitwise AND.
<dt> digitwise_tlumdom(base, x,y) <dd>
Another logical extension of bitwise OR. Note that tlumdom is modmult
backwards; the underlying algorithms are related.
<dt> digitwise_xor_(which, base, x,y) <dd>
Internal function; Contains the main engine for
all of the XOR related functions in this file.
<dt> no_borrow_diff(base, x,y) <dd>
Yet another XOR-like extension.
Takes the difference of digits of x and y, modulo the base, without borrowing from the left.
<dt> no_carry_add(base, x,y) <dd>
A sixth XOR-like extension.
Adds digits of x and y, modulo the base, without carrying any overflow leftwards.
</dl>
<dt class="filename"><a title="download file" name="logic_striping" href="./code/logic_striping.bc">logic_striping.bc</a><dd>
A family of functions related to the bitwise functions which may be useful
for encryption and hashing. Then again they might not. See the
<a href="./logic_striping.txt" target="_blank">text documentation</a>
for more technical information.
<p>These were separated from the main <a href="#logic">logic.bc</a> due to being of questionable
worth, but were given their own file as they are still interesting functions. <em>The latter file
is required for these functions to work correctly.</em>
<ul class="keywords">
<li> Bitwise striping
</ul>
<dl class="functions">
<dt> stripe_(b,x,y) <dd>
Internal function: Engine for striped_and and striped_or
<dt> striped_and(x,y) <dd>
Performs a bitwise logical 'STRIPED AND' of x and y
<dt> striped_andf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> striped_andm(x,y) <dd>
'Multiplies' x and y in a no-carry, bitwise manner using logical
'STRIPED AND' in place of addition.
<dt> striped_andmf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> striped_or(x,y) <dd>
Performs a bitwise logical 'STRIPED OR' of x and y
<dt> striped_orf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> striped_orm(x,y) <dd>
'Multiplies' x and y in a no-carry, bitwise manner using logical
'STRIPED OR' in place of addition.
<dt> striped_ormf(x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> genstripe(override,repeat,x,y) <dd>
A generalisation of the concept behind 'STRIPED AND' and 'STRIPED OR'
creating an infinite class of related bitwise functions.
<dt> genstripef(o,r,x,y) <dd>
As above but includes any floating point portion which may be present.
<dt> genstripem(override,repeat,x,y) <dd>
'Multiplication' as seen many times before here.
<dt> genstripemf(o,r,x,y) <dd>
As above but includes any floating point d�j� vu which may be present.
</dl>
<dt class="filename"><a title="download file" name="logic_striping_meta" href="./code/logic_striping_meta.bc">logic_striping_meta.bc</a><dd>
<strong> New for February 2013 </strong><br />
A library for exploring the mathematics of the striping pattern numbers used
in <a href="#logic_striping">logic_striping.bc</a> which allows integers
to be interpreted in a completely different way to either integer or modular
arithmetic. See the end of the
<a href="./logic_striping.txt" target="_blank">text documentation</a>
for more technical information.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> simplify_stripe_pattern(x) <dd>
Converts x into the minimal stripe pattern value. e.g. if x, interpreted in binary,
is of form <code>1[pattern][pattern]...</code> where the same pattern (bit length
unimportant) repeats to the end of the number, then this function will return the
number whose binary representation is <code>1[pattern]</code>. e.g. when given
the number 26<sub>dec</sub> = 11010<sub>bin</sub>, this function detects and
removes the repeat of '10' at the end and returns 110<sub>bin</sub> = 6<sub>dec</sub>,
likewise, 731<sub>dec</sub> = 1<b>011</b>011<b>011</b><sub>bin</sub> &rarr;
1<b>011</b><sub>bin</sub> = 11<sub>dec</sub>.
This is somewhat similar to finding the smallest congruence in modular arithmetic,
or a prime given a power of that prime.
<dt> next_match_stripe_pattern(x) <dd>
Generates the next stripe pattern in a sequence by appending one iteration of any
repeating bit pattern found after the leading 1. If the bit pattern does not repeat,
the number returned will have two copies of the whole bit string part of its pattern
interpretation. e.g. 1<b>011</b>011 &rarr; 1<b>011</b>011<b>011</b> and
1<b>010011010</b> &rarr; 1<b>010011010</b>010011010.
This is somewhat similar to finding the next largest congruence in modular arithmetic,
or the next largest power of a prime given particular power of that prime.
<dt> rep_stripe_pattern(x,p) <a name="lsm_rsp"></a> <dd>
Takes the entire bit pattern (repeating or otherwise) after the leading 1 in the
binary representation of <code>x</code> and repeats it <code>p</code> times.
e.g. 1<b>010010</b> &rarr; 1<b>010010</b>010010. Note that no simplification of
the bit pattern is performed.
This has similarities to raising a number to a particular power or multiplying unary
numbers.
<p>Negative values of p will invert the bit pattern after the leading 1 before
repeating the pattern the specified number of times.
Indeed all functions here will accept a negative value for their pattern parameter,
interpreting the pattern as its bit-flipped equivalent.
e.g. -1<b>010010</b> &harr; 1<b>101101</b>.
This means that there are technically no 'negative' patterns as they all have a
positive interpretation, similar to how negative numbers are merely an
interpretation of a residue in modular arithmetic.
<dt> repsof_stripe_pattern(x) <dd>
Determines the maximal number of repeats of the bit pattern after the leading 1 in
the binary representation of <code>x</code>. e.g. 1<b>010</b>010<b>010</b>010 has four
copies of the substring '010', and so this function would return 4 given this number.
Note that this could also have been interpreted as two repeats of '010010', but this
is not a maximal solution.
This is similar to determining the power of a prime when given only the value of that
prime power.
<dt> stripe_pattern_to_1c(x) <dd>
Converts a stripe pattern into a 1s complement integer such that the integer is
simply the stripe pattern without the leading 1. Since this would cause ambiguity
for those patterns which begin with a zero (01 = 001 = 0001 etc.), all patterns with
a leading zero are bit flipped and negated. e.g. pattern value 11101 becomes 1101,
but pattern value 10101 becomes -1010.
Note that this is very similar to the procedure for negative values as described
within the definition for <code><a href="#lsm_rsp">rep_stripe_pattern</a>()</code>.
<dt> stripe_pattern_to_2c(x) <dd>
As above, but negative values are calculated as if they are 2s complement, meaning
that when read as a binary value they are one away from the value of the pattern
they represent. e.g. 1011011011 &rarr; -10010010<b>1</b>
<dt> stripe_pattern_from_1c(x) <dd>
Inverse of <code>stripe_pattern_to_1c()</code>; Creates a standard stripe pattern
integer from a 1s complement representation.
<dt> stripe_pattern_from_2c(x) <dd>
Inverse of <code>stripe_pattern_to_2c()</code>; Creates a standard stripe pattern
integer from a 2s complement representation.
<dt> mul_stripe_patterns(x,y) <dd>
A method for combining / multiplying two patterns. The result is equal to the first
pattern repeated either as-is, or bit-flipped, designated by the bits of the second.
This multiplication is not symmetric except if the parameter patterns are powers of
two or one less than a power of two. Indeed this multiplication implies a direct
connection between these numbers and the positive and negative integers.
See comments in code. The number of bits in the result is equal to the product of
the number of bits in the parameters.
<dt> div1_stripe_patterns(z,y) <dd>
Since the above multiplication is not symmetric, there are two division functions.
Given the result of such a multiplication and the right hand side value of the
multiplication, this reconstructs the left hand (or <b>1</b>st) value.
<dt> div2_stripe_patterns(z,x) <dd>
Since the above multiplication is not symmetric, there are two division functions.
Given the result of such a multiplication and the left hand side value of the
multiplication, this reconstructs the right hand (or <b>2</b>nd) value.
<dt> sqrt_stripe_pattern(z) <dd>
Given the result of one of the above multiplications, try to find whether it could
have been the same pattern multiplied by itself.
<dt> mix_stripe_patterns(x,y) <dd>
An alternative and symmetric multiplication of patterns using NXOR. The length of
the resulting pattern is the lowest common multiple (not the product) of the lengths
of the two parameters. Multiplicative-like structure is conserved as is the sign of
the result when considering the previously mentioned mapping of powers of two and
one less than powers of two to negative and positive integers.
<dt> unmix_stripe_patterns(z,x) <dd>
The inverse of the above up to pattern uniqueness in the sense of representing the
same repeating bit string. Given a result of the mix-multiplication and one of the
parameters, reconstruct the other.
<dt> modsum_stripe_patterns(x,y) <dd>
Another method for combining patterns using modular addition, modulo
2<sup>lcm of pattern lengths</sup>.
<dt> unmodsum_stripe_patterns(z,x) <dd>
The inverse of the above up to pattern uniqueness in the sense of representing the
same repeating bit string. Given a result of the modular sum and one of the
parameters, reconstruct the other.
<dt> cat_stripe_patterns(x,y) <dd>
The most basic way of combining patterns, akin to addition; Create a new pattern
by appending one to another. (Cat = catenation). Has the unfortunate side effect of
not properly preserving addition for the aforementioned powers of two and one less than
powers of two. e.g. Adding the pattern akin to -3 to the pattern akin to 2 will not
result in the pattern akin to -1.
<dt> decat_stripe_patterns(z,y) <dd>
An extended inverse of the above. Given a pattern and a supposed right hand parameter
from a prior catenation, chop off the matching segment of the catenation, or else
catenate the bit-flipped version of the right hand parameter. See notes in code.
<dt> decat2_stripe_patterns(z,y) <dd>
A more intelligent version of the above. Removes the largest matching part of the
right hand side of the left parameter relative to the left hand side of the right
parameter's pattern. Any non-matching remainder of the right hand parameter is then
bit flipped and appended to the result as in the previous decatenation. See notes in code.
<dt> undecat2_stripe_patterns(z,y) <dd>
The <em>pi�ce-de-r�sistance</em>; This function preserves the addition of the
power-of-two / one-less-than-power-of-two patterns when interpreted as negative and
positive integers. Removes the largest matching-when-bit-flipped portion of the
right hand side of the left parameter relative to the left hand side of the pattern
of the right parameter, before appending the non-bit-flipped unmatching portion
of the right parameter. See notes in code.
</dl>
<!-- ==================== M ==================== -->
<dt class="filename"><a title="download file" name="melancholy" href="./code/melancholy.bc">melancholy.bc</a> and <a title="download file" name="melancholy_b" href="./code/melancholy_b.bc">melancholy_b.bc</a><dd>
<strong> Twinned for February 2013 </strong><br />
Twin suites of functions for investigating the two kinds of Melancholy Numbers and the
iterations which lead to them. These are a discovery undoubtedly made by many people,
myself included.
<p>Your humble author is guilty of coining the term "melancholy" with the intention of
comparing these with the un<a href="#digits_happy">happy</a> numbers.
See
<a href="https://groups.google.com/group/sci.math/browse_thread/thread/dc56c573714b00b0/">
here</a> for a Usenet discussion on the first and original kind, and also many notes
stored within the bc code in both files.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> is_melancholy(x)
<dt> is_melancholyb(x) <dd>
Returns 1 (true) if x is melancholy, i.e. the iteration does not reach 0,
and 0 otherwise.
<dt> melancholy_chainlength(x)
<dt> melancholyb_chainlength(x) <dd>
Returns the number of iterations required to reach 0 for the given
<i>x</i>. Will return a negative number of iterations if <i>x</i> is
melancholy, which is the number of iterations required before the algorithm
"realises" that it will not reach 0.
<dt> melancholy_lastsqrt(x)
<dt> melancholyb_lastsqrt(x) <dd>
The nature of the melancholy algorithm is such that a square number immediately
leads to 0, meaning that <i>x</i> is not melancholy. This function gives the
square root of that final perfect square.
<dt> melancholy_loopsize(x)
<dt> melancholyb_loopsize(x) <dd>
Returns the number of iterations in the loop encountered by numbers that are
melancholy.
<dt> melancholy_max(x)
<dt> melancholyb_max(x) <dd>
During determining whether the iteration of <i>x</i> will eventually reach 0,
the iterates rise and fall much like those of the <a href="#collatz">Collatz</a>
conjecture. This returns the largest number encountered before reaching zero,
or else prior to detecting a loop.
<dt> melancholy_print(x)
<dt> melancholyb_print(x) <dd>
Shows all the iterations down to 0 if the number is not melancholy, or else stops
once a loop is detected.
<dt> melancholy_root(x)
<dt> melancholyb_root(x) <dd>
Shows 0 if the number is not melancholy, or else the smallest number in the loop
that a melancholy number becomes trapped within.
<dt> is_melancholy_sg(x)
<dt> is_melancholyb_sg(x) <dd>
sg = "set globals": This function is all of the above rolled into one, and will
set global variables by the names of the above functions
(e.g. <code>melancholyb_max</code>) for the parameters given.
f the global variable <code>melancholy_print</code> is set to 1, then this function
will also behave as the <code>melancholy_print()</code> function and
display the value of the iterations. Set to 0 to turn the feature off again.
Like <code>is_melancholy()</code>, returns 1 if <i>x</i> is melancholy and 0 otherwise.
</dl>
<dt class="filename"><a title="download file" name="misc_235" href="./code/misc_235.bc">misc_235.bc</a><dd>
Find the sum of powers of 2, 3 and 5 that are closest to a number
<ul class="keywords">
</ul>
<dl class="functions">
<dt> print235(x) <dd>
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.
</dl>
<dt class="filename"><a title="download file" name="misc_ack" href="./code/misc_ack.bc">misc_ack.bc</a><dd>
Calculate the hyper-exponential Ackermann function; <em>All but useless given
that bc can't cope with such huge numbers!</em>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> ack(x,y) <dd>
Tries to calculate the Ackermann function
<dt> ackz(x,y) <dd>
As above, but works better (when it works at all) for floating point values
</dl>
<dt class="filename"><a title="download file" name="misc_anglepow" href="./code/misc_anglepow.bc">misc_anglepow.bc</a><dd>
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
<a href="http://www.research.att.com/projects/OEIS?Anum=A037124">A037124</a>]
<ul class="keywords">
</ul>
<dl class="functions">
<dt> anglepow10(x) <dd>
Calculates the x'th entry in the above sequence
<dt> anglelog10(x) <dd>
Calculates the inverse of the above
<dt> anglepow(b,x) <dd>
An extension of anglepow10 to all number bases b
<dt> anglelog(b,x) <dd>
Calculates the inverse of the above
</dl>
<dt class="filename"><a title="download file" name="misc_perfectpow" href="./code/misc_perfectpow.bc">misc_perfectpow.bc</a><dd>
Find the nearest perfect power to a number
<ul class="keywords">
</ul>
<dl class="functions">
<dt> nearest_perfect_power(x) <dd>
Finds the nearest perfect power to x, e.g. the nearest perfect power to 31 is 32
which is 2<sup>5</sup>. In the case of a tie, chooses the lower option, e.g. 26 is
midway between 5<sup>2</sup> = 25 and 3<sup>3</sup> = 27 and so 25 is returned.
<dt> nearest_perfect_power_a(*a__[],x) <dd>
As above, but uses the undocumented pass-by-reference for arrays to store extra
information into the given array. Array element 0 is set to the perfect power itself,
elements 1 and 2 are the root of the power and it's radix, and the third element
is the sign of x. e.g. x = -124 would cause the array to contain {125,5,3,-1} because
125 = 5<sup>3</sup> and the input was negative.
</dl>
<dt class="filename"><a title="download file" name="misc_srr" href="./code/misc_srr.bc">misc_srr.bc</a><dd>
<!-- Note to self: Rewrite this in 21st century web code style :-/ -->
The Sum of Repeated Roots function<br />
The mathematical formula for this interesting function is:<br />
<table cellspacing=0 cellpadding=0 align=center>
<tr><td>
SRR(<i>x</i>) =
</td><td>
<table cellspacing=0 cellpadding=0>
<tr><td align=center>&infin;</td></tr>
<tr><td align=center><font size=+3>&Sigma;</font></td></tr>
<tr><td align=center><font size=-1>n = 1</font></td></tr>
</table>
</td><td>
<i>x</i><sup>2<sup><i>-n</i></sup></sup> - 1
</td></tr>
</table><br />
Or as simply as possible: <code>srr(x) = sum[n=1..oo] x^(2^(-n))-1</code>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> srr(x) <dd>
The function as described above.
<dt> srr_n(n,x) <dd>
A generalisation of srr, which uses the nth root rather than the square root.
<code>srr_n(2,x)</code> is equivalent to <code>srr(x)</code>
</dl>
<!-- ==================== N ==================== -->
<!-- ==================== O ==================== -->
<dt class="filename"><a title="download file" name="orialc" href="./code/orialc.bc">orialc.bc</a><dd>
Extensions and unusual variants of factorial-related functions. Requires
all three of <a href="#funcs">funcs.bc</a>, <a href="#factorial">factorial.bc</a>
and <a href="#primes">primes.bc</a> in order for all functions to work.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> lcmultorialc(x) <dd>
Simple and logical extension to the <code>lcmultorial()</code> as found in
<a href="#factorial">factorial.bc</a>. Simply multiplies by a fractional power
of the next LCMultorial.
<dt> primorialc(x) <dd>
Dummy function which suggests the use of any of the other <code>primorialc</code> alternatives.
<dt> primorialc_fact(x) <dd>
An attempt to extend the primorial function over the reals by using the <code>factorial()</code>
function as a substrate.
<dt> primorialc_nextp(x) <dd>
A very simple extension to the primorial which multiplies by a fractional power of the next prime
when given a non-prime argument.
<dt> primorialc_self(x) <dd>
Another simple extension to the primorial; Multiplies by a fractional power of the argument when
it is not prime.
<dt> primorialc_backstep(x) <dd>
A more complicated combination of the above two functions. Calculates the next highest primorial
and then uses the parameter to determine which fractional power of parameter to divide by to
find a sensible intermediate value.
<dt> primorialc_accident(x) <dd>
An incorrect version of the above which has a serendipidous bug leading not only to sensible
values for the extended primorial, but also has some instances for non-prime integer argument
where the result is actually rational. Examples may be found in the source code.
<dt> submodorial(x) <dd>
Submodulus superprimorial / Product of remainders / Product of x mod k for 2 &le; k &lt; x
See <a href="http://oeis.org/A180491">A180491</a> in the OEIS.
<dt> submodorialg(n,x) <dd>
Generalised version of the above; Product of n+(x mod k) for 2 &le; k &lt; x
<dt> lcmsubmodorial(x) <dd>
LCM of remainders / LCM of x mod k for 2 &le; k &lt; x.
LCM equivalent of <code>submodorial</code>.
<dt> lcmsubmodorialg(n,x) <dd>
Generalised version of the above; LCM of n+(x mod k) for 2 &le; k &lt; x.
LCM equivalent of <code>submodorialg</code>.
</dl>
<dt class="filename"><a title="download file" name="output_formatting" href="./code/output_formatting.bc">output_formatting.bc</a><dd>
<strong> Updated for June 2012 </strong><br />
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.
<ul class="keywords">
<li> Bases &le; 36
<li> Base 27 (and others) with letters
<li> Bijective representations
<li> Negative base representations
<li> Fractions
<li> PrintF (C-like)
<li> Commas
<li> Truncation / Rounding
</ul>
<dl class="functions">
<dt> comma_(x,gp) <dd>
Internal function: Engine for commaprint.
<dt> commaprint(x,g) <dd>
Print x with groups of digits of size g, separated by commas.
e.g. commaprint(1020304,3) prints 1,020,304
<dt> intprint(w, n) <dd>
Print integer n within a field width of w characters.
<dt> letterl__(a), letteru__(a), letter_(mode, a) <dd>
Internal functions which print specific letters or digits given particular values of a.
Lower case; upper case; mode sets alphanumeric or alpha-only.
<dt> newline() <dd>
Prints a newline
<dt> printbase(x) <dd>
By default bc will use decimal groups for 'digits' when outputting
numbers with <code>obase</code> set above 16.
When <code>obase</code> &le; 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 <code>obase</code>, so no base
need be specified as a parameter.<br />
Lowercase letters can be specified by setting the global variable
<code>output_lcase_</code> to 1. The default is 0, since bc usually prints
its letter digits in uppercase.
<dt> printbase_letters(x) <dd>
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. Again, setting <code>output_lcase_</code> to 1 will enforce lowercase.
<dt> printbijective(bbase,x) <dd>
Display x in the
<a href="http://en.wikipedia.org/wiki/Bijective_numeration">bijective base</a>
specified by bbase, which may be positive or negative.
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.
<em>
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.
</em>
<dt> printbijective_letters(bbase,x) <dd>
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.
<dt> printsbase(base,x) <dd>
An all-in-one function that chooses which of the above four functions to call
based on various global variables and settings. The first of these is the global
<code>bijective</code> variable which is also found in <a href="#digits">digits.bc</a>;
When set to 1, it indicates bijective numeration output. The second is the global
variable <code>printsbase_letters_</code> which if set to 1, indicates that
the output should be in letter form only.
<dt> printsobase(x) <dd>
As above, with the exception that the function will use bc's own <code>obase</code>
global variable to specify the output base.
<dt> printfactorialbase(x) <dd>
Show the representation of x in the
<a href="http://en.wikipedia.org/wiki/Factorial_number_system">factoradic</a>
or factorial number base. Uses global variable <code>pfactb_zero_</code> to
specify whether the zeros for the 1! and 1/1! digit places are displayed.
This is set to 0 by default and so these zeros are not displayed.
Spaces are placed between digit places and individual digits are displayed
in the current <code>obase</code>.
<dt> printnegabase_(base,x) <dd>
Internal function; Used by the above functions with a <code>base</code> or
<code>bbase</code> parameter to allow them to support printing of numbers
in negative bases.
<dt> printdms(x) <dd>
Treat x as a number of hours and print it in hh:mm:ss format.
<dt> printff(width, precision, n) <dd>
A function styled after the C syntax:
<code>printf("%*.*f",width,precision,n)</code>;
There are some minor differences however:<ul>
<li>
If width is negative, n is aligned to the left hand side of the field
</li>
<li>
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.
</li>
<li>
If precision is set to zero, no decimal point nor fractional part of n
will be displayed.
</li>
<li>
If precision is 0.0 (bc can tell the difference between 0 and 0.0), the
above two features are combined.
</li>
</ul>
<dt> printfe(width, precision, n) <dd>
A function styled after the C syntax:
<code>printf("%*.*e",width,precision,n)</code>;
In addition to having the same features as for printff, above:<ul>
<li>
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 <code>obase</code>, and so is not always 3.
</li>
</ul>
<dt> printfrac(improper, maxdenom, x) <dd>
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. <em>Returns the
value of the fraction printed and not the original value of x.</em>
<dt> printsft(a,b) <dd>
Prints a and b as an improper fraction in Smallest Fractional Terms.
Requires the GCD function from <a href="#funcs">funcs.bc</a>
<dt> printspc(n) <dd>
Prints the specified number of spaces.
<dt> printtabs(n) <dd>
Prints the specified number of tabs.
<dt> trunc(x) <dd>
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.
</dl>
<dt class="filename"><a title="download file" name="output_graph" href="./code/output_graph.bc">output_graph.bc</a><dd>
A rudimentary console-based graphics package. Uses a global array called
<code>screen[]</code> to store a very simple 'bitmap' made up of characters.
The x and y dimensions are set with global variables <code>screen_x</code>
and <code>screen_y</code>.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> or_(x,y) <dd>
Internal function: Bitwise OR. See <a href="#logic">logic.bc</a> for the
fully fledged version of this function.
<dt> screen_clear() <dd>
Blanks out the global <code>screen[]</code> array.
<dt> screen_axes(xx,yy) <dd>
Draws axes with an origin at coordinates (xx,yy) into <code>screen[]</code>
Returns 0 if (xx,yy) is out of bounds and 1 otherwise
<dt> screen_plot(x,y,c) <dd>
Put the character specified by c into <code>screen[]</code> 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.
<dt> screen_print() <dd>
Actually display the intended interpretation of the contents of
<code>screen[]</code> onto the console.
<dt> screen_printchar_(c) <dd>
Internal function: Prints a character specified by c.
</dl>
<dt class="filename"><a title="download file" name="output_roman" href="./code/output_roman.bc">output_roman.bc</a><dd>
A one-function library for displaying numbers in Roman style.
<ul class="keywords">
<li> Roman Numerals
</ul>
<dl class="functions">
<dt> printroman(n) <dd>
Outputs n to the console in Roman numerals. Uses N (nulla) for zero, bracketed
notation for thousands, millions, etc, and fractions are given in duodecimal
unciae notation ("S::.")<br />
Can use the <code>output_lcase_</code> global variable, also found in the main
<a href="#output_formatting">output_formatting.bc</a>, to specify lowercase
numerals. Set it to 1 to enable this mode. Default is 0.
</dl>
<!-- ==================== P ==================== -->
<dt class="filename"><a title="download file" name="primes" href="./code/primes.bc">primes.bc</a><dd>
<strong> Updated for February 2013 </strong><br />
A mostly naive implementation of prime number handling, with one exception:
Contains a relatively powerful primality checker.
<p> Many functions can be given a speed boost by using one of the prime databases
available on this site and running the <code>fillprimearray()</code> function in
<a href="#primes_db_code">primes_db_code.bc</a>. This will fill the global <code>prime[]</code>
array which the other functions can use as a reference but all functions can operate without
that add-on. A word of caution however, regardless of whether a prime database is loaded:
The main factorisation engine is a glorified Eratosthenes' sieve and so any functions here which
rely on that engine may take a while to run.
</p><p> To offset this somewhat, the last factorisation is always stored in global array
<code>factorpow[]</code> so follow-up calculations on the same number do not need to
perform the same factorisation again.
</p>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> arithmetic_derivative(x) <dd>
Calculate the so-called
<a href="http://en.wikipedia.org/wiki/Arithmetic_derivative">Arithmetic derivative</a>
of x, using new internal factorisation storage routines.
<dt> count_divisors(x) <dd>
Also known as the sigma or sigma-zero function (see below), returns the total number
of divisors of x, including 1 and x itself.
<dt> count_factors(x) <dd>
Returns the number of prime factors of x, counting primes more than once if necessary.
<dt> count_unique_factors(x) <dd>
Returns the number of unique prime factors of x, i.e. ignoring powers.
<dt> core(x) <dd>
Find the squarefree core of x, i.e. the product of all primes which have an odd power
in the factorisation of x.
<dt> divisors_print(x) <dd>
Prints a partially ordered list of the divisors of x
<dt> divisors_sp_(*divs[],x,print_) <dd>
Internal function used by the immediately above and below.
<dt> divisors_store(*d[],x) <dd>
Stores a partially ordered list of the divisors of x into an array given as the first
parameter. Preference is given to divisors &le;&radic;x if the array is too small
to hold all divisors; Larger divisors can be reconstructed from these.
This uses the undocumented <nobr>pass-by-reference</nobr> feature of bc.
<dt> fac_print(x) <dd>
Formerly known as <code>fac(x)</code>; Prints the prime factorisation of x
<dt> fac_sp_innerloop_() <dd>
<dt> fac_sp_(*fp[],x,print_) <dd>
<dt> fac_store_(*fp[],m,p,c,print_) <dd>
<dt> factorpow_set_(fp[]) <dd>
Internal functions; These three are called by each other as well as the immediately
above and below (print and store) functions
<dt> fac_store(*fp[],x) <dd>
Stores the prime factorisation of x into an array given as the first parameter.
As before, this uses the undocumented <nobr>pass-by-reference</nobr> feature of bc.
The array format is {prime_factor,power,prime_factor,power,...}. This function is
also used internally by many other functions for calculations on factorisations.
<dt> has_freedom(x,y) <dd>
Determine whether x is y'th power-free. Returns 0 if the number is not power-free,
but returns non-zero otherwise (not necessarily 1). When y = 1, defaults to returning
whether x is prime. When y = 2, returns the Mobius function. For y > 2, returns a logical
but non-standard extension to the Mobius function.
<dt> int_gcd(x,y) <dd>
Integer-only greatest common divisor function. This can also be found in
<a href="#funcs">funcs.bc</a>.
<dt> int_modpow(x,y,m) <dd>
Quickly determine the value of <i>x<sup>y</sup></i> mod <i>m</i> for
x, y and m all positive integers.
<dt> int_modpow_(x,y,m) <dd>
Internal function, used by the above.
<dt> is_perfect_totient(x) <dd>
Returns whether a number is a so-called
<a href="http://en.wikipedia.org/wiki/Perfect_totient_number">perfect totient number</a>.
<dt> is_perrin_pseudoprime(p) <dd>
Determine whether p is a
<a href="http://mathworld.wolfram.com/PerrinPseudoprime.html">Perrin pseudoprime</a>.
Also performs a very basic Mersenne primality check.
<dt> is_practical(x) <dd>
Returns whether a number is a so-called
<a href="http://en.wikipedia.org/wiki/Practical_number">practical number</a>.
<dt> is_prime(x) <dd>
A powerful primality checker which combines the pseudoprime tests herein
to determine whether x is extremely probably prime. If zero is returned, x is most
definitely not prime. May take a while to return 1 in certain cases, but is almost
certain to be correct if it does. Estimates suggest less than 1 in 10<sup>1000</sup>
candidates would be misidentified.
<p>Be aware that this function takes advantage of all pseudoprime tests in this
file and so accuracy is susceptible to how the <code>rabin_miller_maxtests_</code>
global variable is set.
<dt> is_prime_td(x) <dd>
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.
<dt> is_rabin_miller_pseudoprime(p) <dd>
Determine whether p is a
<a href="http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test">
Rabin-Miller pseudoprime
</a>.
Performs multiple RM tests, to achieve high certainty of primality.
The global variable <code>rabin_miller_maxtests_</code>, when set to a positive value,
determines the maximum number of RM tests this function performs. This reduces
time to execute at the expense of accuracy. By default this is set to 0, meaning
run until almost certain the number is prime.
<dt> is_small_division_pseudoprime(x) <dd>
Confirms that x is indivisible by a significant number of small primes
<dt> largest_prime_factor(x) <dd>
Returns the largest prime factor of x; A full factorisation has to be performed,
so this has more in common with other functions here than with its counterpart
<code>smallest_prime_factor()</code>.
<dt> largest_prime_power(x) <dd>
Returns whichever prime factor of x, when raised to its power from the full
factorisation of x, is the largest.
<dt> primorial(n) <dd>
Returns the product of all primes &le; n. See <a href="#orialc">orialc.bc</a> for
a few possible extensions of the primorial to all numbers.
<dt> mobius(x) <dd>
The Mobius function: Returns 0 if <i>x</i> is not prime, or else -1 or 1 depending on
the powers of the primes in <i>x</i>. Is an alias for <code>has_freedom(x,2)</code>.
<dt> nextprime(n) <dd>
Returns the nearest prime &gt; n; Relies on the <code>is_prime()</code> function
when searching for candidates, so may take a while to find an answer.
<dt> nextprime_ifnotprime(n) <dd>
Returns the nearest prime &ge; n
<dt> nearestprime(n) <dd>
Returns the nearest prime to n, or n if n is prime;
Relies on the <code>is_prime()</code>, <code>prevprime()</code>, and
<code>nextprime()</code> functions when searching for candidates,
so may take a while to find an answer.
<dt> prevprime(n) <dd>
Returns the nearest prime &lt; n; Relies on the <code>is_prime()</code> function
when searching for candidates, so may take a while to find an answer.
<dt> prevprime_ifnotprime(n) <dd>
Returns the nearest prime &le; n
<dt> printfactorpow(fp[]) <dd>
Prints the contents of the array interpreted as a prime factorisation. Expects the array
to be of the form {prime_factor,power,prime_factor,power,...} as created by the
<code> fac_store() </code> function.
<dt> rad(x) <dd>
Integer radical function; Returns the largest power-free number which is a divisor of x.
<dt> ramanujan_c(q,n) <dd>
<a href="http://en.wikipedia.org/wiki/Ramanujan%27s_sum">Srinivasa Ramanujan's sum</a>
<dt> sigma(n,x) <dd>
Sum of divisors function, with the extension of raising the divisors to the power n
before summation. When n is 0, this is equivalent to the <code>count_divisors()</code>
function. When n is 1, it is equivalent to the <code>sum_of_divisors()</code> function below.
<dt> smallest_prime_factor(x) <dd>
Returns the smallest prime factor of x; If this value is all that is required, this function
is often much faster than performing a full factorisation as it stops once the factor is found.
<dt> squarepart(x) <dd>
Determine the square part of x, i.e. find the largest square number which is a divisor of x.
<dt> sum_of_divisors(x) <dd>
Simple sum of divisors function. Is an alias for <code>sigma(1,x)</code>.
<dt> totient(x) <dd>
Euler totient function; Returns the number of integers less than or equal to x
which are coprime to x.
<dt> totient_itercount(x) <dd>
Returns how many times the Euler totient function must be applied to x in order to reach 1.
<dt> totient_itersum(x) <dd>
Returns the sum of intermediate terms as the Euler totient function is repeatedly applied to x
in order to reach 1.
</dl>
<dt class="filename"><a title="download file" name="primes_db"
href="./code/primes_db_old/primes_db.bc">primes_db.bc</a> (Deprecated) <dd>
A database of primes in an array called <code>prime[]</code>. Contains all primes from
the first to the 65,535th. This idea was independently discovered, but is identical to
a technique found in the <a href="http://x-bc.sourceforge.net">X-bc</a> project.
<p>
To distinguish their project from this one, this file was generated by native,
independent bc code and is "compressed" through use of hexadecimal.
</p>
<p><em><strong>
NB: Even though this file is accurate, it is now deprecated and one of the other
prime databases should be used instead.
</strong></em></p>
<p>
* This file is not included in the main site ZIP download.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> None <dd>
There is only the <code>prime[]</code> array
</dl>
<dt class="filename"><a title="download file" name="primes_db_code"
href="./code/primes_db_code.bc">primes_db_code.bc</a><dd>
<strong> Fixed for February 2013 </strong><br />
Code for accessing the packed primes databases below, the main two of which take the form of
the standard mathematical nth-prime and prime counting (primepi) functions.
<ul class="keywords">
<li> Prime counting function </li>
<li> Finding the nth prime </li>
</ul>
<dl class="functions">
<dt> fillprimearray() <dd>
Quickly unpacks the first 65,535 primes into the global <code>prime[]</code> array from whichever
version of the packed primes database has been loaded at the same time as this file.
None of the provided databases contain less than this number so no error should result as long
as at least one of them is loaded.
<dt> prime(n) <dd>
Returns the nth prime; Can only return answers available in whichever
version of the packed primes database has been loaded at the same time as this file.
Will return an error stating the limitation if it cannot find an answer.
<dt> primepi(x) <dd>
Returns the number of primes &le; x; Can only return answers available in whichever
version of the packed primes database has been loaded at the same time as this file.
Will return an error stating the limitation if it cannot find an answer.
<dt> makemods2310_() <dd>
Internal function: Creates global metadata arrays used by the above functions for
fast access to a packed prime database.
</dl>
<dt class="filename"><a title="download file" name="primes_db_minipack"
href="./code/primes_db_minipack.bc">primes_db_minipack.bc</a><dd>
The primes from 13 to 822347 packed using hexadecimal bc code into a global bit array
called <code>pd_[]</code>.
<p>This and <a href="#primes_db_code">primes_db_code.bc</a> effectively replace the older
<a href="#primes_db">primes_db.bc</a> database; The old database is well over
1MB in size whereas this and the above are under 53kB.</p>
<p>Like the other data packs below, a global variable, <code>pd_max_</code> is set so
that if data packs are loaded in the wrong order or in a manner such that they overlap,
a warning will result. A <code>pd_max_</code>-related load error can mean the database
is incomplete or two files have been loaded which contain the same data.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> None <dd>
There is only the <code>pd_[]</code> array
</dl>
<dt class="filename">
<a title="download file" name="primes_db_bigpack"
href="./code/primes_db_bigpack/0000-0FFF.bc">primes_db_bigpack/0000-0FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/1000-1FFF.bc">1000-1FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/2000-2FFF.bc">2000-2FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/3000-3FFF.bc">3000-3FFF.bc</a><br />
<a title="download file" href="./code/primes_db_bigpack/4000-4FFF.bc">primes_db_bigpack/4000-4FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/5000-5FFF.bc">5000-5FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/6000-6FFF.bc">6000-6FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/7000-7FFF.bc">7000-7FFF.bc</a><br />
<a title="download file" href="./code/primes_db_bigpack/8000-8FFF.bc">primes_db_bigpack/8000-8FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/9000-9FFF.bc">9000-9FFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/A000-AFFF.bc">A000-AFFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/B000-BFFF.bc">B000-BFFF.bc</a><br />
<a title="download file" href="./code/primes_db_bigpack/C000-CFFF.bc">primes_db_bigpack/C000-CFFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/D000-DFFF.bc">D000-DFFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/E000-EFFF.bc">E000-EFFF.bc</a> -
<a title="download file" href="./code/primes_db_bigpack/F000-FFFF.bc">F000-FFFF.bc</a><dd>
The 8.5 million primes from 13 to 151,388,137 packed using hexadecimal bc code into a
global bit array called <code>pd_[]</code>.
<p>Each consecutive file contains the next 4096 entries of the full database, accessible
through the functions in <a href="#primes_db_code">primes_db_code.bc</a>.
<p>In total, these files weigh in at a grand total of 8.53MB, and since bc can take a
while to load files given to it on the command line, only as much of the database as
is needed can be loaded if the database is split into files this way.
<p>Given that these files take time to load, especially if more than one is used,
they display a message after they have loaded so that the user is aware that something
is happening rather than a hung bc session.
<p>In each of these packs, a global variable, <code>pd_max_</code> is set so
that if data packs are loaded in the wrong order or in a manner such that they overlap,
a warning will result. A <code>pd_max_</code>-related load error can mean the database
is incomplete or two files have been loaded which contain the same data.
<p>
* These files are not included in the main site ZIP download.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> None <dd>
There is only the <code>pd_[]</code> array
</dl>
<dt class="filename"><a title="download file" name="primes_db_bigpack_onefile"
href="./code/primes_db_bigpack_onefile/0000-FFFF.bc">primes_db_bigpack_onefile/0000-FFFF.bc</a><dd>
The 8.5 million primes from 13 to 151,388,137 packed using hexadecimal bc code into a
global bit array called <code>pd_[]</code>.
<p>This is the full database available in the above files as one huge block.
The data is accessible through the functions in
<a href="#primes_db_code">primes_db_code.bc</a>.
<p>This file weighs in at a grand total of 8.53MB, and bc necessarily takes a very long
time to load it into memory from disk. During the loading, a message is continually
updated on-screen as each block of 4096 entries is loaded into the <code>pd_[]</code>
array to avoid giving the impression of a hung bc session. <em> Warning: This file will
take on the order of 15 seconds to load on even the fastest 2011 home computer! </em>
<p>In each of these packs, a global variable, <code>pd_max_</code> is set so
that if data packs are loaded in the wrong order or in a manner such that they overlap,
a warning will result. A <code>pd_max_</code>-related load error can mean the database
is incomplete or two files have been loaded which contain the same data.
<p>
* For obvious reasons, this file is not included in the main site ZIP download.
<ul class="keywords">
</ul>
<dl class="functions">
<dt> None <dd>
There is only the <code>pd_[]</code> array
</dl>
<dt class="filename"><a title="download file" name="primes_other" href="./code/primes_other.bc">primes_other.bc</a><dd>
The chaff of interesting but unnecessary functions that would otherwise be
included elsewhere. Also, all functions here require <a href="#funcs">funcs.bc</a>
in order to run.
<ul class="keywords">
<li> Prime counting function (approximation) </li>
<li> Guessing the nth prime </li>
</ul>
<dl class="functions">
<dt> aprimepi(x) <dd>
An approximation to the prime counting function, <i>&pi;(x)</i>;
Gives an estimate of the number of primes &le; x
<dt> aq(x) <dd>
A Questionable (prime): Turns x into either 2, 3 or base 6 pseudoprime.
<em>All primes are of form 2, 3 or <i>6n&plusmn;1</i> for some integer n.</em>
<dt> iaq(x) <dd>
Inverse of the above; Guaranteed to return a unique value for every prime x.
<dt> aq30(x) <dd>
A Questionable (prime; base) 30: Turns x into 2, 3, 5 or a base 30 pseudoprime.
<em>All primes are of form 2, 3, 5 or <i>30n&plusmn;{1,7,11,13}</i>
for some integer n.</em>
<dt> iaq30(x) <dd>
Inverse of the above; Guaranteed to return a unique value for every prime x.
<dt> fastguessprime(n) <dd>
Uses aprimepi() to find a number very approximately equal to the nth prime.
<em>Not guaranteed to return a prime number and almost certainly not the nth prime,
but is much faster than the following.</em>
<dt> guessprime(n) <dd>
Uses the above as well as nearestprime() from <a href="#primes">primes.bc</a>
to find a prime very approximately equal to the nth prime.
<em>Almost never actually gives the nth prime, but is guaranteed
to return a prime number somewhere near it (usually within 0.5%).</em>
<dt> sum_of_factors(x) <dd>
Adds together the individual prime factors of a number. e.g. 150 = 2*3*5*5 which
becomes 2+3+5+5, and so the result is 15.
<dt> sum_of_factor_terms(x) <dd>
Adds together the prime power factors of a number. e.g. 150 = 2*3*5<sup>2</sup>
which becomes 2+3+5<sup>2</sup> = 30.
<dt> factor_invert(x) <dd>
Raises the powers of prime factors to the power of their primes and re-multiplies
</dl>
<dt class="filename"><a title="download file" name="primes_twin" href="./code/primes_twin.bc">primes_twin.bc</a><dd>
Three functions based upon and requiring the main <a href="#primes">primes.bc</a> for
faster investigation into twin primes.
<ul class="keywords">
<li> Twin Primes
</ul>
<dl class="functions">
<dt> is_twin_prime(x) <dd>
Determines whether x is a member of a prime twin pair. Returns zero if it is not, or else
returns <em>the other twin</em> if it is.
<dt> nexttwinprime(x) <dd>
Returns the nearest twin prime &gt; x
<dt> prevtwinprime(x) <dd>
Returns the nearest twin prime &lt; x
</dl>
<!-- ==================== Q ==================== -->
<!-- ==================== R ==================== -->
<dt class="filename"><a title="download file" name="rand" href="./code/rand/rand.bc">rand.bc</a><dd>
<strong> Modified for February 2013 </strong><br />
A floating-point based random number generator. Since bc has no method of
obtaining an initial seed, use of <a href="./code/rand/randbc">randbc</a>
is highly recommended. For a sample guessing game which uses this library
see <a href="./code/rand/guess.bci">guess.bci</a>
<ul class="keywords">
</ul>
<dl class="functions">
<dt> rand(x) <dd>
For values of x &lt; 0, this will call the srand function with -x as a parameter.
<br />
For values of x &lt; 1, will return the previous random number, i.e. the same as
the last time the function was called. <em>This is 0 if not previously called.</em>
<br />
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 <code>scale</code>.
<br />
For integer values of x &gt; 1, will return an integer between 1 and x.
<br />
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.
<dt> srand(x) <dd>
Resets the internal random seed based on the value of x
</dl>
<!-- ==================== S ==================== -->
<!-- ==================== T ==================== -->
<dt class="filename"><a title="download file" name="thermometer" href="./code/thermometer.bc">thermometer.bc</a><dd>
Temperature scale conversions amongst the five most common scales.
<ul class="keywords">
<li> Celcius / centigrade
<li> Farenheit
<li> Rankin
<li> R�amur
<li> Kelvin
</ul>
<dl class="functions">
<dt> kelvin_to_celcius(k) <dt> kelvin_to_farenheit(k) <dt> kelvin_to_rankine(k) <dt> kelvin_to_reamur(k)
<dt> reamur_to_celcius(r) <dt> reamur_to_farenheit(r) <dt> reamur_to_kelvin(r) <dt> reamur_to_rankine(r)
<dt> celcius_to_farenheit(c) <dt> celcius_to_kelvin(c) <dt> celcius_to_rankine(c) <dt> celcius_to_reamur(c)
<dt> rankine_to_celcius(r) <dt> rankine_to_farenheit(r) <dt> rankine_to_kelvin(r) <dt> rankine_to_reamur(r)
<dt> farenheit_to_celcius(f) <dt> farenheit_to_kelvin(f) <dt> farenheit_to_rankine(f) <dt> farenheit_to_reamur(f)
<dd> These functions are - hopefully - self explanatory.
</dl>
</dl>
<h2> <a name="toc_notes"></a> General Notes</h2>
<p>
More information here as and when I think of it...
</p>
<h2> <a name="toc_dclaim"></a> Disclaimer</h2>
<p>
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
<code>scale</code> is set to 0 or where <code>ibase</code> - which affects the
interpretation of 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.
</p><p>
Before uploading anything to this page, I remove as many bugs as I can find, and
hopefully provide sufficient warnings in the above information and the comments in
the files themselves about where unusually loose approximations might come about.
That said:
</p><p>
<strong>
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.
</strong>
</p><p>
<strong>
Furthermore, I reserve the right to change, update or add to these files at any time,
without prior notification, as I see fit.
</strong>
</p>
<h3> <a name="toc_contact"></a> Contact </h3>
<p>
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,
<a href='mailto:gnu-bc[change this to an at sign]phodd[change this to a dot]net?subject=GNU bc Bug Report: [more detail here]'>let me know</a>
and I'll look into fixing the problem. If you have code suggestions or bug fixes or
even questions about bc, feel free to
<a href='mailto:gnu-bc[change this to an at sign]phodd[change this to a dot]net?subject=GNU bc: [subject here]'>drop me a line</a>.
<span style='float: right; font-family: monospace; font-size: 90%;'><br />-- phodd</span>
</p>
</body>
</html>