Next: , Up: Revised Arithmetics   [Contents][Index]


63.5.1 Basic Arithmetics and ENT

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: operation-error

Error signalled when an operation is undefined over the worlds of the arguments.

Error: relation-error

Error signalled when a relation is undefined over the worlds of the arguments.

Error: valuation-error

Error signalled when a valuation is undecidable or unknown over the world of an argument.

Error: domain-error

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.

Function: // &rest numbers

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.

Function: div &rest numbers

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’.

Function: mod x y

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: , Up: Revised Arithmetics   [Contents][Index]