BigRat

© 2009,2011 John Abbott
GNU Free Documentation License, Version 1.2



CoCoALib Documentation Index

Examples

User documentation

Generalities

The class BigRat is intended to represent (exact) rational numbers of practically unlimited range; it is currently based on the implementation in the GMP big integer library. This code forms the interface between CoCoALib and the big integer/rational library upon which it relies. It seems most unlikely that GMP will be displaced from its position as the foremost library of this type; as a consequence the class BigRat may eventually be replaced by GMP's own C++ interface.

The usual arithmetic operations are available with standard C++ syntax but generally these incur run-time overhead since results are returned through temporaries which are created and destroyed silently by the compiler. Thus if the variables a, b and c are each of type BigRat then a = b+c; is a valid C++ statement for placing the sum of b and c in a, but the sum is first computed into a hidden temporary which is then copied to a, and then finally the temporary is destroyed. As a general principle, the type BigRat is provided for convenience of representing rational values rather than for rapid computation.

There is an important exception to the natural syntax: ^ does not denote exponentiation; you must use the function power instead. We have chosen not to define operator^ to perform exponentiation because it is too easy to write misleading code: for instance, a*b^2 is interpreted by the compiler as (a*b)^2. There is no way to make the C++ compiler use the expected interpretation.

Arithmetic may also be performed between a BigRat and a machine integer or a BigInt. The result is always of type BigRat (even if the value turns out to be an integer). Do remember, though, that operations between two machine integers are handled directly by C++, and problems of overflow can occur.

It is important not to confuse values of type BigRat with values of type RingElem which happen to belong to the ring RingQQ. The distinction is analogous to that between values of type BigInt and value of type RingElem which happen to belong to the ring RingZZ. In summary, the operations available for RingElem are those applicable to elements of any ordered commutative ring, whereas the range of operations on BigRat values is wider (since we have explicit knowledge of the type).

The Functions Available For Use

Constructors

A value of type BigRat may be created from:

See Bugs section for why there is no ctor from a single integer, and also for why BigRat(0) is accepted by the compiler.

Infix operators

  1. normal arithmetic (potentially inefficient because of temporaries)
  2. arithmetic and assignment
  3. arithmetic ordering
  4. increment/decrement

More functions

  1. query functions (all take 1 argument)
  2. Exponentiation
  3. The cmp function (three way comparison)
  4. Other functions
  5. Functions violating encapsulation

Maintainer Documentation

Nothing very clever. Conversion from a string was a bit tedious.

Note that the ctor call BigRat(0) actually calls the ctor from a string. Unfortunately, this a C++ "feature". It will result in a run-time error.

I have replaced the bodies of the BigRat ctors which take two integers as arguments by a call to the common body BigRat::myAssign. This does mean that some wasteful temporaries are created when either of the arguments is a machine integer. Time will tell whether this waste is intolerable.

Bugs, Shortcomings and other ideas

This code is probably not exception safe; I do not know what the mpq_* functions do when there is insufficient memory to proceed. Making the code exception safe could well be non-trivial: I suspect a sort of auto_ptr to an mpq_t value might be needed.

Removed BigRat ctors from a single (machine) integer because too often I made the mistake of writing something like BigRat(1/2) instead of BigRat(1,2).

Should the BigRat ctor from string also accept numbers with decimal points? e.g. BigRat("3.14159")? We'll wait and see whether there is demand for this before implementing; note that GMP does not offer this capability.

Should the BigRat ctor from a string (or C string) also accept an optional ReduceFlag?

Main changes

2011