This file contains a short description of what the goals of this project are,
building guidelines etc. This was born after discussions with John Peacock, who
provided helpfull feedback.

* Favour correctness over speed
* Make your code maintable, so avoid Copy&Paste.
* Optimize more for the average case than the worst, while trying to avoid 
  performance hits for the worst case.
  The average case is more for longer numbers than short, based on the
  assumption that if you wanted to add 1 and 2 _fast_ together, you wouldn't
  use BigInt nor Perl, now would you? ;)
* Make subclassing as easy and painless as possible. This means clean
  inheritance and overload section, no C&P code etc.
* Make mixing of classes work, like in:

	$x = Math::BigFloat->new(10);
	$y = Math::BigInt->new(2);
	$z = $x / $y;			# $z = Math::BigFloat = 5

  See also BUGS.

##############################################################################
 Some thoughts about using Bit::Vector as under-the-hood package for BigInt:

Bit::Vector (BV) provides fast calculation routines in C, but some (possible)
problems remain. (Note: The same "problems" apply to other math packages in C)

+ Representation:

First, it uses base2, instead of base10 for the internal representation: 

* This means things like 2**1024 are much faster to calculate (basically a one
  padded by many zeros) than with MBI's way.
* OTOH printing a number needs to convert it to decimal, and this takes some
  time (even with sophisticated algorithmns like FFT). Printing the largest
  known prime (until today) takes some _dozend seconds_ on a 800 Mhz machine
  using a FFT in c implementation. Note that it is trivial to calculate the
  number 2**$x, the base2-to-base10 conversation is costly. MBI currently
  has it the other way round, calculation is very slow, but printing easy.
  The same time-limit applies in constructing numbers, because they will
  likely be given in base10 (although input numbers tend to be small).
  The same limits also applies to rounding, since it works in decimal
  space.
* Especially with MBFs way to normalize the numbers after each op the time
  fpr each op becomes O(N*N) since normalization needs to know the number of
  trailing zeros, which you only know in decimal space. Oups. (for odd numbers
  this is determined in O(1), but for even numbers it is still O(N*N))

It remains to be seen wether the "wasted" time in new() and bstr() is
compensated for in the faster calculation routines or not. 

Note: The current implementation using arrays has the same trade-off against
the old core (v0.02 and lower) routines:

slower new() and bstr() compared to storing the number as string, but faster
internal calculation compared against the original v0.01 BigInt. When doing
benchmarks, even for small numbers the "wasted" time in new() and bstr() is
usually compensated for by the faster internal math, thus speeding up programs
on the average. F.i. factorial() is now about 2.6 times faster than with the
old code (of course it is still factor 30 away from a c-library like
SSLeay::BN).

One problem here is rounding. It works in decimal space. So whenever you round,
the number must be converted to decimal, which is very costly. Things like
A and P turned on by default will make it _very_ slow, and even slow for big
numbers. Think O(N*N) compared to O(N) and you know what I mean. In these cases
it can be better to use Calc instead of Pari, BitVect or GMP.

Another problem is MBF: It tries to find the smallest exponent, and for this
needs to look at the decimal digits to find trailing zeros. Currently it does
this after _every op_ and this is bad. Really bad. new() could be modified to
not do this (by looking at the decimal digits of the decimal input), and
we could stop reducing the numbers after each op. The only places we need it
then is for bsstr() and exponenT() and parts(). Hopefully this will fly.

+ Sign:

The complete sign-mangling is done by MBI. The underlying core math lib only
handles big unsigned integers, which simplifies many things greatly. But the
sign mangling is in Perl, thus slow and adding a constant time per op.

+ Auto-extend/size issues:

BV does not extend the operands automatically on overflow. So the core-lib
acting as a wrapper must do this. Luckily, BV returns overflow and carry
flags. Unfortunately, BV also expects it's arguments to have the same size,
which means a lot of padding and reducing again. This makes BV unnecc. slow,
as compared f.i. to Pari.

All the wrappers overhead makes it pretty slow for small numbers, even slower
than it is now with Calc. So the real performance boost will come only for
really long numbers like 2**654321. It remains to be seen were the tradeoff
will occur, f.i. when the numbers must get insanly big to pay off, it is better
to use the old way, but if it is faster for relatively small numbers like
1234567890123456789, that is the way to go.

##############################################################################

More to come later.

Please send me test-reports, your experiences with this and your ideas - I love
to hear about my work!

Tels <http://bloodgate.com/>
