Most of jAgg's Aggregators perform calculations on numeric values. These values are
generally represented as the Java built-in type `double`, which represents a
wide range of possible values. However, many numbers cannot be represented exactly,
due to the binary representation of floating-point numbers. Many numbers can only be
approximated, using the binary representation that is the closest possible value to the
number desired.

These approximations are usually insignificant, but they become problematic in a few ways. When an intermediate result is used to calculate the next result, usually in iterations involving a large set of figures, the error resulting from the approximations can become more signficant, i.e. floating-point errors are compounded. In addition, numerical instabilities in normally sound mathematical algorithms can render floating-point accuracy non-existent, such as when two nearly equal quantities are subtracted.

However, because jAgg supports arbitrarily large datasets to aggregate, these approximation errors can easily become significant. This can manifest itself in an answer that is "off" by a little bit. E.g. the answer should be 2.18, but the printed answer is 2.180000000000001.

Such errors can be minimized by using in-memory representations of numbers that have
a higher precision. Java has two levels of precision for floating-point numbers,
`float` and `double`, with `double` having more
precision, and thus a far smaller approximation error. Arbitrary-precision libraries
are available that can virtually eliminate these kinds of errors. However, they can
suffer from large peformance penalties, especially when a high degree of precision is
desired.

The solution that jAgg employs is to use "Double-Double" precision. A
`DoubleDouble` is an object that consists of two `double`
instance variables - one of "high" significance, and one of "low" significance.
Normally, one `double` contains 52 bits in its "signficand", plus the
implicit "one", yielding 53 bits of precision. In a `DoubleDouble`, the
"high" `double` represents the best `double` approximation to the
desired number. To improve precision, the "low" `double` represents an
adjustment to the total value of the "high" number, with 54 additional bits of
precision (52 bits of the significand, plus its implicit "one" and the sign bit is also
used here), yielding a total of 107 bits of precision. This greatly reduces, but does
not eliminate, the problem of binary approximation of real numbers. However, in testing,
this appears to be sufficient to yield highly accurate and precise `double`
results for aggregation tasks.

All `Aggregators` that use numeric calculations employ
`DoubleDoubles` behind the scenes to maintain a high level of precision and
to minimize floating-point errors in calculations. Also, numerically stable algorithms
are utilized wherever needed to maintain precision.

Additionally, some numeric `Aggregators` use other
`Aggregator` results to calculate their own results. Normally, the result
of a numeric `Aggregator` is a `double`, as a result of calling
`terminate`. For some Aggregators to use other Aggregators in their
calculations, they call `terminateDoubleDouble`, an internally used method
that provides intermediate results at `DoubleDouble` precision.

The `DoubleDouble` class supplies many operations that represent
mathematical operations on the represented value. Such operations can typically, but
not always, handle both a `double` and another `DoubleDouble`.
`DoubleDoubles` are not immutable; in fact, operations do not return
separate `DoubleDoubles` -- they modify their own object. However, two
constants are defined in the class which are immutable, `NaN` and
`ZERO`. (Any operations that would modify those constants' contents throw
`UnsupportedOperationExceptions`.)

Computational algorithms for `DoubleDouble` precision are based on
"Algorithms for Quad-Double Precision Floating Point Arithmetic" by Hida, Li, and
Bailey, 2000, Berkeley.

Here are the methods defined on the `DoubleDouble` class:

`DoubleDouble()`- Constructor with an initial value of zero.`DoubleDouble(double d)`- Constructor that takes a normal`double`.`DoubleDouble(double hi, double lo)`- Constructor that takes two`doubles`. If the two values "overlap" in precision, then they are normalized, so that the "low" value is no longer overlapping bits of precision with the "high" value, e.g. (1, 0.125) => (1.125, 0).`DoubleDouble(DoubleDouble dd)`- A copy constructor.`reset()`- Sets this`DoubleDouble`equal to zero.`doubleValue()`- Returns the "high"`double`, which by itself is the best`double`approximation to this`DoubleDouble's`value.`getLow()`- Returns the "low"`double`, which is the "correction" applied to the "high" double to arrive at the overall more precise`DoubleDouble`value.`isNaN()`- Returns whether this`DoubleDouble`represents`NaN`- not a number.`addToSelf(DoubleDouble dd)`- Add another`DoubleDouble`to this one, modifying this value.`addToSelf(double d)`- Add a`double`to this value, modifying this value.`subtractFromSelf(DoubleDouble dd)`- Subtract another`DoubleDouble`from this one, modifying this value.`subtractFromSelf(double d)`- Subtract a`double`from this value, modifying this value.`negateSelf()`- Negates this value. Both the "high" and "low" values are negated.`multiplySelfBy(DoubleDouble dd)`- Multiply this value by another`DoubleDouble`, modifying this value.`multiplySelfBy(double d)`- Multiply this value by a`double`, modifying this value.`squareSelf()`- Multiply this value by itself, modifying this value.`divideSelfBy(DoubleDouble dd)`- Divide this value by another`DoubleDouble`, modifying this value.`divideSelfBy(double d)`- Divide this value by a`double`, modifying this value.`sqrtSelf()`- Take the square root of this value, modifying this value.`powSelf(long exponent)`- Raise this value to an integer power, modifying this value.`nthRootSelf(long n)`- Take the*n*th root of this value, modifying this value.`compareTo(DoubleDouble other)`- Compare to another`DoubleDouble`, to determine less than, equal to, or greater than. (`DoubleDoubles`are`Comparable`to each other.)