Go to the previous, next section.
This chapter discusses the various types of objects that can be placed on the Calculator stack, how they are displayed, and how they are entered. (See section Data Type Formats, for information on how these data types are represented as underlying Lisp objects.)
Integers, fractions, and floats are various ways of describing real numbers. HMS forms also for many purposes act as real numbers. These types can be combined to form complex numbers, modulo forms, error forms, or interval forms. (But these last four types cannot be combined arbitrarily: error forms may not contain modulo forms, for example.) Finally, all these types of numbers may be combined into vectors, matrices, or algebraic formulas.
The Calculator stores integers to arbitrary precision. Addition, subtraction, and multiplication of integers always yields an exact integer result. (If the result of a division or exponentiation of integers is not an integer, it is expressed in fractional or floating-point form according to the current Fraction Mode. See section Fraction Mode.)
A decimal integer is represented as an optional sign followed by a sequence of digits. Grouping (see section Grouping Digits) can be used to insert a comma at every third digit for display purposes, but you must not type commas during the entry of numbers.
A non-decimal integer is represented as an optional sign, a radix between 2 and 36, a `#' symbol, and one or more digits. For radix 11 and above, the letters A through Z (upper- or lower-case) count as digits and do not terminate numeric entry mode. See section Radix Modes, for how to set the default radix for display of integers. Numbers of any radix may be entered at any time. If you press # at the beginning of a number, the current display radix is used.
A fraction is a ratio of two integers. Fractions are traditionally written "2/3" but Calc uses the notation `2:3'. (The / key performs RPN division; the following two sequences push the number `2:3' on the stack: 2 : 3 RET, or 2 RET 3 / assuming Fraction Mode has been enabled.) When the Calculator produces a fractional result it always reduces it to simplest form, which may in fact be an integer.
Fractions may also be entered in a three-part form, where `2:3:4' represents two-and-three-quarters. See section Fraction Formats, for fraction display formats.
Non-decimal fractions are entered and displayed as `radix#num:denom' (or in the analogous three-part form). The numerator and denominator always use the same radix.
A floating-point number or float is a number stored in scientific notation. The number of significant digits in the fractional part is governed by the current floating precision (see section Precision). The range of acceptable values is from @c{$10^{-3999999}$} 10^-3999999 (inclusive) to @c{$10^{4000000}$} 10^4000000 (exclusive), plus the corresponding negative values and zero.
Calculations that would exceed the allowable range of values (such as `exp(exp(20))') are left in symbolic form by Calc. The messages "floating-point overflow" or "floating-point underflow" indicate that during the calculation a number would have been produced that was too large or too close to zero, respectively, to be represented by Calc. This does not necessarily mean the final result would have overflowed, just that an overflow occurred while computing the result. (In fact, it could report an underflow even though the final result would have overflowed!)
If a rational number and a float are mixed in a calculation, the result
will in general be expressed as a float. Commands that require an integer
value (such as k g [gcd
]) will also accept integer-valued
floats, i.e., floating-point numbers with nothing after the decimal point.
Floats are identified by the presence of a decimal point and/or an exponent. In general a float consists of an optional sign, digits including an optional decimal point, and an optional exponent consisting of an `e', an optional sign, and up to seven exponent digits. For example, `23.5e-2' is 23.5 times ten to the minus-second power, or 0.235.
Floating-point numbers are normally displayed in decimal notation with all significant figures shown. Exceedingly large or small numbers are displayed in scientific notation. Various other display options are available. See section Float Formats.
Floating-point numbers are stored in decimal, not binary. The result of each operation is rounded to the nearest value representable in the number of significant digits specified by the current precision, rounding away from zero in the case of a tie. Thus (in the default display mode) what you see is exactly what you get. Some operations such as square roots and transcendental functions are performed with several digits of extra precision and then rounded down, in an effort to make the final result accurate to the full requested precision. However, accuracy is not rigorously guaranteed. If you suspect the validity of a result, try doing the same calculation in a higher precision. The Calculator's arithmetic is not intended to be IEEE-conformant in any way.
While floats are always stored in decimal, they can be entered and displayed in any radix just like integers and fractions. The notation `radix#ddd.ddd' is a floating-point number whose digits are in the specified radix. Note that the `.' is more aptly referred to as a "radix point" than as a decimal point in this case. The number `8#123.4567' is defined as `8#1234567 * 8^-4'. If the radix is 14 or less, you can use `e' notation to write a non-decimal number in scientific notation. The exponent is written in decimal, and is considered to be a power of the radix: `8#1234567e-4'. If the radix is 15 or above, the letter `e' is a digit, so scientific notation must be written out, e.g., `16#123.4567*16^2'. The first two exercises of the Modes Tutorial explore some of the properties of non-decimal floats.
There are two supported formats for complex numbers: rectangular and polar. The default format is rectangular, displayed in the form `(real,imag)' where real is the real part and imag is the imaginary part, each of which may be any real number. Rectangular complex numbers can also be displayed in `a+bi' notation; see section Complex Formats.
Polar complex numbers are displayed in the form `(r;@c{$\theta$} theta)' where r is the nonnegative magnitude and @c{$\theta$} theta is the argument or phase angle. The range of @c{$\theta$} theta depends on the current angular mode (see section Angular Modes); it is generally between -180 and +180 degrees or the equivalent range in radians.
Complex numbers are entered in stages using incomplete objects. See section Incomplete Objects.
Operations on rectangular complex numbers yield rectangular complex results, and similarly for polar complex numbers. Where the two types are mixed, or where new complex numbers arise (as for the square root of a negative real), the current Polar Mode is used to determine the type. See section Polar Mode.
A complex result in which the imaginary part is zero (or the phase angle is 0 or 180 degrees or @c{$\pi$} pi radians) is automatically converted to a real number.
The word inf
represents the mathematical concept of infinity.
Calc actually has three slightly different infinity-like values:
inf
, uinf
, and nan
. These are just regular
variable names (see section Variables); you should avoid using these
names for your own variables because Calc gives them special
treatment. Infinities, like all variable names, are normally
entered using algebraic entry.
Mathematically speaking, it is not rigorously correct to treat "infinity" as if it were a number, but mathematicians often do so informally. When they say that `1 / inf = 0', what they really mean is that 1 / x, as x becomes larger and larger, becomes arbitrarily close to zero. So you can imagine that if x got "all the way to infinity," then 1 / x would go all the way to zero. Similarly, when they say that `exp(inf) = inf', they mean that @c{$e^x$} exp(x) grows without bound as x grows. The symbol `-inf' likewise stands for an infinitely negative real value; for example, we say that `exp(-inf) = 0'. You can have an infinity pointing in any direction on the complex plane: `sqrt(-inf) = i inf'.
The same concept of limits can be used to define 1 / 0. We really want the value that 1 / x approaches as x approaches zero. But if all we have is 1 / 0, we can't tell which direction x was coming from. If x was positive and decreasing toward zero, then we should say that `1 / 0 = inf'. But if x was negative and increasing toward zero, the answer is `1 / 0 = -inf'. In fact, x could be an imaginary number, giving the answer `i inf' or `-i inf'. Calc uses the special symbol `uinf' to mean undirected infinity, i.e., a value which is infinitely large but with an unknown sign (or direction on the complex plane).
Calc actually has three modes that say how infinities are handled.
Normally, infinities never arise from calculations that didn't
already have them. Thus, 1 / 0 is treated simply as an
error and left unevaluated. The m i (calc-infinite-mode
)
command (see section Infinite Mode) enables a mode in which
1 / 0 evaluates to uinf
instead. There is also
an alternative type of infinite mode which says to treat zeros
as if they were positive, so that `1 / 0 = inf'. While this
is less mathematically correct, it may be the answer you want in
some cases.
Since all infinities are "as large" as all others, Calc simplifies,
e.g., `5 inf' to `inf'. Another example is
`5 - inf = -inf', where the `-inf' is so large that
adding a finite number like five to it does not affect it.
Note that `a - inf' also results in `-inf'; Calc assumes
that variables like a
always stand for finite quantities.
Just to show that infinities really are all the same size,
note that `sqrt(inf) = inf^2 = exp(inf) = inf' in Calc's
notation.
It's not so easy to define certain formulas like `0 * inf' and
`inf / inf'. Depending on where these zeros and infinities
came from, the answer could be literally anything. The latter
formula could be the limit of x / x (giving a result of one),
or 2 x / x (giving two), or x^2 / x (giving inf
),
or x / x^2 (giving zero). Calc uses the symbol nan
to represent such an indeterminate value. (The name "nan"
comes from analogy with the "NAN" concept of IEEE standard
arithmetic; it stands for "Not A Number." This is somewhat of a
misnomer, since nan
does stand for some number or
infinity, it's just that which number it stands for
cannot be determined.) In Calc's notation, `0 * inf = nan'
and `inf / inf = nan'. A few other common indeterminate
expressions are `inf - inf' and `inf ^ 0'. Also,
`0 / 0 = nan' if you have turned on "infinite mode"
(as described above).
Infinities are especially useful as parts of intervals. See section Interval Forms.
The vector data type is flexible and general. A vector is simply a list of zero or more data objects. When these objects are numbers, the whole is a vector in the mathematical sense. When these objects are themselves vectors of equal (nonzero) length, the whole is a matrix. A vector which is not a matrix is referred to here as a plain vector.
A vector is displayed as a list of values separated by commas and enclosed in square brackets: `[1, 2, 3]'. Thus the following is a 2 row by 3 column matrix: `[[1, 2, 3], [4, 5, 6]]'. Vectors, like complex numbers, are entered as incomplete objects. See section Incomplete Objects. During algebraic entry, vectors are entered all at once in the usual brackets-and-commas form. Matrices may be entered algebraically as nested vectors, or using the shortcut notation `[1, 2, 3; 4, 5, 6]', with rows separated by semicolons. The commas may usually be omitted when entering vectors: `[1 2 3]'. Curly braces may be used in place of brackets: `{1, 2, 3}', but the commas are required in this case.
Traditional vector and matrix arithmetic is also supported; see section Basic Arithmetic and see section Vector/Matrix Functions. Many other operations are applied to vectors element-wise. For example, the complex conjugate of a vector is a vector of the complex conjugates of its elements.
Algebraic functions for building vectors include `vec(a, b, c)' to build `[a, b, c]', `cvec(a, n, m)' to build an @c{$n\times m$} nxm matrix of `a's, and `index(n)' to build a vector of integers from 1 to `n'.
Character strings are not a special data type in the Calculator. Rather, a string is represented simply as a vector all of whose elements are integers in the range 0 to 255 (ASCII codes). You can enter a string at any time by pressing the " key. Quotation marks and backslashes are written `\"' and `\\', respectively, inside strings. Other notations introduced by backslashes are:
\a 7 \^@ 0 \b 8 \^a-z 1-26 \e 27 \^[ 27 \f 12 \^\\ 28 \n 10 \^] 29 \r 13 \^^ 30 \t 9 \^_ 31 \^? 127
Finally, a backslash followed by three octal digits produces any character from its ASCII code.
Strings are normally displayed in vector-of-integers form. The
d " (calc-display-strings
) command toggles a mode in
which any vectors of small integers are displayed as quoted strings
instead.
The backslash notations shown above are also used for displaying strings. Characters 128 and above are not translated by Calc; unless you have an Emacs modified for 8-bit fonts, these will show up in backslash-octal-digits notation. For characters below 32, and for character 127, Calc uses the backslash-letter combination if there is one, or otherwise uses a `\^' sequence.
The only Calc feature that uses strings is compositions; see section Compositions. Strings also provide a convenient way to do conversions between ASCII characters and integers.
There is a string
function which provides a different display
format for strings. Basically, `string(s)', where s
is a vector of integers in the proper range, is displayed as the
corresponding string of characters with no surrounding quotation
marks or other modifications. Thus `string("ABC")' (or
`string([65 66 67])') will look like `ABC' on the stack.
This happens regardless of whether d " has been used. The
only way to turn it off is to use d U (unformatted language
mode) which will display `string("ABC")' instead.
Control characters are displayed somewhat differently by string
.
Characters below 32, and character 127, are shown using `^' notation
(same as shown above, but without the backslash). The quote and
backslash characters are left alone, as are characters 128 and above.
The bstring
function is just like string
except that
the resulting string is breakable across multiple lines if it doesn't
fit all on one line. Potential break points occur at every space
character in the string.
HMS stands for Hours-Minutes-Seconds; when used as an angular argument, the interpretation is Degrees-Minutes-Seconds. All functions that operate on angles accept HMS forms. These are interpreted as degrees regardless of the current angular mode. It is also possible to use HMS as the angular mode so that calculated angles are expressed in degrees, minutes, and seconds.
The default format for HMS values is `hours@ mins' secs"'. During entry, the letters `h' (for "hours") or `o' (approximating the "degrees" symbol) are accepted as well as `@', `m' is accepted in place of `'', and `s' is accepted in place of `"'. The hours value is an integer (or integer-valued float). The mins value is an integer or integer-valued float between 0 and 59. The secs value is a real number between 0 (inclusive) and 60 (exclusive). A positive HMS form is interpreted as hours + mins/60 + secs/3600. A negative HMS form is interpreted as - hours - mins/60 - secs/3600. Display format for HMS forms is quite flexible. See section HMS Formats.
HMS forms can be added and subtracted. When they are added to numbers, the numbers are interpreted according to the current angular mode. HMS forms can also be multiplied and divided by real numbers. Dividing two HMS forms produces a real-valued ratio of the two angles.
Just for kicks, M-x calc-time pushes the current time of day on the stack as an HMS form.
A date form represents a date and possibly an associated time. Simple date arithmetic is supported: Adding a number to a date produces a new date shifted by that many days; adding an HMS form to a date shifts it by that many hours. Subtracting two date forms computes the number of days between them (represented as a simple number). Many other operations, such as multiplying two date forms, are nonsensical and are not allowed by Calc.
Date forms are entered and displayed enclosed in `< >' brackets. The default format is, e.g., `<Wed Jan 9, 1991>' for dates, or `<3:32:20pm Wed Jan 9, 1991>' for dates with times. Input is flexible; date forms can be entered in any of the usual notations for dates and times. See section Date Formats.
Date forms are stored internally as numbers, specifically the number of days since midnight on the morning of January 1 of the year 1 AD. If the internal number is an integer, the form represents a date only; if the internal number is a fraction or float, the form represents a date and time. For example, `<6:00am Wed Jan 9, 1991>' is represented by the number 726842.25. The standard precision of 12 decimal digits is enough to ensure that a (reasonable) date and time can be stored without roundoff error.
If the current precision is greater than 12, date forms will keep additional digits in the seconds position. For example, if the precision is 15, the seconds will keep three digits after the decimal point. Decreasing the precision below 12 may cause the time part of a date form to become inaccurate. This can also happen if astronomically high years are used, though this will not be an issue in everyday (or even everymillenium) use. Note that date forms without times are stored as exact integers, so roundoff is never an issue for them.
You can use the v p (calc-pack
) and v u
(calc-unpack
) commands to get at the numerical representation
of a date form. See section Packing and Unpacking.
Date forms can go arbitrarily far into the future or past. Negative
year numbers represent years BC. Calc uses a combination of the
Gregorian and Julian calendars, following the history of Great
Britain and the British colonies. This is the same calendar that
is used by the cal
program in most Unix implementations.
Some historical background: The Julian calendar was created by Julius Caesar in the year 46 BC as an attempt to fix the gradual drift caused by the lack of leap years in the calendar used until that time. The Julian calendar introduced an extra day in all years divisible by four. After some initial confusion, the calendar was adopted around the year we call 8 AD. Some centuries later it became apparent that the Julian year of 365.25 days was itself not quite right. In 1582 Pope Gregory XIII introduced the Gregorian calendar, which added the new rule that years divisible by 100, but not by 400, were not to be considered leap years despite being divisible by four. Many countries delayed adoption of the Gregorian calendar because of religious differences; in Britain it was put off until the year 1752, by which time the Julian calendar had fallen eleven days behind the true seasons. So the switch to the Gregorian calendar in early September 1752 introduced a discontinuity: The day after Sep 2, 1752 is Sep 14, 1752. Calc follows this convention. To take another example, Russia waited until 1918 before adopting the new calendar, and thus needed to remove thirteen days (between Feb 1, 1918 and Feb 14, 1918). This means that Calc's reckoning will be inconsistent with Russian history between 1752 and 1918, and similarly for various other countries.
Today's timekeepers introduce an occasional "leap second" as well, but Calc does not take these minor effects into account. (If it did, it would have to report a non-integer number of days between, say, `<12:00am Mon Jan 1, 1900>' and `<12:00am Sat Jan 1, 2000>'.)
Calc uses the Julian calendar for all dates before the year 1752, including dates BC when the Julian calendar technically had not yet been invented. Thus the claim that day number -10000 is called "August 16, 28 BC" should be taken with a grain of salt.
Please note that there is no "year 0"; the day before `<Sat Jan 1, +1>' is `<Fri Dec 31, -1>'. These are days 0 and -1 respectively in Calc's internal numbering scheme.
Another day counting system in common use is, confusingly, also called "Julian." It was invented in 1583 by Joseph Justus Scaliger, who named it in honor of his father Julius Caesar Scaliger. For obscure reasons he chose to start his day numbering on Jan 1,lt.
Please note that there is no "year 0"; the day before `<Sat Jan 1, +1>' is `<Fri Dec 31, -1>'. These are days 0 and -1 respectively in Calc's internal numbering scheme.
Another day counting system in common use is, confusingly, also called "Julian." It was invented in 1583 by Joseph Justus Scaliger, who named it in honor of his father Julius Caesar Scaliger. For obscure reasons he chose to start his day numbering on Jan 1,