Next: New Arithmetics, Up: Revised Arithmetics [Contents][Index]
Of course, all of the provided new number types work when used with
the basic arithmetic operations, +
, -
, *
,
/
, %
, 1+
, and 1-
. At first glance, there
are no severe differences to non-ENT-SXEmacs. However, there is a
traditional rule, whenever one argument in a basic arithmetic
operation is a float, the result is a float. This is an auto-coercion
behaviour, which is heavily generalised in an ENT-SXEmacs.
First, a remark on the alternatives. The most obvious alternative would have been to disallow algebraic operations on arguments of different types, or (to be more fair) to disallow certain category mixtures in the arguments. But since SXEmacs is not a strict maths professor, we will allow most combinations of argument types.
Indeed there are a few cases of binary operations where coercion would be so confusing that SXEmacs rather answers with an error instead of trying the insane.
For a better understanding of the behaviour of auto-coercion,
imagine that the expression (+ a b)
does something
like:
(let ((super-category (find-least-common-category a b))) (+ (coerce a super-category) (coerce 'b super-category)))
analogously for more than two arguments.
Now we just have to look at what this
find-least-common-category
actually does. For some types it is
obvious, an ‘int’ and a ‘bigz’ share the super-category
‘integer’, a ‘float’ and a ‘bigfr’ belong to
‘real’. In that way, we can define the following chains:
int < bigz < bigq < float < bigf < bigfr < bigc int < bigz < bigg < bigc
which verbosely means, if argument one is of type ‘int’ and argument two of type ‘bigz’, then their super-category is ‘bigz’; if argument one is of type ‘bigz’ and argument two of type ‘bigq’ their super-category is ‘bigq’, and so on.
The general rule is to look for the first argument’s type in one of the chains, then if the second is in the same chain, use the type which is more to the right. If the arguments’ types lie in different chains, go rightwards to the leftmost type which is in both chains and use that one.
Some examples:
(+ 1 1/2) ⇒ 3/2 (+ 2 2.0) ⇒ 4.0 (+ 2 1+i) ⇒ 3+1i (+ 2/3 1.4+2.8i) ⇒ 2.066666664+2.800000000i
To be honest, this is chain technique is just a hint for users or programmers. The awful truth is that for every binary operation and every two types there has to be a function which returns the operation’s value.
Given that we currently support 12 different number types and 16 elementary binary operations and relations, there is a total of 2304 combinations – which is too much to list here. The above chain technique is a good approximation of the actual behaviour for all of the elementary binary operations and relations.
A variety of exceptions results from operations on residue classes and quaternions at the moment, which is due to the imposed mathematical background. Rather we discuss the resulting errors, all being sub-errors of the ‘arith-error’ class:
Error signalled when an operation is undefined over the worlds of the arguments.
Error signalled when a relation is undefined over the worlds of the arguments.
Error signalled when a valuation is undecidable or unknown over the world of an argument.
Error signalled when the world of an argument cannot be coerced or lifted onto or into another world.
We close this discussion with a small list of examples:
(+ 3+7Z 3+8Z) Operation undefined over domain (* 3+7Z 3) Operation undefined over domain
(< 2+i 1+2i) Relation undefined over domain (= 2.0+1.0i 2.0+1.0i) Relation undefined over domain
In order to retain compatibility to existing lisp code, there are a
number of issues dealing with division. We have to distinguish
between historical lisp-behaviour and mathematically correct
behaviour. The historic behaviour of /
is to act as what is
known as div
.
(/ 2) ⇒ 0 (/ 1 2) ⇒ 0 (/ 10 2 2) ⇒ 2
However, in order to construct quotients of integers, in terms of
creating a ‘bigq’, there is the function //
. This
quotient function behaves just like /
with the mentioned
exception of returning always a fraction when all arguments are in the
category of rationals.
Return first argument divided by all the remaining arguments. If a rest occurred, the category is enlarged, such that the division can be performed without leaving a rest.
The arguments must be numbers, characters or markers. With one argument, reciprocates the argument.
The above examples using //
then yield:
(// 2) ⇒ 1/2 (// 1 2) ⇒ 1/2 (// 10 2 2) ⇒ 5/2
The mathematical division (division with remainder) is provided by
the function div
, the corresponding remainder function is
mod
.
Return first argument divided by all the remaining arguments, possibly leaving a rest.
The arguments must be numbers, characters or markers. With one argument, reciprocates the argument.
The division of a and b is defined as the largest number c such that (* b c) is less or equal a. Hereby, c lies in the larger category of a and b.
The rest can be queried by ‘mod’.
Return x modulo y. The result falls between zero (inclusive) and y (exclusive). Both x and y must be numbers, characters or markers.
The result value lies in the larger category of x and y.
Next: New Arithmetics, Up: Revised Arithmetics [Contents][Index]