@Test
public void testMerge() throws CardinalityMergeException
{

    int numToMerge = 5;
    int bits = 16;
    int cardinality = 1000000;
    HyperLogLog[] hyperLogLogs = new HyperLogLog[numToMerge];
    HyperLogLog baseline = new HyperLogLog(bits);
    for (int i = 0; i < numToMerge; i++)
    {
        hyperLogLogs[i] = new HyperLogLog(bits);
        for (int j = 0; j < cardinality; j++)
        {
            double val = Math.random();
            hyperLogLogs[i].offer(val);
            baseline.offer(val);
        }
    }
    long expectedCardinality = numToMerge * cardinality;
    HyperLogLog hll = hyperLogLogs[0];
    hyperLogLogs = Arrays.asList(hyperLogLogs).subList(1, hyperLogLogs.length).toArray(new HyperLogLog[0]);
    long mergedEstimate = hll.merge(hyperLogLogs).cardinality();
    long baselineEstimate = baseline.cardinality();
    double se = expectedCardinality * (1.04 / Math.sqrt(Math.pow(2, bits)));
    System.out.println("Baseline estimate: " + baselineEstimate);
    System.out.println("Expect estimate: " + mergedEstimate + " is between " + (expectedCardinality - (3 * se)) + " and " + (expectedCardinality + (3 * se)));
    assertTrue(mergedEstimate >= expectedCardinality - (3 * se));
    assertTrue(mergedEstimate <= expectedCardinality + (3 * se));
    assertEquals(mergedEstimate, baselineEstimate);
}