import java.util.*;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;

/**Static class for comparing performance of java.math.BigDecimal, 
 * be.arci.math.BigDecimal and com.ibm.math.BigDecimal
 * 
 *******************************************************************************
 * WARNING: RUNNING THIS PROGRAM CAN RAISE YOUR CPU'S TEMPERATURE CONSIDERABLY *
 *******************************************************************************
 */
public class Benchmark
{
 /*
  * Parameters for the benchmark
  */
 //benchmark machine
 static final String sMachine = "Win98 AMD K6-2 350MHz, 16MB heap memory";
 //number of different strings to test with
 static final int iSamples = 20;
 //minimal duration for operations call to get precise time measurements
 static final long lTargetMillis = 100000L;
 //starting string length to test with
 static final int iSTARTLEN = 32;
 //maximum string length to test with
 static final int iMAXLEN = 512;
 //pool of digits to get strings from
 static final String sE = numberE(2 + 2 * (iMAXLEN + iSamples), be.arci.math.BigDecimal.ONE);
 //MS JVM does not set a 'java.compiler' property
 static String sCompiler = " (" + System.getProperty("java.compiler", "msjvm") + ")";
 static String[] asRowHeader = 
 {
  "Iteration count", 
  "java.math.BigDecimal" + sCompiler, 
  "be.arci.math.BigDecimal" + sCompiler, 
  "com.ibm.math.BigDecimal" + sCompiler,
  "com.tce.math.TBigDecimal" + sCompiler,
  "java.math.BigInteger" + sCompiler, 
  "com.tce.math.BCD" + sCompiler,
 };
 static final long RNDSEED = 12351251251L;
 static final boolean SWJAV = true;
 static final boolean SWARC = true;
 static final boolean SWIBM = true;
 static final boolean SWTCE = true;
 static final int iPACKAGES = 4 + 1;
 
 /**Lengths in digits of the tested Strings */
 static int[] aiAvrgPrecision;
 /**Test exponented numbers  */
 static final boolean SWEXP = true;
 /**Exponent to test exponented numbers with  */
 static final int iTestExp =  1000;
 /**Exponent suffix string for creating exponented numbers from 
  * String for com.ibm.math and be.arci.math  */
 static final String sExpSuffix = "E+" + iTestExp;
 /**Zero-tail suffix string for creating exponented numbers from 
  * String for java.math (has no E9999 notation  */
 static final String sExpSurrogate;
 static 
 {
  if (SWEXP)
  {
   char[] ac = new char[iTestExp];
   for (int i = iTestExp; i-- > 0; )
    ac[i] = '0';
   sExpSurrogate = new String(ac);
  }
  else
   sExpSurrogate = "";
 }
 /**Test number 'e'  */
 static final boolean SWNME = true;
 /**Test BigDecimal from int  */
 static final boolean SWINT = true;
 /**Test BigDecimal from long  */
 static final boolean SWLNG = true;
 /**Test BigDecimal from double  */
 static final boolean SWDBL = true;
 /**Test from/ toBigDecimal()  */
 static final boolean SWBGD = true;
 static long[][] alBgd1 = new long[iPACKAGES - 1][];
 static long[][] alBgd2 = new long[iPACKAGES - 1][];
 /**Test BigDecimal from String  */
 static final boolean SWSTR = true;
 static long[][] alStr = new long[iPACKAGES][];
 /**Test add()   */
 static final boolean SWADD = true;
 static long[][] alAdd = new long[iPACKAGES][];
 /**Test subtract()   */
 static final boolean SWSUB = true;
 static long[][] alSub = new long[iPACKAGES][];
 /**Test multiply()  */
 static final boolean SWMUL = true;
 static long[][] alMul = new long[iPACKAGES][];
 /**Test divide()  */
 static final boolean SWDIV = true;
 static long[][] alDiv = new long[iPACKAGES][];
 /**Test pow()  */
 static final boolean SWPOW = true;
 static long[][] alPow = new long[iPACKAGES][];
 
 /**Test remainder()  */
 //static final boolean SWREM = true;
 //static long[][] alRem = new long[iPACKAGES][];
 /**Test divideInteger()  */
 //static final boolean SWDVI = true;
 //static long[][] alDvi = new long[iPACKAGES][];

 /**Test compareTo()  */
 static final boolean SWCMP = true;
 static long[][] alCmp = new long[iPACKAGES][];
 /**Test equals()  */
 static final boolean SWEQL = true;
 static long[][] alEql = new long[iPACKAGES][];

 /**Test plus()  */
 //static final boolean SWPLS = true;
 //static long[][] alPls = new long[iPACKAGES][];
 /**Test negate()  */
 //static final boolean SWNEG = true;
 //static long[][] alNeg = new long[iPACKAGES][];

 /**Test abs()  */
 static final boolean SWABS = true;
 static long[][] alAbs = new long[iPACKAGES][];
 /**Test max()  */
 static final boolean SWMAX = true;
 static long[][] alMax = new long[iPACKAGES][];
 /**Test min()  */
 //static final boolean SWMIN = true;
 //static long[][] alMin = new long[iPACKAGES][];

 /**Test movePointLeft() and movePointRight()  */
 //static final boolean SWMOV = true;
 //static long[][] alMov = new long[iPACKAGES][];
 /**Test setScale()  */
 static final boolean SWSCL = true;
 static long[][] alScl = new long[iPACKAGES][];

 /**Test toString()  */
 static final boolean SWTST = true;
 static long[][] alTst = new long[iPACKAGES][];
 /**Test unscaledValue()  */
 //static final boolean SWUNS = true;
 //static long[][] alUns = new long[iPACKAGES][];
 /**Test toBigDecimal()  */
 //static final boolean SWBGD = true;
 //static long[][] alBgd = new long[iPACKAGES][];
 /**Test format()  */
 //static final boolean SWFMT = true;
 //static long[][] alFmt = new long[iPACKAGES][];
 /**Test rounding through plus(FullDecimal, Usage)  */
 //static final boolean SWRND = true;
 //static long[][] alRnd = new long[iPACKAGES][];
 
 //common work fields
 static int iRepeat;
 static long lMillis, lTrigger;
 static long lEmptyLoopMillis;
 
  public static void main (String[] args)
 {
  int iRuns = 0;
  if (SWINT) iRuns++;
  if (SWLNG) iRuns++;
  //if (SWDBL) iRuns++;
  //we always need the Strings to construct from: if (SWSTR)
  {
   for (int iLength = iSTARTLEN; iLength <= iMAXLEN; iLength *= 2)
    iRuns++;
  }
  aiAvrgPrecision = new int[iRuns];
  for (int i = iPACKAGES; i-- > 0; )
  {
   if (SWSTR) alStr[i] = new long[iRuns];
   if (SWADD) alAdd[i] = new long[iRuns];
   if (SWSUB) alSub[i] = new long[iRuns];
   if (SWMUL) alMul[i] = new long[iRuns];
   if (SWDIV) alDiv[i] = new long[iRuns];
   if (SWPOW) alPow[i] = new long[iRuns];
   if (SWCMP) alCmp[i] = new long[iRuns];
   if (SWEQL) alEql[i] = new long[iRuns];
   if (SWABS) alAbs[i] = new long[iRuns];
   if (SWMAX) alMax[i] = new long[iRuns];
   if (SWSCL) alScl[i] = new long[iRuns];
   if (SWTST) alTst[i] = new long[iRuns];
   if (i < (iPACKAGES - 1) && SWBGD) alBgd1[i] = new long[iRuns];
   if (i < (iPACKAGES - 1) && SWBGD) alBgd2[i] = new long[iRuns];
  }       
  boolean swExp = SWEXP;
  do
  {
   //Create log for errors
   try {
    System.setOut(new PrintStream(new FileOutputStream("benchmark" + (swExp ? "exp" : "") + ".htm")));
   } catch (java.io.IOException e) {}
   System.out.println("<HTML><HEAD><TITLE>BigDecimal benchmark with" + (swExp ? " exponent " + iTestExp : "out exponent") + "</TITLE></HEAD><BODY>");
   System.out.println("<H1>Benchmark" + (swExp ? " E" + iTestExp : "") + "</H1><P>Benchmarks in nanoseconds (10<SUP>-9</SUP>s) per operation using " + 
                      System.getProperty("java.vendor") + "'s virtual machine version " + 
                      System.getProperty("java.version") + " on a " + sMachine + "<P><HR>");
   System.out.println("<TABLE BORDER = 1>");
   System.gc();
   try {
    int iRun = 0;
    if (SWINT)
     ints(iRun++, swExp);
    if (SWLNG)
     longs(iRun++, swExp);
    if (SWDBL)
     doubles(iRun /*++*/, swExp);
    //we always need the Strings to construct from and to count average precision: if (SWSTR)
    {
     String[] as = new String[iSamples];
     for (int iLength = iSTARTLEN; iLength <= iMAXLEN; iLength *= 2)
     {//take some substring out of the String representation of the number 'e', but give it a dot-decimal notation
      //and prefix them all with a different number to destroy all correlation
      for (int i = 0, j = iLength; i < iSamples; i++)
       as[i] = j + (swExp ? "" : ".") + sE.substring(2 + j, 2 + j + j++);//2 skips leading "2.", avoids 2 dot's
      strings(as, iRun, swExp);
/*      long lDuration = operations(as, 1, iRun, swExp);
      if (lTargetMillis > lDuration)
       operations(as, (int)(lTargetMillis / lDuration) + 1, iRun, swExp);*/
      operations(as, (swExp ? 1 : 1), iRun, swExp);
      iRun++;
     }
    }
   }
   catch (Throwable t) { t.printStackTrace(); }
   finally
   {
    if (SWSTR) printOut("new", "new BigDecimal(String)", alStr);
    if (SWTST) printOut("toString", "toString", alTst);
    if (SWADD) printOut("add", "add", alAdd);
    if (SWSUB) printOut("subtract", "subtract", alSub);
    if (SWMUL) printOut("multiply", "multiply", alMul);
    if (SWDIV) printOut("divide", "divide", alDiv);
    if (SWPOW) printOut("pow", "pow", alPow);
    if (SWCMP) printOut("compareTo", "compareTo", alCmp);
    if (SWEQL) printOut("equals", "equals", alEql);
    if (SWABS) printOut("abs", "abs", alAbs);
    if (SWMAX) printOut("max", "max", alMax);
    if (SWSCL) printOut("setScale", "setScale", alScl);
    if (SWBGD && !swExp) printOut("fromBigDecimal", "new BigDecimal(java.math.BigDecimal)", alBgd1);
    if (SWBGD && !swExp) printOut("toBigDecimal", "toBigDecimal", alBgd2);
   }
   try {
    System.gc();
    if (!swExp && SWNME)
    {//calculate the number e to different precisions; 1 loop per library to charge garbage creation to the right culprit
     System.err.print("number e ");
     final int iSAMPLES = 10;
     System.out.println("<TR><TH COLSPAN=4><A HREF=numbere.htm><IMG SRC=../img/chart4.gif ALIGN=LEFT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>number 'e' (microseconds)</TH></TR>");
     System.out.print("<TR><TH>Precision</TH>");
     for (int iPrecision = 8, iSamples = iSAMPLES; iSamples-- > 0; iPrecision *= 2)
      System.out.print("<TD>" + iPrecision + "</TD>");
     {
      System.out.println("</TR>\r\n<TR><TH>" + asRowHeader[0] + "</TH>");
      for (int iRepeat = 256, iSamples = iSAMPLES; iSamples-- > 0; iRepeat /= 2)
      {
       if (iRepeat == 0)
        iRepeat = 1;
       System.out.println("<TD>" + iRepeat + "</TD>");
      }
      System.gc();
     }
     if (SWJAV)
     {
      System.out.println("</TR>\r\n<TR><TH>" + asRowHeader[1] + "</TH>");
      java.math.BigDecimal bdOne = new java.math.BigDecimal("1");
      for (int iPrecision = 8, iRepeat = 256, iSamples = iSAMPLES; iSamples-- > 0; iPrecision *= 2, iRepeat /= 2)
      {
       if (iRepeat == 0)
        iRepeat = 1;
       lTrigger = System.currentTimeMillis();
       while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
       for (int i = iRepeat; i-- > 0; )
        numberE(iPrecision, bdOne);
       lMillis = System.currentTimeMillis() - lMillis;
       System.err.print(iRepeat + " x " + iPrecision + " : " + lMillis + ", ");
       System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
      }
      System.gc();
     }
     if (SWARC)
     {
      System.out.println("</TR>\r\n<TR><TH>" + asRowHeader[2] + "</TH>");
      be.arci.math.BigDecimal bdOne = be.arci.math.BigDecimal.ONE;
      for (int iPrecision = 8, iRepeat = 256, iSamples = iSAMPLES; iSamples-- > 0; iPrecision *= 2, iRepeat /= 2)
      {
       if (iRepeat == 0)
        iRepeat = 1;
       lTrigger = System.currentTimeMillis();
       while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
       for (int i = iRepeat; i-- > 0; )
        numberE(iPrecision, bdOne);
       lMillis = System.currentTimeMillis() - lMillis;
       System.err.print(iRepeat + " x " + iPrecision + " : " + lMillis + ", ");
       System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
      }
      System.gc();
     }
     if (SWIBM)
     {
      System.out.println("</TR>\r\n<TR><TH>" + asRowHeader[3] + "</TH>");
      com.ibm.math.BigDecimal bdOne = com.ibm.math.BigDecimal.ONE;
      for (int iPrecision = 8, iRepeat = 256, iSamples = iSAMPLES; iSamples-- > 0; iPrecision *= 2, iRepeat /= 2)
      {
       if (iRepeat == 0)
        iRepeat = 1;
       lTrigger = System.currentTimeMillis();
       while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
       for (int i = iRepeat; i-- > 0; )
        numberE(iPrecision, bdOne);
       lMillis = System.currentTimeMillis() - lMillis;
       System.err.print(iRepeat + " x " + iPrecision + " : " + lMillis + ", ");
       System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
      }
      System.gc();
     }
     if (SWTCE)
     {
      System.out.println("</TR>\r\n<TR><TH>" + asRowHeader[4] + "</TH>");
      com.tce.math.TBigDecimal bdOne = com.tce.math.TBigDecimal.ONE;
      for (int iPrecision = 8, iRepeat = 256, iSamples = iSAMPLES; iSamples-- > 0; iPrecision *= 2, iRepeat /= 2)
      {
       if (iRepeat == 0)
        iRepeat = 1;
       lTrigger = System.currentTimeMillis();
       while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
       for (int i = iRepeat; i-- > 0; )
        numberE(iPrecision, bdOne);
       lMillis = System.currentTimeMillis() - lMillis;
       System.err.print(iRepeat + " x " + iPrecision + " : " + lMillis + ", ");
       System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
      }
      System.gc();
     }
     System.out.println("</TR>");
    }
   }
   catch (Throwable t) { t.printStackTrace(); }
   finally
   {
    System.out.println("</TABLE><P>");
    System.out.println("</BODY></HTML>");
   }
   swExp = !swExp;
  } while (!swExp);
 }
 /**Prints a set of timings into the html output  */
 static void printOut(String sOperation, String sTitle, long[][] alMillis)
 {
  System.out.println("<TR><TH COLSPAN=4><A HREF=" + sOperation + ".htm><IMG SRC=../img/chart4.gif ALIGN=LEFT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + sTitle + "</TH></TR>");
  System.out.print("<TR><TH>Avg. Precision</TH>");
  for (int i = 0; i < aiAvrgPrecision.length; i++)
   System.out.print("<TD>" + aiAvrgPrecision[i] + "</TD>");
  System.out.println("</TR>");
  for (int j = 0; j < alMillis.length; j++)
  {
   if (alMillis.length == (iPACKAGES - 1)) //method not in java.math.BigDecimal
    System.out.print("<TR><TH>" + asRowHeader[(j == 0 ? j : j + 1)] + "</TH>");
   else
    System.out.print("<TR><TH>" + asRowHeader[(sOperation.startsWith("pow") ? 
                                               (j == 1 ? 
                                                iPACKAGES - 2 : 
                                                (j == 4 ? 
                                                 iPACKAGES - 1 : 
                                                 j)) : 
                                               j)] + "</TH>");
   for (int i = 0; i < aiAvrgPrecision.length; i++)
    System.out.print("<TD>" + (long)(alMillis[j][i] * (j == 0 ? 1 : (1000000.d / alMillis[0][i]))) + "</TD>");
   System.out.println("</TR>");
  }
 }
 /**Creates a series of BigDecimal for int values with 7-10 digits
  * and performs a series of performancetests on them  */
 static void ints(int iRun, boolean swExp)
 {
  Random random = new Random();
  if (!swExp)
  {
   iRepeat = 200000;
   System.err.print("ints ");
  
   random.setSeed(RNDSEED);//always reproduce the same results
   lTrigger = System.currentTimeMillis();
   while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
   for (int k = iRepeat; k-- > 0; )
   {//EMPTY LOOP
    double d = random.nextDouble() - 0.5;
    int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
   }
   lEmptyLoopMillis = System.currentTimeMillis() - lMillis;
   System.out.println("\r\n<TR><TH COLSPAN=2><A HREF=valueOf.htm><IMG SRC=../img/chart4.gif ALIGN=LEFT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "valueOf(int)</TH>" + 
                      "<TH COLSPAN=4><A HREF=intValue.htm><IMG SRC=../img/chart4.gif ALIGN=RIGHT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "intValue()</TH></TR>" + 
                      "<TR><TH>" + asRowHeader[0] + "</TH><TD>" + iRepeat + "</TD><TD>" + (iRepeat * 100) + "</TD></TR>");
   System.gc();

   if (SWJAV)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     java.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.print("\r\n<TH>" + asRowHeader[1] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let java.math do intValue 100 times to get enough tiketiks
    java.math.BigDecimal[] abdJ = new java.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     abdJ[k] = java.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = 100 * 100; i-- > 0; )
      abdJ[k].intValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((100 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdJ[k] = null; //make garbage collection as easy as possible
    abdJ = null;
    System.gc();
   }
  
   if (SWARC)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     be.arci.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.print("\r\n<TH>" + asRowHeader[2] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let be.arci.math do intValue 100 times to get enough tiketiks
    be.arci.math.BigDecimal[] abdA = new be.arci.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     abdA[k] = be.arci.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = 100 * 100; i-- > 0; )
      abdA[k].intValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((100 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdA[k] = null; //make garbage collection as easy as possible
    abdA = null;
    System.gc();
   }
  
   if (SWIBM)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     com.ibm.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.print("\r\n<TH>" + asRowHeader[3] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let com.ibm.math do intValue 10 times only, takes enough tiketiks already
    com.ibm.math.BigDecimal[] abdI = new com.ibm.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     abdI[k] = com.ibm.math.BigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = 100 * 10; i-- > 0; )
      abdI[k].intValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((10 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdI[k] = null; //make garbage collection as easy as possible
    abdI = null;
    System.gc();
   }
  
   if (SWTCE)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     com.tce.math.TBigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.print("\r\n<TH>" + asRowHeader[4] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let com.ibm.math do intValue 10 times only, takes enough tiketiks already
    com.tce.math.TBigDecimal[] abdT = new com.tce.math.TBigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     double d = random.nextDouble() - 0.5;
     int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
     abdT[k] = com.tce.math.TBigDecimal.valueOf(d > 0 ? +iValue : -iValue);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = 100 * 10; i-- > 0; )
      abdT[k].intValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((10 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdT[k] = null; //make garbage collection as easy as possible
    abdT = null;
    System.gc();
   }
  }
  
  String[] as = new String[iSamples];
  random.setSeed(RNDSEED);//always reproduce the same results
  for (int k = iSamples; k-- > 0; )
  {//quite unprejudiced range of samples
   double d = random.nextDouble() - 0.5;
   int iValue = (int)(Integer.MAX_VALUE / 100 + (Integer.MAX_VALUE / 500) * (100 * d));
   as[k] = String.valueOf(d > 0 ? +iValue : -iValue);
  }
  strings(as, iRun, swExp);
/*  long lDuration = operations(as, 1, iRun, swExp);
  if (lTargetMillis > lDuration)
   operations(as, (int)(lTargetMillis / lDuration) + 1, iRun, swExp);*/
  operations(as, (swExp ? 1 : 6), iRun, swExp);
 }

 static void longs(int iRun, boolean swExp)
 {//to get 'the real long feeling', we try to produce longs with 15-20 digits
  Random random = new Random();
  if (!swExp)
  {
   iRepeat = 200000;
   System.err.print("longs ");

   random.setSeed(RNDSEED);//always reproduce the same results
   lTrigger = System.currentTimeMillis();
   while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
   for (int k = iRepeat; k-- > 0; )
   {//EMPTY LOOP
    double d = random.nextDouble() - 0.5;
    long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
   }
   lEmptyLoopMillis = System.currentTimeMillis() - lMillis;
   System.out.println("\r\n<TR><TH COLSPAN=2><A HREF=valueOf.htm><IMG SRC=../img/chart4.gif ALIGN=LEFT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "valueOf(long)</TH>" + 
                      "<TH COLSPAN=4><A HREF=intValue.htm><IMG SRC=../img/chart4.gif ALIGN=RIGHT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "longValue()</TH></TR>" + 
                      "<TR><TH>" + asRowHeader[0] + "</TH><TD>" + iRepeat + "</TD><TD>" + (iRepeat * 100) + "</TD></TR>");
   System.gc();
    
 
   if (SWJAV)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     java.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[1] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let java.math do longValue 100 times to get enough tiketiks
    java.math.BigDecimal[] abdJ = new java.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     abdJ[k] = java.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = 100 * 100; i-- > 0; )
      abdJ[k].longValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((100 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdJ[k] = null; //make garbage collection as easy as possible
    abdJ = null;
    System.gc();
   }
  
   if (SWARC)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     be.arci.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[2] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let be.arci.math do longValue 100 times to get enough tiketiks
    be.arci.math.BigDecimal[] abdA = new be.arci.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     abdA[k] = be.arci.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = 100 * 100; i-- > 0; )
      abdA[k].longValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((100 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdA[k] = null; //make garbage collection as easy as possible
    abdA = null;
    System.gc();
   }
  
   if (SWIBM)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     com.ibm.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[3] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let com.ibm.math do longValue 10 times only, takes enough tiketiks already
    com.ibm.math.BigDecimal[] abdI = new com.ibm.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     abdI[k] = com.ibm.math.BigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = 100 * 10; i-- > 0; )
      abdI[k].longValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((10 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdI[k] = null; //make garbage collection as easy as possible
    abdI = null;
    System.gc();
   }
  
   if (SWTCE)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     com.tce.math.TBigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[4] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
    //let com.ibm.math do longValue 10 times only, takes enough tiketiks already
    com.tce.math.TBigDecimal[] abdT = new com.tce.math.TBigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     double d = random.nextDouble() - 0.5;
     long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
     abdT[k] = com.tce.math.TBigDecimal.valueOf(d > 0 ? +l : -l);
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = 100 * 10; i-- > 0; )
      abdT[k].longValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / ((10 * iRepeat) / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdT[k] = null; //make garbage collection as easy as possible
    abdT = null;
    System.gc();
   }
  }

  String[] as = new String[iSamples];
  random.setSeed(RNDSEED);//always reproduce the same results
  for (int k = iSamples; k-- > 0; )
  {//quite unprejudiced range of samples
   double d = random.nextDouble() - 0.5;
   long l = (long)(Long.MAX_VALUE / 100 + (Long.MAX_VALUE / 500) * (100 * d));
   as[k] = String.valueOf(d > 0 ? +l : -l);
  }
  strings(as, iRun, swExp);
/*  long lDuration = operations(as, 1, iRun, swExp);
  if (lTargetMillis > lDuration)
   operations(as, (int)(lTargetMillis / lDuration) + 1, iRun, swExp);*/
  operations(as, (swExp ? 1 : 4), iRun, swExp);
 }

 static void doubles(int iRun, boolean swExp)
 {//we try not to put too much stress on large exponents, which are difficult to handle for java.math.BigDecimal
  //which has no real decimal doubleing point
  //for (double d = Double.MAX_VALUE; d > 7*Double.MIN_VALUE; d -= d/7)
  Random random = new Random();
  if (!swExp)
  {
   iRepeat = 10000;
   System.err.print("doubles ");
    
   random.setSeed(RNDSEED);//always reproduce the same results
   lTrigger = System.currentTimeMillis();
   while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
   for (int k = iRepeat; k-- > 0; )
   {//EMPTY LOOP
    double d = (iRepeat + k) * random.nextDouble() / random.nextDouble();
   }
   lEmptyLoopMillis = System.currentTimeMillis() - lMillis;
   System.out.println("\r\n<TR><TH COLSPAN=2><A HREF=valueOf.htm><IMG SRC=../img/chart4.gif ALIGN=LEFT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "new BigDecimal(double)</TH>" + 
                      "<TH COLSPAN=4><A HREF=intValue.htm><IMG SRC=../img/chart4.gif ALIGN=RIGHT WIDTH=32 HEIGHT=32 ALT=\"view chart\"></A>" + 
                      "doubleValue()</TH></TR>" + 
                      "<TR><TH>" + asRowHeader[0] + "</TH><TD>" + iRepeat + "</TD><TD>" + iRepeat + "</TD></TR>");
   System.gc();
  
   if (SWJAV)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     new java.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[1] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
     
    java.math.BigDecimal[] abdJ = new java.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     abdJ[k] = new java.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = 100; i-- > 0; )
      abdJ[k].doubleValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdJ[k] = null; //make garbage collection as easy as possible
    abdJ = null;
    System.gc();
   }
  
   if (SWARC)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     new be.arci.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[2] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
     
    be.arci.math.BigDecimal[] abdA = new be.arci.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     abdA[k] = new be.arci.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = 100; i-- > 0; )
      abdA[k].doubleValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdA[k] = null; //make garbage collection as easy as possible
    abdA = null;
    System.gc();
   }
  
   if (SWIBM)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     new com.ibm.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[3] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
  
    com.ibm.math.BigDecimal[] abdI = new com.ibm.math.BigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     abdI[k] = new com.ibm.math.BigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = 100; i-- > 0; )
      abdI[k].doubleValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdI[k] = null; //make garbage collection as easy as possible
    abdI = null;
    System.gc();
   }
  
   if (SWTCE)
   {
    random.setSeed(RNDSEED);//always reproduce the same results
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     new com.tce.math.TBigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    System.out.println("\r\n<TH>" + asRowHeader[4] + "</TH><TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD>");
    System.gc();
  
    com.tce.math.TBigDecimal[] abdT = new com.tce.math.TBigDecimal[iRepeat / 100];
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     abdT[k] = new com.tce.math.TBigDecimal((iRepeat + k) * random.nextDouble() / random.nextDouble());
    }
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat / 100; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = 100; i-- > 0; )
      abdT[k].doubleValue();
    }
    lMillis = System.currentTimeMillis() - lMillis;// - lEmptyLoopMillis;
    System.out.println("<TD>" + (long)(lMillis / (iRepeat / 1000000.d)) + "</TD></TR>");
    for (int k = iRepeat / 100; k-- > 0; ) 
     abdT[k] = null; //make garbage collection as easy as possible
    abdT = null;
    System.gc();
   }
  }
 
  //java.math.BigDecimal cannot handle exponent (like 1.235E22) in String
  /*
  String[] as = new String[iSamples];
  random.setSeed(RNDSEED);//always reproduce the same results
  for (int k = iSamples; k-- > 0; )
  {//quite unprejudiced range of samples
   double d = (iSamples + k) * random.nextDouble() / random.nextDouble();
   as[k] = Double.toString(d);
  }
  strings(as, iRun, swExp);
  long lDuration = operations(as, 1, -1, swExp);
  if (lTargetMillis > lDuration)
   operations(as, (int)(lTargetMillis / lDuration) + 1, iRun, swExp);
  */
 }

 static void strings(String[] as, int iRun, boolean swExp)
 {
  int iSamples = as.length;
  //fill average precision 
  int iTotalPrecision = 0;
  for (int i = iSamples; i-- > 0; )
   iTotalPrecision += (new be.arci.math.BigDecimal(as[i])).getDigits();
  iTotalPrecision = (iTotalPrecision + iSamples / 2 ) / iSamples;
  aiAvrgPrecision[iRun] = iTotalPrecision;

  if (SWSTR)
  {
   iRepeat = 1000000 / (int)java.lang.Math.sqrt(iTotalPrecision) / iSamples;
   emptyLoop(iRepeat, iSamples, 1, "Strings(" + iTotalPrecision + ")");
   alStr[0][iRun] = iRepeat * iSamples * 1;
  
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
     {
      if (swExp)
       new java.math.BigDecimal(as[i] + sExpSurrogate);
      else
       new java.math.BigDecimal(as[i]);
     }
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alStr[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
     {
      if (swExp)
       new be.arci.math.BigDecimal(as[i] + sExpSuffix);
      else
       new be.arci.math.BigDecimal(as[i]);
     }
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alStr[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
     {
      if (swExp)
       new com.ibm.math.BigDecimal(as[i] + sExpSuffix);
      else
       new com.ibm.math.BigDecimal(as[i]);
     }
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alStr[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
     {
      if (swExp)
       new com.tce.math.TBigDecimal(as[i] + sExpSurrogate);
      else
       new com.tce.math.TBigDecimal(as[i]);
     }
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alStr[4][iRun] = lMillis;
    System.gc();
   }
  }
 }
 /**Performance measurements of the different operations  */
 static long operations(String[] as, int iBaseRepeat, int iRun, boolean swExp)
 {
  boolean swLog = (iRun >= 0);
  System.err.println("Baserepeat " + iBaseRepeat);
  int iSamples = as.length;
  java.math.BigDecimal[] abdJ = new java.math.BigDecimal[iSamples];
  be.arci.math.BigDecimal[] abdA = new be.arci.math.BigDecimal[iSamples];
  com.ibm.math.BigDecimal[] abdI = new com.ibm.math.BigDecimal[iSamples];
  com.tce.math.TBigDecimal[] abdT = new com.tce.math.TBigDecimal[iSamples];
  for (int i = iSamples; i-- > 0; )
  {
   abdJ[i] = new java.math.BigDecimal(as[i] + (swExp ? sExpSurrogate : ""));
   abdA[i] = new be.arci.math.BigDecimal(as[i] + (swExp ? sExpSuffix : ""));
   abdI[i] = new com.ibm.math.BigDecimal(as[i] + (swExp ? sExpSuffix : ""));
   abdT[i] = new com.tce.math.TBigDecimal(as[i] + (swExp ? sExpSurrogate : ""));
  }
  //for some operations we need java.math.BigInteger
  BigInteger[] abiJ = new BigInteger[iSamples];
  for (int i = iSamples; i-- > 0; )
  {
   int iScale = abdJ[i].scale();
   java.math.BigDecimal bdUnscaledValue = (iScale > 0 ? abdJ[i].movePointRight(iScale) : abdJ[i]);
   abiJ[i] = bdUnscaledValue.toBigInteger();
  }
  
  java.math.BigDecimal bdJ;
  be.arci.math.BigDecimal bdA;
  com.ibm.math.BigDecimal bdI; 
  com.tce.math.TBigDecimal bdT; 
  long lTestStart;
  lTrigger = System.currentTimeMillis();
  while (lTrigger == (lTestStart = System.currentTimeMillis())) {}
  
  //BINARY OPERATIONS
  if (SWADD)
  {
   iRepeat = 100 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, iSamples, "add");
   alAdd[0][iRun] = iRepeat * iSamples * iSamples;
   
  
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].add(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAdd[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].add(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAdd[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].add(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAdd[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].add(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAdd[4][iRun] = lMillis;
    System.gc();
   }
  }  
  if (SWSUB)
  {
   iRepeat = 100 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, iSamples, "subtract");
   alSub[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].subtract(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alSub[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].subtract(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alSub[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].subtract(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alSub[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].subtract(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alSub[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWMUL)
  {
   iRepeat = 80 * iBaseRepeat / (aiAvrgPrecision[iRun] < 100 ? 1 : aiAvrgPrecision[iRun] / 100);
   emptyLoop(iRepeat, iSamples, iSamples, "multiply");
   alMul[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].multiply(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMul[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].multiply(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMul[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].multiply(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMul[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].multiply(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMul[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWDIV)
  {
   iRepeat = 25 * iBaseRepeat / (aiAvrgPrecision[iRun] < 100 ? 1 : aiAvrgPrecision[iRun] / 100);
   emptyLoop(iRepeat, iSamples, iSamples, "divide");
   alDiv[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].divide(abdJ[j], java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alDiv[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].divide(abdA[j], java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alDiv[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].divide(abdI[j], java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alDiv[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].divide(abdT[j], java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alDiv[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWCMP)
  {
   iRepeat = 1000 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, iSamples, "compareTo");
   alCmp[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].compareTo(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alCmp[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].compareTo(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alCmp[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].compareTo(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alCmp[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].compareTo(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alCmp[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWMAX)
  {
   iRepeat = 1000 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, iSamples, "max");
   alMax[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].max(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMax[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].max(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMax[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].max(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMax[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].max(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alMax[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWEQL)
  {
   iRepeat = 2000 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, iSamples, "equals");
   alEql[0][iRun] = iRepeat * iSamples * iSamples;
   
   if (SWJAV)
   {
    //let java.math do it (aiAvrgPrecision[iRun]/5) times as much, question of time.   
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat * (aiAvrgPrecision[iRun]/5); k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdJ[i].equals(abdJ[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alEql[1][iRun] = lMillis / (aiAvrgPrecision[iRun]/5);
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdA[i].equals(abdA[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alEql[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdI[i].equals(abdI[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alEql[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {//let tce do it more often, to get enough timetiks
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat * (aiAvrgPrecision[iRun]/5); k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      for (int j = iSamples; j-- > 0; )
       abdT[i].equals(abdT[j]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alEql[4][iRun] = lMillis / (aiAvrgPrecision[iRun]/5);
    System.gc();
   }
  }
  //UNARY OPERATIONS
  iBaseRepeat *= iSamples;
  
  if (SWPOW)
  {
   iRepeat = 10 * iBaseRepeat / (aiAvrgPrecision[iRun] <= 50 ? 1 : aiAvrgPrecision[iRun] * aiAvrgPrecision[iRun] / 50 / 50);
   if (iRepeat == 0) iRepeat = 1;
   int iPowSamples = (aiAvrgPrecision[iRun] > 200 ? iSamples / 2 : iSamples);
   emptyLoop(iRepeat, iPowSamples, 1, "pow");
   alPow[0][iRun] = iRepeat * iPowSamples * 1;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iPowSamples; i-- > 0; )
      abiJ[i].pow(10);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alPow[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iPowSamples; i-- > 0; )
      abdA[i].pow(10);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alPow[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iPowSamples; i-- > 0; )
      abdI[i].pow(com.ibm.math.BigDecimal.TEN);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alPow[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iPowSamples; i-- > 0; )
      abdT[i].unscaledValue().pow(10);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alPow[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWABS)
  {
   iRepeat = 2000 * iBaseRepeat * (aiAvrgPrecision[iRun]/5);
   emptyLoop(iRepeat, iSamples, 1, "abs");
   alAbs[0][iRun] = iRepeat * iSamples * 1;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdJ[i].abs();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAbs[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdA[i].abs();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAbs[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdI[i].abs();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAbs[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      abdT[i].abs();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alAbs[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWTST)
  {
   iRepeat = 80 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, 1, "toString");
   alTst[0][iRun] = iRepeat * iSamples * 1;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdJ[i].toString();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alTst[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdA[i].toString();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alTst[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdI[i].toString();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alTst[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      abdT[i].toString();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alTst[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWSCL)
  {
   iRepeat = 100 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, 1, "setScale");
   alScl[0][iRun] = iRepeat * iSamples * 1;
   
   if (SWJAV)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//java.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdJ[i].setScale((abdJ[i].scale() > 0 ? abdJ[i].scale()/2 : 3), java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alScl[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdA[i].setScale((abdA[i].scale() > 0 ? abdA[i].scale()/2 : 3), java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alScl[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdI[i].setScale((abdI[i].scale() > 0 ? abdI[i].scale()/2 : 3), java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alScl[3][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      abdT[i].setScale((abdT[i].scale() > 0 ? abdT[i].scale()/2 : 3), java.math.BigDecimal.ROUND_HALF_UP);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alScl[4][iRun] = lMillis;
    System.gc();
   }
  }
  if (SWBGD && !swExp)//exponents would say more about java.math.BigDecimal than about the compared packages;
  {                   //also they would take long enough to construct a java.math.BigDecimal for to want to exclude them
   iRepeat = 80 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, 1, "new(BigDecimal)");
   alBgd1[0][iRun] = iRepeat * iSamples * 1;
   
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdA[i] = new be.arci.math.BigDecimal(abdJ[i]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd1[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdI[i] = new com.ibm.math.BigDecimal(abdJ[i]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd1[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      abdT[i] = new com.tce.math.TBigDecimal(abdJ[i]);
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd1[3][iRun] = lMillis;
    System.gc();
   }

   iRepeat = 200 * iBaseRepeat;
   emptyLoop(iRepeat, iSamples, 1, "toBigDecimal");
   alBgd2[0][iRun] = iRepeat * iSamples * 1;
   
   if (SWARC)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//be.arci.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdA[i].toBigDecimal();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd2[1][iRun] = lMillis;
    System.gc();
   }
  
   if (SWIBM)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.ibm.math.BigDecimal
     for (int i = iSamples; i-- > 0; )
      abdI[i].toBigDecimal();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd2[2][iRun] = lMillis;
    System.gc();
   }
  
   if (SWTCE)
   {
    lTrigger = System.currentTimeMillis();
    while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
    for (int k = iRepeat; k-- > 0; )
    {//com.tce.math.TBigDecimal
     for (int i = iSamples; i-- > 0; )
      abdT[i].toBigDecimal();
    }
    lMillis = System.currentTimeMillis() - lMillis - lEmptyLoopMillis;
    alBgd2[3][iRun] = lMillis;
    System.gc();
   }
  }

  return System.currentTimeMillis() - lTestStart;
 }
 /**Opens a new table row and sets the timing baseline  */
 static void emptyLoop(int iRepeat, int iSamples1, int iSamples2, String sOperation)
 {
  System.err.print(sOperation + " ");
  lTrigger = System.currentTimeMillis();
  while (lTrigger == (lMillis = System.currentTimeMillis())) {} //start at millisecond change
  for (int k = iRepeat; k-- > 0; )
  {//EMPTY LOOP
   for (int i = iSamples1; i-- > 0; )
    for (int j = iSamples2; j-- > 0; )
    {}
  }
  lEmptyLoopMillis = System.currentTimeMillis() - lMillis;
  System.gc();
 }
 /**Calculates the number 'e' with the requested precision  
  * @param iPrecision the requested precision
  * @param bdOne BigDecimal '1', used for differentating signatures too. */
 static String numberE(int iPrecision, java.math.BigDecimal bdOne)
 {
  java.math.BigDecimal curfact = bdOne;
  java.math.BigDecimal factmul = bdOne;
  java.math.BigDecimal curval = new java.math.BigDecimal("0");
  String sE = "";
  
  for (int iIteration = 0; true; iIteration++)
  {
   //System.out.print("Iteration " + iIteration + "\r");
   // divide 1 by the current factorial
   java.math.BigDecimal bdTerm = bdOne.divide(curfact, iPrecision + 1, java.math.BigDecimal.ROUND_HALF_EVEN);
   // add the result to the accumulated value
   curval = curval.add(bdTerm); 
   // check convergence of the current value
   String s = curval.toString().substring(0, iPrecision + 2);
   if (s.equals(sE)) 
   {
    //System.out.println("");
    //System.out.println(s);
    break;
   }
   sE = s;
   // move to the next factorial value
   curfact = curfact.multiply(factmul);
   factmul = factmul.add(bdOne);
  }
  return sE;
 } 

 /**Calculates the number 'e' with the requested precision  
  * @param iPrecision the requested precision
  * @param bdOne BigDecimal '1', used for differentating signatures too. */
 static String numberE(int iPrecision, be.arci.math.BigDecimal bdOne)
 {
  be.arci.math.BigDecimal curfact = bdOne;
  be.arci.math.BigDecimal factmul = bdOne;
  be.arci.math.BigDecimal curval = be.arci.math.BigDecimal.ZERO;
  String sE = "";
  
  for (int iIteration = 0; true; iIteration++)
  {
   //System.out.print("Iteration " + iIteration + "\r");
   // divide 1 by the current factorial
   be.arci.math.BigDecimal bdTerm = bdOne.divide(curfact, iPrecision + 1, be.arci.math.BigDecimal.ROUND_HALF_EVEN);
   // add the result to the accumulated value
   curval = curval.add(bdTerm); 
   // check convergence of the current value
   String s = curval.toString().substring(0, iPrecision + 2);
   if (s.equals(sE)) 
   {
    //System.out.println("");
    //System.out.println(s);
    break;
   }
   sE = s;
   // move to the next factorial value
   curfact = curfact.multiply(factmul);
   factmul = factmul.add(bdOne);
  }
  return sE;
 } 

 /**Calculates the number 'e' with the requested precision  
  * @param iPrecision the requested precision
  * @param bdOne BigDecimal '1', used for differentating signatures too. */
 static String numberE(int iPrecision, com.ibm.math.BigDecimal bdOne)
 {
  com.ibm.math.BigDecimal curfact = bdOne;
  com.ibm.math.BigDecimal factmul = bdOne;
  com.ibm.math.BigDecimal curval = com.ibm.math.BigDecimal.ZERO;
  String sE = "";
  
  for (int iIteration = 0; true; iIteration++)
  {
   //System.out.print("Iteration " + iIteration + "\r");
   // divide 1 by the current factorial
   com.ibm.math.BigDecimal bdTerm = bdOne.divide(curfact, iPrecision + 1, com.ibm.math.BigDecimal.ROUND_HALF_EVEN);
   // add the result to the accumulated value
   curval = curval.add(bdTerm); 
   // check convergence of the current value
   String s = curval.toString().substring(0, iPrecision + 2);
   if (s.equals(sE)) 
   {
    //System.out.println("");
    //System.out.println(s);
    break;
   }
   sE = s;
   // move to the next factorial value
   curfact = curfact.multiply(factmul);
   factmul = factmul.add(bdOne);
  }
  return sE;
 } 

 /**Calculates the number 'e' with the requested precision  
  * @param iPrecision the requested precision
  * @param bdOne BigDecimal '1', used for differentating signatures too. */
 static String numberE(int iPrecision, com.tce.math.TBigDecimal bdOne)
 {
  com.tce.math.TBigDecimal curfact = bdOne;
  com.tce.math.TBigDecimal factmul = bdOne;
  com.tce.math.TBigDecimal curval = com.tce.math.TBigDecimal.ZERO;
  String sE = "";
  
  for (int iIteration = 0; true; iIteration++)
  {
   //System.out.print("Iteration " + iIteration + "\r");
   // divide 1 by the current factorial
   com.tce.math.TBigDecimal bdTerm = bdOne.divide(curfact, iPrecision + 1, com.tce.math.TBigDecimal.ROUND_HALF_EVEN);
   // add the result to the accumulated value
   curval = curval.add(bdTerm); 
   // check convergence of the current value
   String s = curval.toString().substring(0, iPrecision + 2);
   if (s.equals(sE)) 
   {
    //System.out.println("");
    //System.out.println(s);
    break;
   }
   sE = s;
   // move to the next factorial value
   curfact = curfact.multiply(factmul);
   factmul = factmul.add(bdOne);
  }
  return sE;
 } 

}

 

