manpagez: man pages & more
info ginac
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.6 Numbers

For storing numerical things, GiNaC uses Bruno Haible's library CLN. The classes therein serve as foundation classes for GiNaC. CLN stands for Class Library for Numbers or alternatively for Common Lisp Numbers. In order to find out more about CLN's internals, the reader is referred to the documentation of that library. See (cln)Introduction, for more information. Suffice to say that it is by itself build on top of another library, the GNU Multiple Precision library GMP, which is an extremely fast library for arbitrary long integers and rationals as well as arbitrary precision floating point numbers. It is very commonly used by several popular cryptographic applications. CLN extends GMP by several useful things: First, it introduces the complex number field over either reals (i.e. floating point numbers with arbitrary precision) or rationals. Second, it automatically converts rationals to integers if the denominator is unity and complex numbers to real numbers if the imaginary part vanishes and also correctly treats algebraic functions. Third it provides good implementations of state-of-the-art algorithms for all trigonometric and hyperbolic functions as well as for calculation of some useful constants.

The user can construct an object of class numeric in several ways. The following example shows the four most important constructors. It uses construction from C-integer, construction of fractions from two integers, construction from C-float and construction from a string:

 
#include <iostream>
#include <ginac/ginac.h>
using namespace GiNaC;

int main()
{
    numeric two = 2;                      // exact integer 2
    numeric r(2,3);                       // exact fraction 2/3
    numeric e(2.71828);                   // floating point number
    numeric p = "3.14159265358979323846"; // constructor from string
    // Trott's constant in scientific notation:
    numeric trott("1.0841015122311136151E-2");
    
    std::cout << two*p << std::endl;  // floating point 6.283...
    ...

The imaginary unit in GiNaC is a predefined numeric object with the name I:

 
    ...
    numeric z1 = 2-3*I;                    // exact complex number 2-3i
    numeric z2 = 5.9+1.6*I;                // complex floating point number
}

It may be tempting to construct fractions by writing numeric r(3/2). This would, however, call C's built-in operator / for integers first and result in a numeric holding a plain integer 1. Never use the operator / on integers unless you know exactly what you are doing! Use the constructor from two integers instead, as shown in the example above. Writing numeric(1)/2 may look funny but works also.

We have seen now the distinction between exact numbers and floating point numbers. Clearly, the user should never have to worry about dynamically created exact numbers, since their `exactness' always determines how they ought to be handled, i.e. how `long' they are. The situation is different for floating point numbers. Their accuracy is controlled by one global variable, called Digits. (For those readers who know about Maple: it behaves very much like Maple's Digits). All objects of class numeric that are constructed from then on will be stored with a precision matching that number of decimal digits:

 
#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;

void foo()
{
    numeric three(3.0), one(1.0);
    numeric x = one/three;

    cout << "in " << Digits << " digits:" << endl;
    cout << x << endl;
    cout << Pi.evalf() << endl;
}

int main()
{
    foo();
    Digits = 60;
    foo();
    return 0;
}

The above example prints the following output to screen:

 
in 17 digits:
0.33333333333333333334
3.1415926535897932385
in 60 digits:
0.33333333333333333333333333333333333333333333333333333333333333333334
3.1415926535897932384626433832795028841971693993751058209749445923078

Note that the last number is not necessarily rounded as you would naively expect it to be rounded in the decimal system. But note also, that in both cases you got a couple of extra digits. This is because numbers are internally stored by CLN as chunks of binary digits in order to match your machine's word size and to not waste precision. Thus, on architectures with different word size, the above output might even differ with regard to actually computed digits.

It should be clear that objects of class numeric should be used for constructing numbers or for doing arithmetic with them. The objects one deals with most of the time are the polymorphic expressions ex.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.