spigot - command-line exact real calculator
spigot [ options ] expression
spigot is an exact real calculator: that is, you give it a
mathematical expression to evaluate, and it computes it to any desired
precision, by default simply printing digits to standard output until it is
interrupted.
spigot provides command-line options to control the format
of the output, restrict it to a specified number of digits, and apply
rounding at the end of those digits. It can produce output in any base
between 2 and 36 (after that it runs out of digit characters), or as a
continued fraction, and it can read input numbers from files in any of those
formats as well.
This man page gives only a brief summary of spigot's
functionality. For full detail, you should read the main manual
spigot.html; if that is not installed on your system, you can find it
on the web at
http://www.chiark.greenend.org.uk/~sgtatham/spigot/spigot.html
The following options control spigot's basic output
format:
- -b base, -B
base
- Output the number in base base, which must be an integer between 2
and 36 inclusive. Digits above 9 are represented by lower case or upper
case letters, for the options -b and -B respectively. The
default is -b 10.
- -c
- Output the number as a list of continued fraction coefficients, as decimal
integers, by default one per line.
- -C
- Output the number's continued fraction convergents, one per line, in the
form of two decimal integers with a / between them.
- -R
- Output the number's value as a rational, in the form of two decimal
integers with a / between them, or just one decimal integer if the
number is a rational. If spigot does not know the number to be
rational immediately, it will start evaluating it to see if it turns out
rational later, so if it is not rational then spigot will compute
for ever.
- -S, -D, -Q,
-H
- Output the number as a hex representation of an IEEE 754 bit pattern, in
32-bit single precision, 64-bit double, 128-bit quad or 16-bit half
precision respectively. If that representation is not exact, a decimal
point will be printed followed by further mantissa digits.
- --printf
format, --printf=format
- Format the number in the same way that printf(3) would,
given the formatting directive format. format must begin
with a % and end with the associated conversion specifier, which
must be a floating-point one (one of efgaEFGA).
The following options modify the details of those output
formats:
- -d limit
- Limit the amount of data output. In -b mode, no more than
limit digits after the decimal point are printed. In -c or
-C mode, no more than limit continued fraction coefficients
or convergents are printed, not counting the initial one representing the
number's integer part. In the IEEE 754 output modes, no more than
limit additional bits of precision are generated after the end of
the official mantissa. limit may be negative.
- -l
- In -c mode, output continued fraction terms all on one line,
separated by a ; after the first term and , after each
subsequent term.
- -w
min-int-digits
- In -b mode, output at least min-int-digits of the number's
integer part, by printing leading zeroes if necessary.
- --nibble
- In --printf mode with the `a' or `A' conversion
specifier, choose the output exponent to always be a multiple of 4,
instead of the default behaviour of choosing it as large as possible.
- -n
- In any mode where spigot prints output on a single line, suppress
the usual trailing newline if spigot's output terminates.
The following options control rounding, when spigot's
output is limited by the -d option. (Rounding does not occur in
continued fraction modes.)
- --rz
- Round towards zero. This is the default.
- --ri
- Round away from zero.
- --ru
- Round up (towards positive infinity).
- --rd
- Round down (towards negative infinity).
- --rn, --rne
- Round to nearest, breaking ties toward an even last digit.
- --rno
- Round to nearest, breaking ties toward an odd last digit.
- --rnz, --rni,
--rnu, --rnd
- Round to nearest, breaking ties as if rounding via --rz,
--ri, --ru or --rd respectively.
Miscellaneous options:
- --tentative=state
- Control the printing of `tentative output'. Tentative output is printed
when spigot does not know for sure what the next digit of the
number is because it's starting to look as if it's exactly on a digit
boundary. Tentative output is in red, and followed by an indication of
about how many digits spigot has examined beyond that point (i.e.
how close to exact that digit is known to be); spigot will retract
it later if it finds out something definite.
state can be `on', `off' or `auto'.
`auto' is the default, and means that spigot should only print
tentative output if its output is directed to a terminal device.
- -T
- If instructed to read from a file descriptor which points to a terminal,
put the terminal into raw mode (turning off ICANON and ECHO
modes) while doing so.
spigot's expression language supports the following
options, in order of priority from lowest to highest:
- + and -
- Addition and subtraction. (Left-associative.)
- *, /, %, mod, rem
- Multiplication, division and remainder. (Left-associative.) % and
mod are synonyms, which both return a remainder between 0 and the
denominator; rem returns a remainder of either sign, with absolute
value at most half that of the denominator, and ties broken by rounding to
even in IEEE 754 style.
- Unary - and
+
- Negation and no-op.
- ^, **
- Power. (Right-associative.)
You can define variables and functions of your own in
subexpressions using the let expression, as follows:
- let var=value in expression
- Defines the name var to refer to the value of the expression
value. The definition is in scope within expression, but not
in any other parts of the spigot input.
- let fn(params)=defn in expression
- Defines the syntax fn(args) to refer to the
expression defn with the arguments substituted in for the
parameters. params must be a comma-separated list of identifiers;
args is a comma-separated list of expressions.
A let expression can contain multiple definitions,
separated by commas, e.g. `let x=1,y=2 in x+y'. Each definition is in
scope for subsequent definitions, so you can write `let x=1,y=x+1
in' expr. But definitions are not in scope for
themselves; in particular, functions may not be recursive.
spigot also provides the following built-in functions:
- sqrt,
cbrt
- Square and cube roots.
- hypot, atan2
(two arguments)
- Rectangular to polar coordinate conversions: the hypotenuse function
(square root of the sum of the squared arguments), and two-variable
inverse tangent.
- sin, cos,
tan, asin, acos, atan
- Trigonometric functions and their inverses.
- sind, cosd,
tand, asind, acosd, atand,
atan2d
- Trigonometric functions and their inverses, equivalent to the versions
without `d' on the end except that angles are measured in
degrees.
- sinh, cosh,
tanh, asinh, acosh, atanh
- Hyperbolic functions and their inverses.
- exp, exp2,
exp10, log, log2, log10
- Exponential and logarithmic functions: raise e, 2 and 10 to a
power, or take a log with the same three bases. You can also provide a
base of your choice as a second argument to log.
- expm1,
log1p
- Shorthands for exp(x)-1 and log(1+x).
- pow (two
arguments)
- Synonym for the ^ operator.
- gamma, tgamma,
lgamma
- Gamma function (gamma and tgamma are synonyms for this), and
the log of the absolute value of the gamma function.
- erf, erfc,
Phi, norm
- Error-function relatives: the error function itself, 1 minus the error
function, and Phi and norm are synonyms for the cumulative
normal distribution function.
- erfinv,
erfcinv, Phiinv, norminv
- Inverses of the above error-function relatives.
- W, Wn
- The Lambert W function, i.e. the inverse of x exp(x).
W is the branch with value at least -1, and Wn is the
branch with value at most -1.
- Ei, En (two
arguments), E1, Ein
- Exponential integrals, i.e. integrals of things like exp(x)/x.
Ei(x) is the indefinite integral of exp(x)/x itself;
En(n,x) (for non-negative integer n) is the result of
integrating exp(-x)/x n times, flipping the sign each time;
E1(x) is shorthand for En(1,x); and Ein(x) is the
integral of (1-exp(-x))/x.
- Li, li
- Logarithmic integrals, i.e. integrals of 1/log(x). Li(x) and
li(x) are both the indefinite integral of 1/log(x); only
their constants differ, in that Li(2) and li(0) are each
defined to be zero.
- Si, si, Ci,
Cin
- Sine and cosine integrals, i.e. integrals of sin(x)/x and
cos(x)/x. Si(x) and si(x) are both the indefinite
integral of sin(x)/x, differing only in the constant:
Si(0)=0, but si(x) has limit 0 as x tends to positive
infinity. Ci(x) is the indefinite integral of cos(x)/x, also
with limit 0 at positive infinity; Cin(x) is the indefinite
integral of (1-cos(x))/x, with Cin(0)=0.
- UFresnelS,
UFresnelC, FresnelS, FresnelC
- Fresnel integrals. UFresnelS and UFresnelC are the
indefinite integrals of sin(x^2) and cos(x^2);
FresnelS and FresnelC are the `normalised' versions, i.e.
integrals of sin(π x^2/2) and
cos(π x^2/2). All are zero at the
origin.
- zeta
- The Riemann zeta function (restricted to the real numbers).
- abs
- Absolute value.
- ceil,
floor
- Ceiling and floor: smallest integer at least x, and largest integer
at most x.
- frac
- Fractional part, i.e.
x - floor(x).
- algebraic
(variable number of arguments)
- Return a root of an arbitrary polynomial with integer coefficients. The
first two arguments are the rational bounds of an interval to search, and
the rest give the polynomial's coefficients, with constant term
first.
spigot supports the following names for built-in
constants:
- pi, tau
- The circle constant π, and the often more useful 2
π.
- e
- The base of natural logarithms.
- phi
- The golden ratio, (1+sqrt(5))/2.
- eulergamma
- The Euler-Mascheroni constant: the limiting difference between the sum and
the integral of 1/n.
- apery
- Apery's constant: the sum of the reciprocals of the cubes.
Numbers can be input in the following formats:
- •
- Decimal, with an optional C-style e+exponent or
e-exponent for scientific notation
- •
- Hex, with the prefix 0x, and an optional C99-style
p+exponent or p-exponent representing a power
of 2 multiplier
- •
- In any base between 2 and 36, with a prefix of the form
baseN:, e.g. base7:0.123456
- •
- As an IEEE 754 hex bit pattern, consisting of exactly 4, 8, 16 or 32 hex
digits with the prefix ieee:, followed by optional decimal point
and extra mantissa digits
- •
- From a file in base notation, by writing baseNfile:
followed by a filename, e.g. base10fd:pi.txt. The filename is taken
to be the maximal sequence of non-space characters following the prefix,
unless it starts with ' or ", in which case it is taken
to be everything up to a matching closing quote, with doubled quote marks
in between representing a literal quote character.
- •
- From a file in continued fraction notation, by writing cfracfile:
followed by a filename.
- •
- Either of the above, but with file: replaced by xfile: to
indicate that end of file should be taken as the number being exactly
represented rather than running out of precision.
- •
- From a file descriptor in any of those notations, by writing
baseNfd: or cfracfd: followed by an fd number,
e.g. base10fd:0 to read from standard input.
spigot returns 0 if its output terminates (because the
result is exact, or because it reached the specified -d limit) with
no problems.
In case of a parse error, or an invalid operand to a function, or
any other kind of fatal error, spigot returns 1.
If spigot is unable to generate output to the desired
precision because more precision was needed from a number read from an input
file using baseNfile: or cfracfile:, then
spigot returns 2, and prints an error message indicating which input
file (in case there was more than one) ran out first.
Due to inherent limitations of its exact real arithmetic strategy,
spigot is generally unable to recognise when a number it is computing
is exactly equal to a specific boundary value.
One effect of this is that spigot will not behave as you'd
like if the output number has a terminating representation in the selected
base. For example, asking for sin(asin(0.12345)) will not be able to
print 0.12345 and exit. Instead, spigot will get as far as
printing `0.1234', and then print tentative output (mentioned above)
to indicate that it thinks the next digit might be exactly 5, but it
will never reach a point where it's sure of that.
Another effect is that if you ask spigot to evaluate an
expression in which an intermediate result is precisely on a point of
discontinuity of the function it is passed to, then it may never manage to
even start producing output. For example, spigot will hang
completely if you ask it for floor(sin(pi)), since
sin(pi) = 0 is a point of discontinuity
of the floor function, and spigot will never be able to work
out that the value of the input to floor is exactly zero, only
that it seems to be closer and closer to zero the more it computes.
(An exception is numbers that spigot knows from first
principles to be rational. For example, if you ask spigot to evaluate
the simpler expressions `0.12345' or `floor(0)', it will print
the complete output and terminate successfully, in both cases.)
spigot is free software, distributed under the MIT licence.
Type `spigot --licence' to see the full licence text.