@Test
  public void testRandomSetFromDouble() {
    Random r = new Random(14434);
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      doTestRandomSetFromDouble(r, standardAlphabet, bigDecimalFlavor);
    }
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      for (String sparseAlphabet : sparseAlphabets) {
        doTestRandomSetFromDouble(r, sparseAlphabet, bigDecimalFlavor);
      }
    }
  }
*******************************************************************************************

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "1");
    Assert.assertEquals(0, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(2);
    Assert.assertEquals(
        "100", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "1");
    Assert.assertEquals(0, dec.scale());
    // resultDec = dec.scaleByPowerOfTen(2);
    // Assert.assertEquals(
    //     "100", resultDec.toString());

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(2);
    Assert.assertEquals(
        "0.000000000000000000000000000000000001", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, dec.scale());
    resultDec = dec.scaleByPowerOfTen(2);
    Assert.assertEquals(
        "0.000000000000000000000000000000000001", resultDec.toString());

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(38);
    Assert.assertEquals(
        "1", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, dec.scale());
    resultDec = dec.scaleByPowerOfTen(38);
    Assert.assertEquals(
        "1", resultDec.toString());

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(2 * 38 - 1);
    Assert.assertEquals(
        "10000000000000000000000000000000000000", oldResultDec.toString());
    Assert.assertEquals(0, oldResultDec.scale());
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, dec.scale());
    resultDec = dec.scaleByPowerOfTen(2 * 38 - 1);
    Assert.assertEquals(
        "10000000000000000000000000000000000000", resultDec.toString());
    Assert.assertEquals(0, resultDec.scale());

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(2 * 38);
    Assert.assertTrue(oldResultDec == null);
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "0.00000000000000000000000000000000000001");
    Assert.assertEquals(38, dec.scale());
    resultDec = dec.scaleByPowerOfTen(2 * 38);
    Assert.assertTrue(resultDec == null);


    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(
        "0.00000000000000000000000000000000000022");
    Assert.assertEquals(38, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(38);
    Assert.assertEquals(
        "22", oldResultDec.toString());
    Assert.assertEquals(0, oldResultDec.scale());
    //---------------------------------------------------
    dec = HiveDecimal.create(
        "0.00000000000000000000000000000000000022");
    Assert.assertEquals(38, dec.scale());
    resultDec = dec.scaleByPowerOfTen(38);
    Assert.assertEquals(
        "22", resultDec.toString());
    Assert.assertEquals(0, resultDec.scale());

    //---------------------------------------------------
    oldDec = HiveDecimalV1.create("3.00001415926");
    Assert.assertEquals(11, oldDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(2);
    Assert.assertEquals("300.001415926", oldResultDec.toString());
    Assert.assertEquals(9, oldResultDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(5);
    Assert.assertEquals("300001.415926", oldResultDec.toString());
    Assert.assertEquals(6, oldResultDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(18);
    Assert.assertEquals("3000014159260000000", oldResultDec.toString());
    Assert.assertEquals(0, oldResultDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(35);
    Assert.assertEquals("300001415926000000000000000000000000", oldResultDec.toString());
    Assert.assertEquals(0, oldResultDec.scale());
    oldResultDec = oldDec.scaleByPowerOfTen(37);
    Assert.assertEquals("30000141592600000000000000000000000000", oldResultDec.toString());
    Assert.assertEquals(0, oldResultDec.scale());
    //---------------------------------------------------
    dec = HiveDecimal.create("3.00001415926");
    Assert.assertEquals(11, dec.scale());
    Assert.assertEquals(1, dec.integerDigitCount());
    resultDec = dec.scaleByPowerOfTen(2);
    Assert.assertEquals("300.001415926", resultDec.toString());
    Assert.assertEquals(9, resultDec.scale());
    Assert.assertEquals(3, resultDec.integerDigitCount());
    resultDec = dec.scaleByPowerOfTen(5);
    Assert.assertEquals("300001.415926", resultDec.toString());
    Assert.assertEquals(6, resultDec.scale());
    Assert.assertEquals(6, resultDec.integerDigitCount());
    resultDec = dec.scaleByPowerOfTen(18);
    Assert.assertEquals("3000014159260000000", resultDec.toString());
    Assert.assertEquals(0, resultDec.scale());
    Assert.assertEquals(19, resultDec.integerDigitCount());
    resultDec = dec.scaleByPowerOfTen(35);
    Assert.assertEquals("300001415926000000000000000000000000", resultDec.toString());
    Assert.assertEquals(0, resultDec.scale());
    Assert.assertEquals(36, resultDec.integerDigitCount());
    resultDec = dec.scaleByPowerOfTen(37);
    Assert.assertEquals("30000141592600000000000000000000000000", resultDec.toString());
    Assert.assertEquals(0, resultDec.scale());
    Assert.assertEquals(38, resultDec.integerDigitCount());
  }

  @Test
  public void testSingleWordDivision() {
 
    HiveDecimalV1 oldDec1;
    HiveDecimalV1 oldDec2;
    HiveDecimalV1 oldResultDec;

    HiveDecimal dec1;
    HiveDecimal dec2;
    HiveDecimal resultDec;

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("839293");
    oldDec2 = HiveDecimalV1.create("8");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("104911.625", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("839293");
    dec2 = HiveDecimal.create("8");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("104911.625", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("1");
    oldDec2 = HiveDecimalV1.create("3");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("0.33333333333333333333333333333333333333", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("1");
    dec2 = HiveDecimal.create("3");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("0.33333333333333333333333333333333333333", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("1");
    oldDec2 = HiveDecimalV1.create("9");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("0.11111111111111111111111111111111111111", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("1");
    dec2 = HiveDecimal.create("9");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("0.11111111111111111111111111111111111111", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("22");
    oldDec2 = HiveDecimalV1.create("7");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("3.1428571428571428571428571428571428571", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("22");
    dec2 = HiveDecimal.create("7");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("3.1428571428571428571428571428571428571", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("1");
    oldDec2 = HiveDecimalV1.create("81");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("0.01234567901234567901234567901234567901", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("1");
    dec2 = HiveDecimal.create("81");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("0.01234567901234567901234567901234567901", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("425");
    oldDec2 = HiveDecimalV1.create("1000000000000000");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("0.000000000000425", oldResultDec.toString());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("425");
    dec2 = HiveDecimal.create("1000000000000000");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("0.000000000000425", resultDec.toString());  // UNDONE

    //---------------------------------------------------
    oldDec1 = HiveDecimalV1.create("0.000000000088");
    oldDec2 = HiveDecimalV1.create("1000000000000000");
    oldResultDec = oldDec1.divide(oldDec2);
    Assert.assertEquals("0.000000000000000000000000088", oldResultDec.toString());
    Assert.assertEquals(27, oldResultDec.scale());
    //---------------------------------------------------
    dec1 = HiveDecimal.create("0.000000000088");
    dec2 = HiveDecimal.create("1000000000000000");
    resultDec = dec1.divide(dec2);
    Assert.assertEquals("0.000000000000000000000000088", resultDec.toString());  // UNDONE
    Assert.assertEquals(27, resultDec.scale());
   }

  @Test
  public void testDivide() {
    HiveDecimal dec1 = HiveDecimal.create("3.14");
    HiveDecimal dec2 = HiveDecimal.create("3");
    Assert.assertNotNull(dec1.divide(dec2));

    dec1 = HiveDecimal.create("15");
    dec2 = HiveDecimal.create("5");
    Assert.assertEquals("3", dec1.divide(dec2).toString());

    dec1 = HiveDecimal.create("3.140");
    dec2 = HiveDecimal.create("1.00");
    Assert.assertEquals("3.14", dec1.divide(dec2).toString());
  }

  @Test
  public void testPlus() {

    HiveDecimalV1 oldDec;
    HiveDecimalV1 oldDec2;
    HiveDecimalV1 oldResultDec;

    HiveDecimal dec;
    HiveDecimal dec1;
    HiveDecimal dec2;
    HiveDecimal resultDec;

    String decStr;
    String decStr2;

    dec1 = HiveDecimal.create("3.140");
    dec1.validate();
    dec2 = HiveDecimal.create("1.00");
    dec2.validate();
    resultDec = dec1.add(dec2);
    resultDec.validate();
    Assert.assertEquals("4.14", resultDec.toString());

    decStr = "3.140";
    decStr2 = "1.00";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("4.14", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("4.14", resultDec.toString());
    Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "3.140";
    decStr2 = "1.00000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("4.14000008733", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("4.14000008733", resultDec.toString());
    Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "3.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("4.14000000000000000008733", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("4.14000000000000000008733", resultDec.toString());
    Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "30000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("30000000001.14000000000000000008733", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("30000000001.14000000000000000008733", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("300000000000001.14000000000000000008733", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000000001.14000000000000000008733", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    // Edge case?
    decStr = "3000000000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("3000000000000001.1400000000000000000873", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("3000000000000001.1400000000000000000873", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000000000000.14";
    decStr2 = "0.0000055555555550008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("300000000000000000000000.14000555555556", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000000000000000000.14000555555556", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000000000000.14";
    decStr2 = "0.000005555555555000873355";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("300000000000000000000000.14000555555556", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000000000000000000.14000555555556", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());



    // Example from HiveDecimal.add header comments.
    decStr = "598575157855521918987423259.94094";
    decStr2 = "0.0000000000006711991169422033";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("598575157855521918987423259.94094", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("598575157855521918987423259.94094", resultDec.toString());
    Assert.assertEquals(27, resultDec.integerDigitCount());

    decStr = "598575157855521918987423259.94094";
    decStr2 = "0.5555555555556711991169422033";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("598575157855521918987423260.49649555556", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("598575157855521918987423260.49649555556", resultDec.toString());
    Assert.assertEquals(27, resultDec.integerDigitCount());

    decStr = "199999999.99995";
    decStr2 = "100000000.00005";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("300000000", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000", resultDec.toString());
    Assert.assertEquals(9, resultDec.integerDigitCount());

    dec1 = HiveDecimal.create("99999999999999999999999999999999999999");
    dec1.validate();
    Assert.assertEquals(38, dec1.integerDigitCount());
    dec2 = HiveDecimal.create("1");
    dec2.validate();
    Assert.assertNull(dec1.add(dec2));
  }

  @Test
  public void testAdd() {

    HiveDecimalV1 oldDec;
    HiveDecimalV1 oldDec2;
    HiveDecimalV1 oldResultDec;

    HiveDecimal dec;
    HiveDecimal dec2;
    HiveDecimal resultDec;

    // Use the example from HIVE-13423 where the integer digits of the result exceed the
    // enforced precision/scale.
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create("98765432109876543210.12345");
    oldResultDec = oldDec.add(oldDec);
    Assert.assertEquals("197530864219753086420.2469", oldResultDec.toString());
    oldResultDec = HiveDecimalV1.enforcePrecisionScale(oldResultDec, 38, 18);
    Assert.assertTrue(oldResultDec == null);
    //---------------------------------------------------
    dec = HiveDecimal.create("98765432109876543210.12345");
    assertTrue(dec != null);
    dec.validate();
    resultDec = dec.add(dec);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("197530864219753086420.2469", resultDec.toString());
    // Assert.assertEquals(21, resultDec.integerDigitCount());
    resultDec = HiveDecimal.enforcePrecisionScale(resultDec, 38, 18);
    Assert.assertTrue(resultDec == null);
 
    // Make sure zero trimming doesn't extend into the integer digits.
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create("199999999.99995");
    oldDec2 = HiveDecimalV1.create("100000000.00005");
    oldResultDec = oldDec.add(oldDec2);
    Assert.assertEquals("300000000", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create("199999999.99995");
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create("100000000.00005");
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.add(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000", resultDec.toString());
    Assert.assertEquals(9, resultDec.integerDigitCount());
   }

  @Test
  public void testMinus() {

    HiveDecimalV1 oldDec;
    HiveDecimalV1 oldDec2;
    HiveDecimalV1 oldResultDec;

    HiveDecimal dec;
    HiveDecimal dec1;
    HiveDecimal dec2;
    HiveDecimal resultDec;

    String decStr;
    String decStr2;

    dec1 = HiveDecimal.create("3.140");
    dec1.validate();
    dec2 = HiveDecimal.create("1.00");
    dec2.validate();
    resultDec = dec1.add(dec2);
    resultDec.validate();
    Assert.assertEquals("4.14", resultDec.toString());

    decStr = "3.140";
    decStr2 = "1.00";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("2.14", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("2.14", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "3.140";
    decStr2 = "1.00000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("2.13999991267", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("2.13999991267", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "3.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("2.13999999999999999991267", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("2.13999999999999999991267", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "30000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("29999999999.13999999999999999991267", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("29999999999.13999999999999999991267", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("299999999999999.13999999999999999991267", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("299999999999999.13999999999999999991267", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    // Edge case?
    decStr = "3000000000000000.140";
    decStr2 = "1.00000000000000000008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("2999999999999999.1399999999999999999127", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("2999999999999999.1399999999999999999127", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000000000000.14";
    decStr2 = "0.0000055555555550008733";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("300000000000000000000000.13999444444444", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000000000000000000.13999444444444", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "300000000000000000000000.14";
    decStr2 = "0.000005555555555000873355";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("300000000000000000000000.13999444444444", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("300000000000000000000000.13999444444444", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    // Example from HiveDecimal.subtract header comments.
    decStr = "598575157855521918987423259.94094";
    decStr2 = "0.0000000000006711991169422033";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("598575157855521918987423259.94094", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("598575157855521918987423259.94094", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());

    decStr = "598575157855521918987423259.94094";
    decStr2 = "0.5555555555556711991169422033";
    //---------------------------------------------------
    oldDec = HiveDecimalV1.create(decStr);
    oldDec2 = HiveDecimalV1.create(decStr2);
    oldResultDec = oldDec.subtract(oldDec2);
    Assert.assertEquals("598575157855521918987423259.38538444444", oldResultDec.toString());
    //---------------------------------------------------
    dec = HiveDecimal.create(decStr);
    assertTrue(dec != null);
    dec.validate();
    dec2 = HiveDecimal.create(decStr2);
    assertTrue(dec2 != null);
    dec2.validate();
    resultDec = dec.subtract(dec2);
    assertTrue(resultDec != null);
    resultDec.validate();
    Assert.assertEquals("598575157855521918987423259.38538444444", resultDec.toString());
    // Assert.assertEquals(1, resultDec.integerDigitCount());
  }

  @Test
  public void testSubtract() {
    HiveDecimal dec1 = HiveDecimal.create("3.140");
    assertTrue(dec1 != null);
    dec1.validate();
    HiveDecimal dec2 = HiveDecimal.create("1.00");
    assertTrue(dec2 != null);
    dec2.validate();
    HiveDecimal result = dec1.subtract(dec2);
    assertTrue(result != null);
    result.validate();
    Assert.assertEquals("2.14", result.toString());

    dec1 = HiveDecimal.create("0.00001786135888657847525803");
    assertTrue(dec1 != null);
    dec1.validate();
    dec2 = HiveDecimal.create("3.0000123456789");
    assertTrue(dec2 != null);
    dec2.validate();
    result = dec1.subtract(dec2);
    assertTrue(result != null);
    result.validate();
    Assert.assertEquals("-2.99999448432001342152474197", result.toString());
  }

  @Test
  public void testPosMod() {
    HiveDecimal hd1 = HiveDecimal.create("-100.91");
    assertTrue(hd1 != null);
    hd1.validate();
    HiveDecimal hd2 = HiveDecimal.create("9.8");
    assertTrue(hd2 != null);
    hd2.validate();
    HiveDecimal dec = hd1.remainder(hd2).add(hd2).remainder(hd2);
    assertTrue(dec != null);
    dec.validate();
    Assert.assertEquals("6.89", dec.toString());
  }

  @Test
  public void testHashCode() {
      Assert.assertEquals(HiveDecimal.create("9").hashCode(), HiveDecimal.create("9.00").hashCode());
      Assert.assertEquals(HiveDecimal.create("0").hashCode(), HiveDecimal.create("0.00").hashCode());
  }

  @Test
  public void testException() {
    HiveDecimal dec = HiveDecimal.create("3.1415.926");
    Assert.assertNull(dec);
    dec = HiveDecimal.create("3abc43");
    Assert.assertNull(dec);
  }

  @Test
  public void testBinaryConversion() {
    Random r = new Random(2399);
    for (String decString : specialDecimalStrings) {
      doTestBinaryConversion(decString, r);
    }
  }

  private void doTestBinaryConversion(String num, Random r) {
    int scale = r.nextInt(HiveDecimal.MAX_SCALE);
    HiveDecimal dec = HiveDecimal.create(num);
    if (dec == null) {
      return;
    }
    byte[] d = dec.setScale(scale).unscaledValue().toByteArray();
    HiveDecimal roundedDec = dec.setScale(scale, HiveDecimal.ROUND_HALF_UP);
    Assert.assertEquals(roundedDec, HiveDecimal.create(new BigInteger(d), scale));
  }

//------------------------------------------------------------------------------------------------

  @Test
  public void testDecimalsWithOneOne() {
    doTestDecimalsWithPrecisionScale(decimal_1_1_txt, 1, 1);
  }

  @Test
  public void testDecimalsWithKv7Keys() {
    doTestDecimalsWithPrecisionScale(kv7_txt_keys, 38, 18);
  }

  public void doTestDecimalsWithPrecisionScale(String[] decStrings, int precision, int scale) {

    HiveDecimalV1 oldSum = HiveDecimalV1.create(0);
    HiveDecimalWritable sum = new HiveDecimalWritable(0);

    for (int i = 0; i < decStrings.length; i++) {

      String string = decStrings[i];

      HiveDecimalV1 oldDec = HiveDecimalV1.create(string);

      HiveDecimalV1 resultOldDec;
      if (oldDec == null) {
        resultOldDec = null;
      } else {
        resultOldDec = HiveDecimalV1.enforcePrecisionScale(oldDec, precision, scale);
      }

      HiveDecimal dec = HiveDecimal.create(string);

      if (oldDec == null) {
        Assert.assertTrue(dec == null);
        continue;
      }
      HiveDecimal resultDec = HiveDecimal.enforcePrecisionScale(dec, precision, scale);
      if (resultOldDec == null) {
        Assert.assertTrue(resultDec == null);
        continue;
      }

      Assert.assertEquals(resultOldDec.toString(), resultDec.toString());
      Assert.assertEquals(resultOldDec.toFormatString(scale), resultDec.toFormatString(scale));

      oldSum = oldSum.add(resultOldDec);
      sum.mutateAdd(resultDec);
    }

    Assert.assertEquals(oldSum.toString(), sum.toString());
  }

//------------------------------------------------------------------------------------------------

  @Test
  public void testDecimalsWithOneOneWritable() {
    doTestDecimalsWithPrecisionScaleWritable(decimal_1_1_txt, 1, 1);
  }

  @Test
  public void testDecimalsWithKv7KeysWritable() {
    doTestDecimalsWithPrecisionScaleWritable(kv7_txt_keys, 38, 18);
  }

  public void doTestDecimalsWithPrecisionScaleWritable(String[] decStrings, int precision, int scale) {

    HiveDecimalV1 oldSum = HiveDecimalV1.create(0);
    HiveDecimalWritable sum = new HiveDecimalWritable(0);

    for (int i = 0; i < decStrings.length; i++) {
      String string = decStrings[i];

      HiveDecimalV1 oldDec = HiveDecimalV1.create(string);
      HiveDecimalV1 resultOldDec;
      if (oldDec == null) {
        resultOldDec = null;
      } else {
        resultOldDec = HiveDecimalV1.enforcePrecisionScale(oldDec, precision, scale);
      }

      HiveDecimalWritable decWritable = new HiveDecimalWritable(string);
      if (oldDec == null) {
        Assert.assertTrue(!decWritable.isSet());
        continue;
      }
      decWritable.mutateEnforcePrecisionScale(precision, scale);;
      if (resultOldDec == null) {
        Assert.assertTrue(!decWritable.isSet());
        continue;
      }

      Assert.assertEquals(resultOldDec.toString(), decWritable.toString());
      Assert.assertEquals(resultOldDec.toFormatString(scale), decWritable.toFormatString(scale));

      oldSum = oldSum.add(resultOldDec);
      sum.mutateAdd(decWritable);
    }

    Assert.assertEquals(oldSum.toString(), sum.toString());
  }

  //------------------------------------------------------------------------------------------------

  @Test
  public void testSort() {
    doTestSort(decimal_1_1_txt);
  }

  @Test
  public void testSortSpecial() {
    doTestSort(specialDecimalStrings);
  }

  @Test
  public void testSortRandom() {
    Random r = new Random(14434);
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      doTestSortRandom(r, standardAlphabet, bigDecimalFlavor);
    }
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      for (String sparseAlphabet : sparseAlphabets) {
        doTestSortRandom(r, sparseAlphabet, bigDecimalFlavor);
      }
    }
  }

  public void doTestSortRandom(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
    String[] randomStrings = new String[POUND_FACTOR];

    for (int i = 0; i < POUND_FACTOR; i++) {
      BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);

      randomStrings[i] = bigDecimal.toString();
    }

    doTestSort(randomStrings);
  }

  public void doTestSort(String[] decStrings) {

    HiveDecimalV1[] oldDecSortArray = new HiveDecimalV1[decStrings.length];
    HiveDecimal[] decSortArray = new HiveDecimal[decStrings.length];

    int count = 0;
    for (int i = 0; i < decStrings.length; i++) {
      String string = decStrings[i];

      HiveDecimalV1 oldDec = HiveDecimalV1.create(string);
      if (oldDec == null) {
        continue;
      }
      if (isTenPowerBug(oldDec.toString())) {
        continue;
      }
      oldDecSortArray[count] = oldDec;

      HiveDecimal dec = HiveDecimal.create(string);
      if (dec == null) {
        Assert.fail();
      }
      decSortArray[count] = dec;
      count++;
    }

    oldDecSortArray = Arrays.copyOf(oldDecSortArray,  count);
    decSortArray = Arrays.copyOf(decSortArray, count);

    Arrays.sort(oldDecSortArray);
    Arrays.sort(decSortArray);

    for (int i = 0; i < count; i++) {
      String oldDecString = oldDecSortArray[i].toString();
      String decString = decSortArray[i].toString();

      if (!oldDecString.equals(decString)) {
        Assert.fail();
      }
    }
  }

  //------------------------------------------------------------------------------------------------

  @Test
  public void testRandomCreateFromBigDecimal() {
    Random r = new Random(14434);
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      doTestRandomCreateFromBigDecimal(r, standardAlphabet, bigDecimalFlavor);
    }
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      for (String sparseAlphabet : sparseAlphabets) {
        doTestRandomCreateFromBigDecimal(r, sparseAlphabet, bigDecimalFlavor);
      }
    }
  }

  private void doTestRandomCreateFromBigDecimal(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {

    for (int i = 0; i < POUND_FACTOR; i++) {
      BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);

      doTestCreateFromBigDecimal(bigDecimal);
    }
  }

  @Test
  public void testCreateFromBigDecimalSpecial() {
    for (BigDecimal bigDecimal : specialBigDecimals) {
      doTestCreateFromBigDecimal(bigDecimal);
    }
  }

  private void doTestCreateFromBigDecimal(BigDecimal bigDecimal) {

    HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
    if (oldDec != null && isTenPowerBug(oldDec.toString())) {
      return;
    }
    HiveDecimal dec = HiveDecimal.create(bigDecimal);
    if (oldDec == null) {
      assertTrue(dec == null);
      return;
    }
    assertTrue(dec != null);
    dec.validate();

    Assert.assertEquals(oldDec.toString(), dec.toString());
  }

  //------------------------------------------------------------------------------------------------

  @Test
  public void testRandomCreateFromBigDecimalNoRound() {
    Random r = new Random(14434);
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      doTestRandomCreateFromBigDecimalNoRound(r, standardAlphabet, bigDecimalFlavor);
    }
    for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
      for (String sparseAlphabet : sparseAlphabets) {
        doTestRandomCreateFromBigDecimalNoRound(r, sparseAlphabet, bigDecimalFlavor);
      }
    }
  }

  private void doTestRandomCreateFromBigDecimalNoRound(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {

    for (int i = 0; i < POUND_FACTOR; i++) {
      BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);

      doTestCreateFromBigDecimalNoRound(bigDecimal);
    }
  }

  @Test
  public void testCreateFromBigDecimalNoRoundSpecial() {
    for (BigDecimal bigDecimal : specialBigDecimals) {
      doTestCreateFromBigDecimalNoRound(bigDecimal);
    }
  }

  private void doTestCreateFromBigDecimalNoRound(BigDecimal bigDecimal) {

    HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal, /* allowRounding
storage-api/src/test/org/apache/hadoop/hive/common/type/TestHiveDecimal.java