Enhanced Number Types (ENT)
***************************

Compiling SXEmacs with enhanced number type support not only brings a full heap of new number types, but also provides a more convenient concept of numbers at all.  This concept is mostly driven by mathematical issues.  Nonetheless we attempt to provide as much backward compatibility as possible.

The purpose of enhanced number types is to propagate both a convenient set of additional functionality which is (hopefully) widely used in the future, and a consistent concept for dealing with numeric computations from within emacs lisp.

The feature itself must be considered experimental, though.  Howbeit programmers can benefit from extremely increased performance, even with the current implementation.

ENT Basics
==========

SXEmacs supports several of the available arithmetical and mathematical libraries.  Wherever possible, it is attempted to introduce a transparency layer, such that one library can be exchanged by another when both provide equal or similar functionality.  This layering allow emacs lisp and C programmers to minimise their efforts by using a standardised interface.

On the other hand, it is attempted to additionally bring all library-specific features into the emacs lisp environment.  That way emacs lisp (and also C) programmers can easily use certain functions which are contained in only one specific library.

Some of the functionality provided by libraries is even re-implemented in C in order to allow emacs lisp programmers to use such functions even if the external library is not available.  This may sound a little obscure, but it is important to establish a consistent and convenient concept of number types in the emacs lisp environment once the enhanced number type support is enabled.

We start this section with a quick overview of what is available out there, and what is additionally available due to re-implementation.

The GNU multi-precision arithmetic library (GMP)
------------------------------------------------

The GMP library is the most widely used library of its kind, and probably the most versatile and powerful library for high precision arithmetic.  Hence SXEmacs will extensively support this library in its ENT system.  Also, many other libraries and pseudo-implementations are based on GMP.  That is why it is probably worth fetching and installing it.

The term multi-precision arithmetic, also called arbitrary-precision arithmetic, is used to mean that the number of digits of handled numbers is not limited in any way.  Practically of course it is limited by the amount of virtual memory and, more often these days, by time.

GMP is distributed under the GNU LGPL and the library is available at http://swox.com/gmp.  Please refer also to their documentation, and especially their instructions on how to install it.

The GMP library consists of roughly 4 parts, MPN, MPZ, MPQ, and MPF.  Only the latter three are intended for consumption.

MPN is sort of the spine of GMP and provides the actual implementation of the multi-precision arithmetic.  It is not further interesting for SXEmacs since MPN functions are never accessed directly.

MPZ is a higher level interface to arbitrary precision integer arithmetic.  The name is derived from the mathematical symbol for integral numbers Z.  We will also use the term rational integers to refer to the mathematical concept of Z.  In turn, historically Z is derived from the German word ``Zahlen'' which stands for ``numbers''.

MPQ is the interface to rational numbers.  The name is derived from the mathematical symbol for the rational field Q.  Rational numbers, also referred to as fractions of integers or quotients of integers, or (if the meaning is clear) simply fractions and quotients respectively.  This nomenclature already suggests how rationals can be represented, namely by two MPZ integers written in the form a/b.  In such a representation we call a the numerator and b the denominator of a/b.  Internally, a fraction is always stored in its canonical form, that is the fraction is cancelled as far as possible, such that a and b are coprime.  For reasons of compatibility to XEmacs 21.5, we will also refer to fractions as ratios.

MPF is an interface to multi-precision floats.  They are implemented like ordinary floats but are not limited to fixed number of mantissa and exponent bits.  These numbers may vary instead and is called the precision of such a number.  The precision in turn does not need to be a multiple of 4 or 8 or something similar and is measured in bits.  In this sense, MPF numbers may be regarded as an approximation for real numbers, see Unions of Number Types.

The BSD multi-precision library
-------------------------------

The BSD-MP library comes natively (as the name maybe suggests) with BSD distributions.  It is also widely, though mostly stealthily, spread in form of the crypto library libcrypto.so of OpenSSL.

BSD-MP, like GMP, provides a form of arbitrary-precision rational integers, called MINT.  Both MPZ and MINT integers are transparently unified within SXEmacs, which is why you can use only one implementation at a time.

The MPFR library
----------------

MPFR is a portable library for arbitrary precision arithmetic on floating-point numbers, based on the GMP library.  It works similar to the MPF module of GMP, however the main differences with MPF are:

  * the mpfr code is portable, i.e. the result of any operation does not depend on the machine word size mp_bits_per_limb (32 or 64 on most machines);

  * the precision in bits can be set exactly to any valid value for each variable;

  * MPFR provides the four rounding modes from the IEEE 754-1985 standard.

In particular, with a precision of 53 bits, mpfr should be able to exactly reproduce all computations with double-precision machine floating-point numbers (double type in C).  Furthermore, MPFR comes with a heap of useful functions over the reals, like logarithms, trigonometrical functions and so forth.

The MPFR library is released under the GNU LGPL and can be obtained from http://www.mpfr.org.    Please refer also to their documentation, and especially their instructions on how to install it.

Especially note that we currently do only support the standalone version of MPFR, and not the one distributed with GMP.

The MPC library
---------------

MPC is a portable library written by Andreas Enge for arbitrary-precision arithmetic on complex numbers.  It is based on the GMP and MPFR libraries.

The MPC library is released under the GNU LGPL and is available at http://www.lix.polytechnique.fr/Labo/Andreas.Enge/mpc/mpc.html.

Unfortunately, as of November 2005, the build system of MPC is extremely poor, hence we describe shortly how to install it.  After untarring the archive invoke make.  This will produce a libmpc.a.  Copy this file to your favourite lib/ directory, for example /path/to/gmp/prefix/lib/ and make that path known to SXEmacs via the --with-site-prefixes switch when configuring.  Secondly, copy the file mpc.h to your favourite include/ directory, for example to /path/to/gmp/prefix/include/.  That's it!

The name MPC is probably derived from the mathematical symbol C for the complex number field.  Without further explanations, the complex numbers are an algebraic extension of the real numbers, indeed it is the only sensible extension.  It turns out, that efforts to find an algebraic closure of any number field end up in the complex numbers.

Complex numbers have different representations, but one of the most known is the representation as a tuple of reals (more formally as vector space over R).  The notation of a complex number for this representation is (a,b) or a+bi, where a and b are real numbers.  The symbol i denotes the imaginary unit.  In this representation, we refer to a as the real part and to b as the imaginary part of a+bi.

There are other representations of complex numbers which are not implemented yet and hence will not be explained at this place.

Pseudocomplex Numbers
---------------------

Pseudocomplex numbers are the poor man's version of MPC.  Its implementation is based on MPFR which must be available therefore. The representation of complex numbers follows the one used in MPC, namely in the form a+bi.  Complex numbers are internally stored by two independent MPFR floats.

Pseudocomplex numbers are gratis whenever MPFR is provided on a system.  They are contained and maintained within the SXEmacs source distribution and hence inherit the licence of SXEmacs.

Pseudogaussian Numbers
----------------------

Pseudogaussian numbers are implemented like pseudocomplex numbers. They are based on GMP-MPZ which must be available therefore.

Like pseudocomplex numbers, pseudogaussians are gratis whenever GMP-MPZ is provided on a system.  They are contained and maintained within the SXEmacs source distribution and hence inherit the licence of SXEmacs.

The representation of Gaussian numbers within SXEmacs follows the one usually used in algebra, namely as the ring of integers of Q+Qi. Gaussian numbers may thusly be written like complex ones, a+bi, where a and b are both rational integers.

Residue Class Rings
-------------------

Residue classes are a special form of partitioning the class of rational integers into finitely many classes of congruent elements. They are based on GMP-MPZ which must be available therefore.

Like pseudocomplex or pseudogaussian numbers residue class rings are gratis whenever GMP-MPZ is provided on a system.  The classes themselves are represented additively and canonicalised, that is c+mZ, where c and m are both rational integers, and canonically c is in [0..m).

Quaternions
-----------

Quaternions are a special form of hypercomplex numbers.  Currently, we support the integer ring of the usual quaternion definition.  That way, quaternions form a special Z-module.  They are based, however, on the GMP-MPZ which must be available therefore.

Quaternions are represented additively by a set of basis vectors, called 1, i, j, and k.  These suffice the fundamental equation: i^2 = j^2 = k^2 = ijk = -1

Octonions
---------

Neither documented nor implemented yet.

Algebraic Numbers
-----------------

Neither documented nor implemented yet.

Modules and Lattices
--------------------

Neither documented nor implemented yet.

Types of Numbers
================

For proper understanding, we are using the terms type and category in the next sections.  These terms are used (quite inclusive) in the meaning of type and category theory in some sense.  A category is a class of elements related to each other by fulfilling a common predicate.  Then on the other hand the type of an object is something like the strongest category an object may live in disjointly.

The main difference between both terms is that in C an object must have exactly one type, whereas it still can belong to other categories.  For example, having the integer 0 and the fraction 0/1, then both of these belong to the category zero, but it is quite obvious that nobody would expect them to be of type zero.

The Type bigz
-------------

The type bigz is an abstract C type for arbitrary-precision rational integers.  Its actual library-specific implementation is chosen at configure time, and can be either GMP-MPZ or BSD-MP.  In the former case the actual C type would be mpz_t, in the latter case it is MINT.

Any other library which implements something similar to MPZ, should be accessed via the abstract type bigz, too.

Lisp objects can be tested for the type bigz by the following predicates.

 -- Function: bigzp object
     This predicate tests whether its argument is a big integer (as provided by GMP-MPZ or BSD-MP), and returns t if so, nil otherwise.

 -- Function: bignump object
     This is roughly the same as bigzp and is provided for compatibility to XEmacs.

The read syntax (and print syntax) of rational integers is the same as for ordinary emacs integers.  If the mantissa is not sufficient to regard an integer as fixnum, that integer is automatically treated as bigz integer and created as such.

There are no other forms of creation, especially there are no constructors for bigz objects.

Although named `arbitrary'-precision integers there is no way to take influence on the precision or internal representation of bigzs (unlike the float types).  The number of limbs used, read the precision, is administered solely by the underlying library implementation.

The Type bigq
-------------

The type bigq is an abstract C type for arbitrary-precision rational numbers (fractions).  The actual C type provided by the GMP-MPQ library is mpq_t.

Any other library which implements something similar to MPQ, should be accessed via the abstract type bigq, too.

Lisp objects can be tested for the type bigq by the following predicates.

 -- Function: bigqp object
     This predicate tests whether its argument is a fraction of integers (as provided by GMP-MPQ), and returns t if so, nil otherwise.

 -- Function: ratiop object
     This is roughly the same as bigqp and is provided for compatibility to XEmacs.

Furthermore, for bigq objects exist two accessor functions, namely numerator and denominator to access the respective parts of a fraction.

 -- Function: numerator rational
     Return the numerator of the canonical form of RATIONAL. If RATIONAL is an integer, RATIONAL is returned.

 -- Function: denominator rational
     Return the denominator of the canonical form of RATIONAL. If RATIONAL is an integer, 1 is returned.

The read syntax of rational quotients is the intuitive one, and identical to their output syntax if the quotients are not integral (i.e. have denominator 1).  The lisp reader interprets A/B with A a rational integer and B a positive integer as the quotient a/b.

Within the lisp reader quotients are automatically cancelled and stored in their canonical form (A coprime to B), consider the following examples:

     1/3
          => 1/3
     6/18
          => 1/3
     21/3
          => 7

Please note that the result in the latter example is not of type bigq because auto-coercion is in effect (see the notes in Category integer) which canonicalises rational fractions with denominator 1 to rational integers.

Also note that the read syntax for quotients steals a whole class of possible symbol identifiers.  In a non-ENT-SXEmacs 1/3 is a valid name for a variable.

Beside the creation of rational quotients, the arithmetic operation // can also be used to construct quotients.  This function is not exclusively a bigq-constructor, but passing two integral arguments (interpretable as numerator and denominator) will yield a quotient:

     (// 2 3)
          => 2/3

Again, in spite of their name arbitrary-precision quotients do not offer a way to take influence on the precision or internal representation of bigqs (unlike the float types).  The number of limbs used, read the precision, is administered solely by the underlying library implementation.

The Type bigf
-------------

The type bigf is an abstract C type for arbitrary-precision real number approximations (so called floats).  The actual C type provided by the GMP-MPF library is mpf_t.

Any other library which implements something similar to MPF, should be accessed via the abstract type bigf, too.

Lisp objects can be tested for the type bigq by the following predicates.

 -- Function: bigfp object
     This predicate tests whether its argument is a MP-float (as provided by GMP-MPF), and returns t if so, nil otherwise.

 -- Function: bigfloatp object
     This is roughly the same as bigfp and is provided for compatibility to XEmacs.

The read syntax (and print syntax) of bigfs is the same as for emacs floats.  The interpretation in the lisp reader depends on the variable READ-REAL-AS (see Category real).

There are no other forms of creation, especially there are no constructors for bigf objects.

As the name arbitrary-precision suggested, numbers of type bigf can be assigned a precision.  This precision can be queried and even may be changed at any time.

 -- Function: bigf-get-precision number
     Return the precision of NUMBER as an integer.

 -- Function: bigf-set-precision number precision
     Set the precision of NUMBER to PRECISION, a nonnegative integer. The new precision of NUMBER is returned.

     Note that the return value may differ from PRECISION if the underlying library is unable to support exactly PRECISION bits of precision. Note also, that setting the precision is lossy, that means NUMBER after setting the precision is not necessarily the same as the original NUMBER.

The Type bigfr
--------------

The type bigfr is an abstract C type for arbitrary-precision real number approximations with correct rounding facilities (so called floats).  The actual C type is provided by the MPFR library and is called mpfr_t.

Any other library which implements something similar to MPFR, should be accessed via the abstract type bigfr, too.

We have chosen to not regard MPFR and GMP-MPF as equivalent.  MPFR provides a lot more behind the scenes.

Lisp objects can be tested for the type bigfr by the following predicate.

 -- Function: bigfrp object
     This predicate tests whether its argument is a MP-float (as provided by MPFR), and returns t if so, nil otherwise.

The read syntax (and print syntax) of bigfrs is the same as for emacs floats.  The interpretation in the lisp reader depends on the variable READ-REAL-AS (see Category real).

There are no other forms of creation, especially there are no constructors for bigfr objects.

As required by MPFR, SXEmacs supports indefinite number values which can occur as return values of some MPFR functions.  Such number objects, however, are not of type bigfr anymore.  We provide a more general handling for these, see Type indefinite for more information.

Again, numbers of type bigfr can be assigned a precision. This precision can be queried and even may be changed at any time.

 -- Function: bigfr-get-precision number
     Return the precision of NUMBER as an integer.

 -- Function: bigfr-set-precision number precision
     Set the precision of NUMBER to PRECISION, a nonnegative integer. The new precision of NUMBER is returned.

     Note that the return value may differ from PRECISION if the underlying library is unable to support exactly PRECISION bits of precision. Note also, that setting the precision is lossy, that means NUMBER after setting the precision is not necessarily the same as the original NUMBER.

The Type bigc
-------------

The type bigc is an abstract C type for arbitrary-precision complex number approximations with correct rounding facilities.  The actual C type is provided either by the MPC library (mpc_t) or by the SXEmacs pseudo imlementation based on MPFR.

Any other library which implements something similar to MPC, should be accessed via the abstract type bigc, too.

Lisp objects can be tested for the type bigc by the following predicate.

 -- Function: bigcp object
     This predicate tests whether its argument is a complex number (as provided by MPC or the SXEmacs pseudo-implementation), and returns t if so, nil otherwise.

For bigc objects exist two accessor functions, namely real-part and imaginary-part to access the respective parts of a complex number.

 -- Function: real-part number
     Return the real part of NUMBER.

 -- Function: imaginary-part number
     Return the imaginary part of NUMBER. If NUMBER is a comparable, 0 is returned.

The read syntax of bigcs is inspired by the notation of elements of algebraic adjunctions.  In these terms the lisp reader interprets A+Bi as bigc whenever both A and B are written in float syntax, alternatively it is allowed to capitalise the imaginary symbol.  If the imaginary part of a bigc is one, it is additionally allowed to omit B. Consider the examples:

     2.0+3.0i
          => 2.000000+3.000000i
     2.0+3.0I
          => 2.000000+3.000000i
     3.0+i
          => 3.000000+1.000000i

Note that the read syntax for complex numbers steals a whole class of possible symbol identifiers.  In a non-ENT-SXEmacs 2.0+3.0I is a valid name for a variable.

There is also the possibility to create bigc objects with a constructor, passing a real and an imaginary part to it.  Both real and imaginary part may be of any comparable number type, in this case.  In a certain sense, this is the inverse function of the selector functions above.

 -- Function: make-bigc real-part imaginary-part
     Return the bigc number whose real component is REAL-PART and whose imaginary component is IMAGINARY-PART.

     (make-bigc 1 2)
          => 1.000000+2.000000i
     (make-bigc 1/2 3/2)
          => 0.500000+1.500000i

Again, numbers of type bigc can be assigned a precision. This precision can be queried and changed at any time.

 -- Function: bigc-get-precision number
     Return the precision of NUMBER as an integer.

 -- Function: bigc-set-precision number precision
     Set the precision of NUMBER to PRECISION, a nonnegative integer. The new precision of NUMBER is returned.

     Note that the return value may differ from PRECISION if the underlying library is unable to support exactly PRECISION bits of precision. Note also, that setting the precision is lossy, that means NUMBER after setting the precision is not necessarily the same as the original NUMBER.

The precision always affects both, the real and the imaginary part. Although supported by the underlying library, SXEmacs will not handle selective precision assignment.

The Type bigg
-------------

As of November 2005, there is no library dedicated to Gaussian numbers available.  Thusly, the abstract C type bigg is implemented only via the SXEmacs pseudo implementation based on GMP-MPZ.  Gaussian numbers are represented by two MPZ objects.

Nonetheless, any library which implements Gaussian numbers should be accessed via the abstract type bigg in the future.

Lisp objects can be tested for the type bigg by the following predicate.

 -- Function: biggp object
     This predicate tests whether its argument is a Gaussian number (as provided by the SXEmacs pseudo-implementation), and returns t if so, nil otherwise.

For bigg objects exist the same accessor functions as for bigc objects, real-part and imaginary-part to access the respective parts of a Gaussian number.  Hereby, real-part returns the integral rational part.

The read syntax of biggs is inspired by the traditional notation of the elements of a Gaussian lattice.  In these terms the lisp reader interprets A+Bi as bigg whenever both A and B are written in integer syntax, alternatively it is allowed to capitalise the imaginary symbol.  If the imaginary part of a bigg is one, it is additionally allowed to omit B. Consider the examples:

     2+3i
          => 2+3i
     2+3I
          => 2+3i
     3+i
          => 3+1i

And similar to bigc complex numbers, there is a constructor which composes a Gaussian number from a given integral rational and a given imaginary component.

 -- Function: make-bigg real-part imaginary-part
     Return the bigg number whose rational component is REAL-PART and whose imaginary component is IMAGINARY-PART.

The Type indefinite
-------------------

In order to handle indefinite number values, SXEmacs provides an abstract type to gather these and sophisticated means to handle them. Indefinites are treated like ordinary numbers.  They take part in arithmetic and can be used for many mathematical functions.

Howbeit, indefinites cannot be explicitly generated because there merely finitely many.  Hence there are variables which refer to the indefinites, their print syntax is identical to their symbol name.

 -- Variable: +infinity
     A symbol representing positive infinity.

 -- Variable: -infinity
     A symbol representing negative infinity.

 -- Variable: complex-infinity
     A symbol representing the infinitely distant point in the complex plane.

 -- Variable: not-a-number
     A symbol representing a not-a-number (NaN) value.

The big difference to other number objects is that indefinites may shadow another other number types.  This makes them more a category than actually a number type of its own.  Due to efficiency reasons and cleaner coding we have chosen to assign them their own type and allowed them to behave as another number type.  That is SXEmacs does not distinguish between the positively infinite point of the rational integers and the positively infinite point of the reals.

On the other hand (and as typically seen in mathematics), the infinities are not part of the class of numbers of a certain type, therefore the type predicates of other number types will always yield nil.  That means the programmer must track the history of computations to find out which element or term spawned the occurrence of indefinites (if that information is valuable of course).

As usual for number types indefinites have their own predicate

 -- Function: indefinitep object
     Return t if OBJECT is an indefinite symbol, nil otherwise.

Infinities, a subset of the indefinites, can be type-checked separatedly.

 -- Function: infinityp object
     Return t if OBJECT is a form of infinity, nil otherwise.

Note also, the indefinite not-a-number is indeed not a number, thence the category predicate numberp will return nil for not-a-number (see Category number).

The Type residue-class-ring
---------------------------

The type residue-class-ring is a super-type for all possible residue class rings, which in turn are the worlds (actually the types) of residue classes.  To progressively meet the actual need for infinitely many types, we instead gather them into this super-type. The underlying C-type is resc_rng.

Lisp objects can be tested for the type residue-class-ring by the following predicate.

 -- Function: residue-class-ring-p object
     Return t if OBJECT is a residue class ring, nil otherwise.

The read syntax of residue-class-rings is inspired by the traditional algebra, hence the lisp reader interprets Z/MZ as residue-class-ring whenever M is a rational integer.  We call M the modulus of the residue class ring.

Of course, there exists a constructor to derive a residue class ring from a given modulus:

 -- Function: make-residue-class-ring modulus
     Return a residue class ring of size MODULUS (>= 2).

     Z/24Z
          => Z/24Z
     (make-residue-class-ring 24)
          => Z/24Z

The converse is possible via the accessor function residue-class-modulus, too.  See next section for a detailed description.

The Type residue-class-ring
---------------------------

The type residue-class is actually a world of worlds where residue class ring elements may live.  Their actual ``type'' is the residue class ring where the element is contained.  Therefore (higher-ary) operations over residue classes must always perform two type checks, firstly whether an object lives in the world of worlds of residue classes, and secondly whether all of the residue classes are contained in the same ring. The underlying C-type is resc_elm.

Lisp objects can be tested for the type residue-class by the following predicate.

 -- Function: residue-class-p object
     Return t if OBJECT is a residue class, nil otherwise.

For residue-class objects exists an accessor function to obtain the ring in which a certain residue class is contained.

 -- Function: residue-class-ring resclass
     Return the parental residue class ring (the world) of RESCLASS.

The read syntax of residue-classes is inspired by the traditional algebra, hence the lisp reader interprets C+MZ as residue-class whenever both C and M are rational integers, and M is positive.  We call C a representant of the residue class.

Of course, there exists a constructor to derive a residue class from a given representant:

 -- Function: make-residue-class element ring
     Return the residue class of ELEMENT in RING.

     This is a lift of the integer ELEMENT into one of the classes of RING.

Note that arbitrary class members of a residue class are mapped to one canonical representant.

     2+9Z
          => 2+9Z
     (make-residue-class 2 Z/9Z)
          => 2+9Z

     ;; a canonicalisation
     24+9Z
          => 6+9Z

To regain the representant's integer value there is an accessor function residue-class-representant:

 -- Function: residue-class-representant element
     Return the representant of the residue class ELEMENT lifted to the ring of rational integers.

Similarly there is an accessor for the modulus:

 -- Function: residue-class-modulus ring-or-element
     Return the modulus of the residue class ring RING-OR-ELEMENT, or the modulus of a residue class, respectively.

     (residue-class-representant 3+4Z)
          => 3
     (residue-class-representant 6+4Z)
          => 2

     (residue-class-modulus 3+4Z)
          => 4
     (residue-class-modulus Z/7Z)
          => 7

The Type quatern
----------------

The type quatern is an abstract C type for integral elements of the quaternion division algebra.  The actual C type (quatern) is pseudo-implemented as a struct of 4 MP-integers, which are based on either GMP-MPZ or BSD-MP.

Lisp objects can be tested for the type quatern by the following predicate.

 -- Function: quaternp object
     Return t if OBJECT is a quaternion, nil otherwise.

The read syntax of quaterns is similar to the read syntax for complex numbers.  The lisp reader interprets A+Bi+Cj+Dk as quatern whenever A, B, C and D are all rational integers.  We call A the z-part, B the i-part, C the j-part and D the k-part of the quaternion.

As for complex or gaussian numbers, there exists a constructor make-quatern which may be used to compose a quaternion by its components.

 -- Function: make-quatern z i j k
     Return the Quaternion whose z-component is Z, whose i-, j-, and k-components are I, J and K, respectively.

     2+4i+3j+k
          => 2+4i+3j+1k
     0-I-J-K
          => 0-1i-1j-1k
     (make-quatern 2 1 2 0)
          => 2+1i+2j+0k

And again, the single linear factors of a quaternion are regainable by the accessor functions quatern-z, quatern-i, quatern-j and quatern-k.

 -- Function: quatern-z quatern
     Return QUATERN's z-component.

 -- Function: quatern-i quatern
     Return QUATERN's i-component.

 -- Function: quatern-j quatern
     Return QUATERN's j-component.

 -- Function: quatern-k quatern
     Return QUATERN's k-component.

     (quatern-z 1+2i-3j-k)
          => 1
     (quatern-i 1+2i-3j-k)
          => 2
     (quatern-j 1+2i-3j-k)
          => -3
     (quatern-k 1+2i-3j-k)
          => -1

Unions of Number Types
======================

Formally, we refer to numbers (and anything number-related) in the SXEmacs lisp environment by a category called number.  The category number (deductively) consists of all SXEmacs lisp objects which can be used in the arithmetical functions + and *, and which possess a canonical norm, i.e. for which the function canonical-norm returns a value.

Of course, in our deductive approach, we wish to fragment the category number seamlessly into several subcategories.  You can take for granted that this is possible.  To not scare you completely off, we look at an inductive approach instead.

The inductive approach attempts to start at something like the atoms of the enhanced number facilities, namely the C types.  As discussed in the previous section, C types themselves are gathered and unified into an abstract C type, which is library independent.  Now we try further unifications to get something like the super-type, which we call a category, since its objects do not physically carry this type.

The category integer
--------------------

The category of integers is probably the most transparent one.  This is of course due to the fact, that SXEmacs did provide integers before.  Now it would be unregrettably stupid, if we invented another read-syntax for the additional integers.  Hence big integers are unified transparently with ordinary 28-bit integers.  The subcategory of ordinary emacs integers is called int or fixnum.

Nevertheless, we provide functions to distinguish them, and to coerce from the one type to the other.

 -- Function: intp object
     This predicate tests whether its argument is an ordinary emacs integer, and return t if so, nil otherwise.

 -- Function: fixnump object
     This is roughly the same as intp and is provided for compatibility to XEmacs.

 -- Function: bigzp object
     This predicate tests whether its argument is a big integer (as provided by GMP-MPZ or BSD-MP), and returns t if so, nil otherwise.

 -- Function: bignump object
     This is roughly the same as bigzp and is provided for compatibility to XEmacs.

Unfortunately, ordinary emacs integers show some behaviour which in the new category of integers is not bearable anymore.  This may lead to confusion in simpler cases, if not even to wrong code.

The following example shows the most significant change:

     In an old fixnum-only SXEmacs:
     (+ 1 134217727)
          => -134217728

     The same in a SXEmacs with ENT:

     (+ 1 134217727)
          => 134217728

     Now the resulting integer is of bigz type.

     (bigzp (+ 1 134217727))
          => t

Now, in general we can state, that whenever space is too tight for an integer to fit into the built-in integer type, this integer is coerced to the type bigz.

The reverse is not necessarily true.  But there is an auto-coercion, known as canonicalisation, to bang big integers to ints, when they are small enough and to bang fractions which cancel to denominator 1 to integers, but some functions acquiesce their output as is. See the following examples:

     (bigzp (2^ 42))
          => t
     (bigzp (/ (2^ 42) (2^ 30)))
          => nil

     (factorial 4)
          => 24
     (bigzp (factorial 4))
          => t

We say, that / canonicalises its results, whereas factorial does not.  Canonicalisation usually depends on the size of output compared to average input values.  This is much too vague for practice.

However, in order to be absolutely sure about the world where resulting integers (even fractions which cancel to integers) live, there is a canonicalisation function.

 -- Function: canonicalize-number number
     Return the canonical form of NUMBER.

This function determines the smallest category a number can live in, and coerces to there.  Hereby smallest category means the category with the least cardinality.

     (bigzp (factorial 4))
          => t
     (bigzp (canonicalize-number (factorial 4)))
          => nil

Canonicalisation actually begins in the expression reader already, consider the quotient 4/2, which cancels to 2.

     4/2
          => 2
     (bigqp 4/2)
          => nil

The category rational
---------------------

The category of rationals gathers everything that is rational. Practically, it is the union of the integers with the bigqs.

The category's predicate is rationalp.

 -- Function: rationalp object
     Return t if OBJECT is a rational (i.e. a rational integer or a rational quotient), nil otherwise.

     (rationalp 0)
          => t
     (rationalp (factorial 100))
          => t
     (rationalp 1/2)
          => t

The category real
-----------------

The category of reals consists of the emacs floats and all arbitrary real-approximations (bigf, bigfr if provided). Possibly, if provided, it contains the symbolic ``number'' objects for positive and negative infinity, as well as NOT-A-NUMBER.

Important note: As stated in the definition above, rationals are not in the category of reals.  This might seem contradictory, because (especially in school mathematics or calculus classes) reals are sometimes defined as the union of rationals and irrationals.  From the algebraic view, this is approach is inconsistent.  Please see Category comparable.  On the other hand, the non-ENT equivalent of real would be float, and in terms of non-ENT emacsen, fixnums are no floats.

The category's predicate is realp.

 -- Function: realp object
     Return t if OBJECT is real (i.e. a float or one of the arbitrary-precision floats), nil otherwise.

     (realp 0.0)
          => t
     (realp (exp 1))
          => t
     (realp (coerce 1 'bigf))
          => t
     (realp +infinity)
          => t
     (realp not-a-number)
          => t

     (realp 1)
          => nil
     (realp 1/2)
          => nil

Additionally, the category real has some variables to control which float implementation is used.  This is necessary as there is no information about loss of precision, and there is no function to measure if a float number would fit in one type or the other.

 -- Variable: read-real-as
     Indicate how real numbers should be read. If set to `nil' or 'float, reals are always converted to floats. If set to 'bigf or 'bigfr, reals are read as MPF floats or MPFR floats respectively.

 -- Variable: default-real-precision
     The default floating-point precision for newly created floating point values. This should be an unsigned integer no greater than MAX-REAL-PRECISION to create external floats with the indicated precision.

     This variable is effective only when READ-REAL-AS is set to a float type which supports setting a precision.

 -- Variable: max-real-precision
     The maximum number of bits of precision a bigf or bigfr can have.  This is determined by the underlying library used to implement arbitrary-precision floats.

The category comparable
-----------------------

Deductively, the category of comparables are all numbers which possess a total (archimedean) order.  Inductively, this category is the union of reals and rationals.  Comparables, as the names suggests, can be directly compared with ordering relations, such as < or >.

The category's predicate is comparablep.

 -- Function: comparablep object
     Return t if OBJECT is comparable (i.e. a real or a rational), nil otherwise.

     We call a number comparable if there exists a total (archimedean) order on the underlying structure.

     (comparablep 0)
          => t
     (comparablep 1/2)
          => t
     (comparablep 0.5)
          => t

The category nonnegative
------------------------

The category of nonnegatives are those comparables which are not less than zero.  This explicitly implies, that 0 is nonnegative.  The restriction to comparables is necessary, since the membership is indeed tested as in the definition.

The category's predicate is nonnegativep.

 -- Function: nonnegativep object
     Return t if OBJECT is a nonnegative number, nil otherwise.

     We call a number object non-negative iff it is comparable and its value is not less than 0.

     (nonnegativep 0)
          => t
     (nonnegativep 1/2)
          => t
     (nonnegativep 1.5)
          => t

     (nonnegativep -1/2)
          => nil
     (nonnegativep -0.5)
          => nil

     (nonnegativep 1+2i)
          => nil

The category complex
--------------------

The category of complices is the union of bigcs and biggs.  Explicitly, neither reals nor rationals are in the category of complex numbers, in contrast to some analytical definitions.  See Category archimedean for that.

The category's predicate is complexp.

 -- Function: complexp object
     Return t if OBJECT is a complex number (i.e. either a bigc or a bigg), nil otherwise.

     (complexp 1+2i)
          => t
     (complexp 1.0+2.2i)
          => t
     (complexp (sqrt -2))
          => t

     (complexp 1)
          => nil
     (complexp 1.0)
          => nil
     (complexp 1/2)
          => nil

The category archimedean
------------------------

Deductively, the category of archimedeans contains all numbers which do have an archimedean valuation.  Inductively, the category of archimedeans is the union of reals, rationals, complices and quaternions.

The category's predicate is archimedeanp.

 -- Function: archimedeanp object
     Return t if OBJECT is a number with an archimedean valuation, nil otherwise.

     (archimedeanp 0)
          => t
     (archimedeanp 1/2)
          => t
     (archimedeanp 1.2)
          => t
     (archimedeanp pi)
          => t
     (archimedeanp (sqrt -2))
          => t

The category nonarchimedean
---------------------------

Deductively, the category of non-archimedeans contains all numbers which do not have an archimedean valuation -- hence this category also holds numbers with trivial valuation.

Currently, only residue classes are non-archimedeans for their only possible valuation is the trival one (which is not archimedean).

The category's predicate is nonarchimedeanp.

 -- Function: nonarchimedeanp object
     Return t if OBJECT is a number with an non-archimedean valuation, nil otherwise.

     (nonarchimedeanp 0)
          => nil
     (nonarchimedeanp 1/2)
          => nil
     (nonarchimedeanp 1.2)
          => nil
     (nonarchimedeanp 12+121Z)
          => t

The category algebraic
----------------------

Not yet implemented.

The category transcendent
-------------------------

Not yet implemented.

The category zero
-----------------

The category of zeroes are all numbers which represent a zero, that is an additive neutral element.  In that sense, the following is always true:

     (equal NUM (+ 0 NUM))

The category's predicate is zerop.

 -- Function: zerop object
     Return t if OBJECT is a zero, nil otherwise.

Let us look at a variety of examples.

     (zerop 0)
          => t
     (zerop 0/1)
          => t
     (zerop 0.0)
          => t
     (zerop 0+0i)
          => t
     (zerop 0.0+0.0i)
          => t
     (zerop 0+7Z)
          => t
     (zerop 7+7Z)
          => t
     (zerop 0+0i+0j+0k)
          => t

There is a constructor for zeroes which accepts an arbitrary number and uses that to determine the world, read type, the number lives in. Afterwards it creates and returns the zero of that number type.

 -- Function: zero number
     Return the zero of the world NUMBER lives in.

     (zero 23)
          => 0
     (zero 2/3)
          => 0
     (zero 1.4)
          => 0.0
     (zero 1+2i)
          => 0+0i
     (zero 1.2+3.4i)
          => 0.000000+0.000000i
     (zero 7+14Z)
          => 0+14Z
     (zero 7+13Z)
          => 0+13Z

The category one
----------------

The category of ones are all numbers which represent a one, that is a multiplicative neutral element.  In that sense, the following is always true:

     (equal NUM (* 1 NUM))

The category's predicate is onep.

 -- Function: onep object
     Return t if OBJECT is a one, nil otherwise.

As for zeroes, there is a constructor for ones, too, which similarly accepts an arbitrary number and uses that to determine the world of the number.  Afterwards it creates and returns the one of that number type.

 -- Function: one number
     Return the one of the world NUMBER lives in.

     (one 23)
          => 1
     (one 2/3)
          => 1
     (one 1.4)
          => 1.0
     (one 1+2i)
          => 1+0i
     (one 1.2+3.4i)
          => 1.000000+0.000000i
     (one 7+14Z)
          => 1+14Z
     (one 7+13Z)
          => 1+13Z

The category number
-------------------

Inductively, the union of all categories discussed above is the category number.  The category's predicate is numberp.

 -- Function: numberp object
     Return t if OBJECT is a number, nil otherwise.

Coercion
========

Like for non-ENT-SXEmacsen, various coercions (conversions) can be done.  Hereby, on coercion numbers may lose some of their information.  Possibly this loss of information totally destroys the numeric value of a number, and thusly makes coercion uninvertable in general.

 -- Function: coerce-number number type &optional precision
     Convert NUMBER to the indicated type, possibly losing information. See coerce.

     TYPE is one of the symbols: - FIXNUM or INT  to convert to built-in integers - BIGZ or BIGNUM to convert to bigz integers - INTEGER              to convert to the most suitable type out of BIGZ or INT

     - BIGQ or RATIO  to convert to bigq fractions - RATIONAL             to convert to the most suitable type out of BIGQ, BIGZ or INT

     - FLOAT                to convert to built-in floats
     - BIGF or BIGFLOAT  to convert to bigf floats
     - BIGFR                to convert to bigfr floats
     - REAL                 to convert to the type indicated by
     READ-REAL-AS with a fallback to
     FLOAT

     - BIGG                 to convert to a Gaussian
     - BIGC                 to convert to a bigc complex number

     Note: Not all of these types may be supported.

     The optional argument PRECISION is the number of bits of precision to use when converting to reals; it is ignored otherwise. If nil, the default precision is used.

     Note that some conversions lose information.  No error is signaled in such cases; the information is silently lost.

     (coerce-number 1 'bigz)
          => 1
     (bigzp (coerce-number 1 'bigz))
          => t

     (coerce-number 1 'integer)
          => 1
     (coerce-number (exp 40) 'integer)
          => 235385266837019985
     (bigzp (coerce-number 1 'integer))
          => nil
     (bigzp (coerce-number (exp 40) 'integer))
          => t

     (coerce-number 8/2 'bigq)
          => 4
     (coerce-number 8/2 'rational)
          => 4
     (bigqp (coerce-number 8/2 'bigq))
          => t
     (bigqp (coerce-number 8/2 'rational))
          => nil

Now an example for how to effectively lose information and hence make coercion uninvertable.

     (coerce-number 4/3 'bigfr)
          => 1.333333333333333333333333333333333333335
     (coerce-number (coerce-number 4/3 'bigfr) 'bigq)
          => 105637550019019116791391933781/79228162514264337593543950336

Besides, the types bigf, bigfr and bigc allow you to pass a precision to coerce-number and some mathematical functions.  In order to get a notion of varying precisions, we will first present some examples:

     (coerce-number 49000 'bigfr 16)
          => 49000.0
     (coerce-number 49000 'bigfr 13)
          => 49000.
     (coerce-number 49000 'bigfr 12)
          => 48992.
     (coerce-number 49000 'bigfr 10)
          => 49024.
     (coerce-number 49000 'bigfr 9)
          => 49020
     (coerce-number 49000 'bigfr 8)
          => 48900
     (coerce-number 49000 'bigfr 7)
          => 49150
     (coerce-number 49000 'bigfr 4)
          => 49200

Here you can see precisely how rounding affects the actual value of a number.  Also note, with precision 9 or lower the number is not actually a float anymore, because the radix would require more digits in order to be set.  Whenever something like this occurs, we fill the output with trailing zeroes instead of using the scientific exponential notation.  That means, we write 48900 instead of 4.89E+4.

Even more complicated is the situation with one-way coercions. Numbers of the category complex cannot be coerced to numbers of the category comparable.  This is because there exist a dozen methods to do that, and it is not clear which one to use.

     (coerce-number 1 'bigg)
          => 1+0i
     (coerce-number (coerce-number 1 'bigg))
          => Wrong type argument: comparablep, 1+0i

To ease that pain a little you can explicitly use your favourite embedding into comparables.  For example:

     (defun my-coerce-from-bigg (num)
       (if (zerop (imaginary-part num))
           (real-part num)
         (canonical-norm num)))
          => my-coerce-from-bigg

     (let ((num (coerce-number 3 'bigg)))
       (my-coerce-from-bigg num))
          => 3

     (let ((num 3+2i))
       (my-coerce-from-bigg num))
          => 13

There are some abbreviated forms for number coercion.

 -- Function: int number &optional precision
     Return the ordinary integer numerically equal to NUMBER. The optional argument PRECISION is unused.

     This is equivalent to (coerce-number NUMBER 'int precision)

 -- Function: bigz (number &optional precision)
     Return the MPZ number numerically equal to NUMBER. The optional argument PRECISION is unused.

     This is equivalent to (coerce-number NUMBER 'bigz precision)

 -- Function: bigq (number &optional precision)
     Return the MPQ number numerically equal to NUMBER. The optional argument PRECISION is unused.

     This is equivalent to (coerce-number NUMBER 'bigq precision)

 -- Function: rational (number &optional precision)
     Return a rational most suitable to represent NUMBER. The optional argument PRECISION is unused.

     This is equivalent to (coerce-number NUMBER 'rational precision)

 -- Function: float number
     Return the floating point number numerically equal to NUMBER.

 -- Function: bigf (number &optional precision)
     Return the MPF number numerically equal to NUMBER. If optional argument PRECISION is non-nil, its value (an integer) is used as precision.

     This is equivalent to (coerce-number NUMBER 'bigf precision)

 -- Function: bigfr (number &optional precision)
     Return the MPFR number numerically equal to NUMBER. If optional argument PRECISION is non-nil, its value (an integer) is used as precision.

     This is equivalent to (coerce-number NUMBER 'bigfr precision)

 -- Function: real (number &optional precision)
     Return a real with respect to READ-REAL-AS numerically equal to NUMBER. If optional argument PRECISION is non-nil, its value (an integer) is used as precision.

     This is equivalent to (coerce-number NUMBER 'real precision)

 -- Function: bigg (number &optional precision)
     Return the Gaussian number numerically equal to NUMBER. The optional argument PRECISION is unused.

     This is equivalent to (coerce-number NUMBER 'bigg precision)

 -- Function: bigc (number &optional precision)
     Return the MPC number numerically equal to NUMBER. If optional argument PRECISION is non-nil, its value (an integer) is used as precision.

     This is equivalent to (coerce-number NUMBER 'bigc precision)

Revised Arithmetics
===================

Of course, arithmetical functions like +, * and so forth, have been reused for enhanced number types.  These are transparently overlaid.  This concept allows to use the same emacs lisp code for both non-ENT and ENT-SXEmacsen.

However, some of the arithmetical changes are not intuitive, so we discuss them here.  Please always refer to Numbers for function and variable equivalents in a non-ENT-SXEmacs.

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.

New Arithmetical Functions
--------------------------

Completing basic arithmetics, ENT provides functions for exponentiation.  In general, it is highly advised to prefer the dedicated power function over successive multiplication.  We give a timing example below.

 -- Function: ^ number1 number2
     Return the power NUMBER1 to the NUMBER2.

     (^ 3 4)
          => 81
     (^ 81 23)
          => 78551672112789411833022577315290546060373041

Note that exponentiation is not associative.  That is why ^ merely takes two arguments at a time.  Check the order of computation carefully.  The following example demonstrates the generated error in case of wrong association.

     (^ 2 (^ 3 4))
          => 2417851639229258349412352
     (^ (^ 2 3) 4)
          => 4096

In order to get a notion of the time differences,

     (let ((start (current-btime))
           (dummy (^ 2 (^ 3 4)))
           (stop (current-btime)))
       (- stop start))
          => 31

Now we perform the same with sequential multiplication:

     (let* ((start (current-btime))
            (3^4 (* 3 3 3 3))
            (result 1)
            (2^3^4 (dotimes (i 3^4 result)
                      (setq result (* 2 result))))
            (stop (current-btime)))
       (- stop start))
          => 567

To see the superiority, we modify the actual problem.

     (let ((start (current-btime))
           (dummy (^ 5 (^ 5 5)))
           (stop (current-btime)))
       (- stop start))
          => 77

     (let* ((start (current-btime))
            (5^5 (* 5 5 5 5 5))
            (result 1)
            (5^5^5 (dotimes (i 5^5 result)
                      (setq result (* 5 result))))
            (stop (current-btime)))
       (- stop start))
          => 21963

Whenever computing two-powers or ten-powers, there are dedicated functions which make use of special algorithms.

 -- Function: 2^ number &optional precision
     Return the exponential of NUMBER to 2 power. If optional argument PRECISION is non-nil, its value (an integer) is used as precision in float computations.

 -- Function: 10^ number &optional precision
     Return the exponential of NUMBER to 10 power. If optional argument PRECISION is non-nil, its value (an integer) is used as precision in float computations.

There is another arithmetic function working on the prime decomposition of integer numbers.  This is roughly equivalent to repeatedly check if a number is congruent modulo a factor and if so a division by that factor.

 -- Function: remove-factor factor number
     Remove all occurences of FACTOR in NUMBER and return a cons cell with NUMBER divided by a maximal power of FACTOR in the car and the exponent in the cdr.

     (remove-factor 5 25)
          => (1 . 2)
     (remove-factor 7 25)
          => (25 . 0)
     (remove-factor 11 2198765678901)
          => (18171617181 . 2)

New Output Formatting Features
==============================

ENT provides a number of new format specifiers:

  * %Z means print as big integer (convert to bigz)

  * %Q means print as fraction (convert to bigq)

  * %F means print as bigfr or bigf float (convert to in that order) this specifier always converts the argument, regardless the value of `read-real-as'

  * %R means print as real number (convert to bigfr, bigf or float) this specifier respects the value of `read-real-as'

  * %B means print as Gaussian number (convert to bigg)

  * %C means print as complex number (convert to bigc)

Both %B and %C are actually rewrites to %Z%+Z and %F%+F respectively with the argument ARG rewritten to (real-part ARG) (imaginary-part ARG). Flags are passed on to at least the real part specifier.

On the other hand, we have tried to seamlessly integrate the new specifiers along with the ordinary ones.  Any number object is coerced to the integers if %d or %Z is used, if that is possible (see Coercion).  Besides, the base converters work on any number in two steps, too: firstly, coerce to the integers, secondly convert to another base.

Time for examples.  Here we demonstrate the equivalence of %d and %Z if used with big integers as arguments.

     (format "%d" (factorial 20))
          => "2432902008176640000"
     (format "%30d" (factorial 20))
          => "           2432902008176640000""
     (format "%.30d" (factorial 20))
          => "000000000002432902008176640000"

     (format "%Z" (factorial 20))
          => "2432902008176640000"
     (format "%30Z" (factorial 20))
          => "           2432902008176640000""
     (format "%.30Z" (factorial 20))
          => "000000000002432902008176640000"

Now we look at the coercion facilities:

     (format "%d" (exp 1))
          => "3"
     (format "%Z" pi)
          => "3"
     (format "%d" 2/3)
          => "0"
     (format "%Z" 4+3i)
          => Wrong type argument: comparablep, 4+3i

Let us have a quick glance at the specifiers %f, %F and %R.  The most obvious difference is their way to format precision flags, especially how they do precision rounding.

The specifier %f performs a mathematically correct rounding, whereas %F cuts the precision, that is it truncates the result at the given place.

     (format "%f" (exp 1))
          => "2.718282"
     (format "%.2f" (exp 1))
          => "2.72"
     (format "%+.2f" (exp 1))
          => "+2.72"

     (format "%F" (exp 1))
          => "2.718281828459045235360287471352662497759"
     (format "%.2F" (exp 1))
          => "2.71"
     (format "%+.2f" (exp 1))
          => "+2.71"

Indeed, %R is rewritten to either %f or %F, depending on whether READ-REAL-AS is set to 'float or 'bigf or 'bigfr, thusly precision rounding is performed the way of the rewritten specifier.

     read-real-as
          => 'float
     (format "%R" (exp 1))
          => "2.718282"
     (format "%.2R" (exp 1))
          => "2.72"

     (let ((read-real-as 'bigfr))
       (format "%R" (exp 1)))
          => "2.718281828459045235360287471352662497759"
     (let ((read-real-as 'bigfr))
       (format "%.2R" (exp 1)))
          => "2.71"

A special exception of the float formatting rule are indefinite numbers (we like it to call them indefinite symbols since they are not numbers).  These are +infinite, -infinite and not-a-number.  Except the total width flag all of the special flags are ignored in their format specification.

     (format "%F" +infinity)
          => "+infinity"
     (format "%F" -infinity)
          => "-infinity"
     (format "%F" not-a-number)
          => "not-a-number"

     (format "%+F" +infinity)
          => "+infinity"
     (format "% F" -infinity)
          => "-infinity"
     (format "%.10F" not-a-number)
          => "not-a-number"

and compare to:

     (format "%12F" +infinity)
          => "   +infinity"
     (format "%-12F" -infinity)
          => "-infinity   "
     (format "%20F" not-a-number)
          => "        not-a-number"

The coercion to rational quotients (and their output formatting) is straightforward.  It suffers from the impossibility to sanely coerce from floating point numbers, see Coercion.

The precision flag, in contrast, has no effect on rational quotients.  It is generally deprecated to prepend leading zeroes to the numerator of a fraction.

If the quotient can be cancelled it is done so, and the formatted output uses this cancelled fraction.  If the quotient cancels to a rational integer, i.e. if the denominator is 1, the formatted output shows the integer equivalent of the fraction.  Note that even in that situation the precision flag has no effect.

     (format "%Q" 2)
          => "2"
     (format "%Q" 4/2)
          => "2"
     (format "%4Q" 4/2)
          => "   2"
     (format "%.4Q" 4/2)
          => "2"

     (format "%Q" 2/3)
          => "2/3"
     (format "%5Q" 2/3)
          => "  2/3"
     (format "%5.5Q" 2/3)
          => "  2/3"
     (format "%+Q" 2/3)
          => "+2/3"
     (format "% Q" 2/3)
          => " 2/3"

     (format "%Q" 1.5)
          => "3/2"
     (format "%Q" 0.66666)
          => "3002369727582815/4503599627370496"

Finally we have a detailed look at the rewriting technique of complex and Gaussian numbers.

     (format "%B" 2+i)
          => "2+1i"
     (format "%Z%+Zi" (real-part 2+i) (imaginary-part 2+i))
          => "2+1i"

     (format "%C" 1+i)
          => "1.00000000000000+1.00000000000000i"
     (format "%F%+Fi" (real-part 1+i) (imaginary-part 1+i))
          => "1.00000000000000+1.00000000000000i"

Flag characters as well as padding and precision flags are passed to the rewritten specifiers with the following exception, the space and unary plus flags are not passed to the second rewritten specifier, instead the second rewritten specifier is always flagged with the unary plus.

     (format "%.4C" 1+i)
          => "1.0000+1.0000i"
     (format "% B" 2+i)
          => " 2+1i"
     (format "%+.2C" 2+3i)
          => "+2.00+3.00i"

     (format "%10.4C" 1+i)
          => "    1.0000   +1.0000i"
     (format "%+10.4B" 1+i)
          => "     +0001     +0001i"
     (format "%-10.2C" 0+0i)
          => "0.00      +0.00     i"

Number Theoretic Functions
==========================

If GMP is available, some number theoretic functions are in effect. Most of which accept, unlike in number theory, all kinds of numbers. In that case coercion to the target range (mostly integer) takes place.

 -- Function: primep number &optional certainty-threshold
     Return nil if NUMBER is known to be composite, return t if NUMBER is definitely prime and return 'probably-prime if NUMBER seems to be prime but it is not certain.

     If optional argument CERTAINTY-THRESHOLD is non-nil, it should be a natural number to indicate how many probabilistic primality tests must be passed in order to have certainty about the primality of NUMBER. The default is 8.

 -- Function: next-prime number
     Return the next prime number greater than NUMBER.

 -- Function: gcd &rest numbers
     Return the greatest common divisor of the arguments.

 -- Function: xgcd &rest numbers
     Return the extended gcd of the arguments. The result is a list of integers, where the car is the actual gcd and the cdr consists of coefficients, S1, ..., SN, such that S1*ARG1 + ... + SN*ARGN = gcd.

 -- Function: lcm &rest numbers
     Return the least common multiple of the arguments.

 -- Function: factorial number
     Return the factorial of NUMBER.

 -- Function: binomial-coefficient n k
     Return the binomial coefficient, N over K.

 -- Function: fibonacci number
     Return the NUMBERth Fibonacci number. To compute both, the NUMBERth and (NUMBER-1)th Fibonacci number use fibonacci2 instead.

 -- Function: fibonacci2 number
     Return a cons with the NUMBERth and (NUMBER-1)th Fibonacci number. To compute a series of Fibonacci numbers starting at index NUMBER, use this function and recursively compute the rest.

 -- Function: lucas number
     Return the NUMBERth Lucas number. To compute both, the NUMBERth and (NUMBER-1)th Lucas number use lucas2 instead.

 -- Function: lucas2 number
     Return a cons with the NUMBERth and (NUMBER-1)th Lucas number. To compute a series of Lucas numbers starting at index NUMBER, use this function and recursively compute the rest.

 -- Function: divisiblep number d
     Return t if NUMBER is divisible by D, nil otherwise.

 -- Function: congruentp number c m
     Return t if NUMBER is congruent to C modulo M, nil otherwise.

 -- Function: perfect-power-p number
     Return t if NUMBER is a perfect power, nil otherwise. An integer NUMBER is said to be a perfect power if there exist integers, A and B, such that A^B = NUMBER.

 -- Function: perfect-square-p number
     Return t if NUMBER is a perfect square, nil otherwise. An integer NUMBER is said to be a perfect square if there exists an integer B such that B^2 = NUMBER.

 -- Function: integral-sqrt number
     Return a cons with the integral square root of NUMBER in the car and the remainder in the cdr. An integral square root is a number B and a remainder C such that B*B + C = NUMBER.

 -- Function: canonical-norm number
     Return the canonical norm of NUMBER.

 -- Function: conjugate number
     Return the (canonical) conjugate of NUMBER. If NUMBER is a comparable, just return NUMBER.

 -- Function: zero-divisor-p number
     Return t if NUMBER is a zero-divisor, nil otherwise. NUMBER is said to be a zero-divisor, if there exists another non-zero number B, such that NUMBER * B = 0

 -- Function: unitp number
     Return t if NUMBER is a unit, nil otherwise. NUMBER is said to be a unit, if there exists another number B (the inverse of NUMBER), such that NUMBER * B = 1

Auxiliary Functions using ENT
=============================

This section is an unstructured assortment of new functions or functions which change their behaviour in an ENT-build.

Time functions
--------------

 -- Function: current-btime
     Return the current time, as the number of microseconds since 1970-01-01 00:00:00. The time is returned as a big integer.

     (current-btime)
          => 1131714421468312
     (current-btime)
          => 1131714424362856

With current-btime some of the functions of the time-date library can be quickly rewritten.

Compare

     (/ (current-btime) (bigfr 86400000000))
          => 13098.5557760026967592

to

     (time-to-number-of-days (current-time))
          => 13098.55588377945

Also, conversions from ordinary time conses to big time integers and vice versa are supported.

 -- Function: time-to-btime specified-time
     Return a big integer from SPECIFIED-TIME with the number of microseconds since the Epoch.

 -- Function: btime-to-time specified-time
     Return a time specified as (high low usec) as obtainable from current-time from SPECIFIED-TIME.

     (time-to-btime (current-time))
          => 1131959836543525

     (btime-to-time 1131959836543525)
          => (17272 22044 543525)

Of course, existing time functions are changed when SXEmacs is compiled with ENT enabled, such that they take both, time cons cells and big integer time values.  We do not list the respective functions here again.

 -- Function: encode-btime &rest arguments
     Like `encode-time' but return a big integer time instead.

Random numbers
--------------

Having ENT enabled the random function may return pseudo-random integers of unlimited size.  However, called without the optional limit argument, random always returns an ordinary integer (int).

 -- Function: random &optional limit
     Return a pseudo-random number. All integers representable in Lisp are equally likely. On most systems, this is 31 bits' worth.

     With positive integer argument LIMIT, return random number in interval [0,LIMIT). LIMIT can be a big integer, in which case the range of possible values is extended.

     With argument t, set the random number seed from the current time and pid.

     (random (factorial 20))
          => 2391898294963683867
     (random (factorial 20))
          => 1300461496957250511

 -- Function: randomb limit
     Return a uniform pseudo-random number in the range [0, 2^LIMIT).

Sequences
---------

Having ENT and the residue class subfeature enabled the sequence accessor functions accept residue classes as their input.  This is a neat feature when round-robins over sequences are regarded.

     (let ((v (make-vector 12 0))
           (rr 0+12Z)
           (i 0))
       (while (<= (aref v rr) 43)
         (aset v rr i)
         (incf rr)
         (incf i))
       v)
          => [48 49 50 51 52 53 54 55 44 45 46 47]

The above example shows a counter (RR) which can be continuously incremented without the need to check if its value is still in the bounds of the vector.  The same snippet with RR being set to 0 would survive for 12 cycles and then yield: Args out of range: [0 1 2 3 4 5 6 7 8 9 10 11], 12.