FAQ
Author: ehans
Date: Fri Jan 31 23:27:53 2014
New Revision: 1563338

URL: http://svn.apache.org/r1563338
Log:
HIVE-6257: Add more unit tests for high-precision Decimal128 arithmetic (Eric Hanson, reviewed by Jitendra Pandey)

Modified:

==============================================================================
+++ hive/trunk/common/src/test/org/apache/hadoop/hive/common/type/TestDecimal128.java Fri Jan 31 23:27:53 2014
@@ -17,6 +17,9 @@ package org.apache.hadoop.hive.common.ty

import static org.junit.Assert.*;

+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
import java.util.Random;

import org.junit.After;
@@ -376,6 +379,203 @@ public class TestDecimal128 {
verifyMultiplyDivideInverse(a, b);
}

+ // Test a set of random adds at high precision.
+ @Test
+ final int N = 10000;
+ for (int i = 0; i < N; i++) {
+ }
+ }
+
+ // Test one random hi-precision decimal add.
+
+ Decimal128 a, b, r;
+ String sA, sB;
+
+ a = new Decimal128();
+ sA = makeNumericString(37);
+ a.update(sA, (short) 0);
+ b = new Decimal128();
+ sB = makeNumericString(37);
+ b.update(sB, (short) 0);
+
+ r = new Decimal128();
+
+ String res1 = r.toFormalString();
+
+ // Now do the add with Java BigDecimal
+ BigDecimal bdA = new BigDecimal(sA);
+ BigDecimal bdB = new BigDecimal(sB);
+
+ String res2 = bdR.toPlainString();
+
+ // Compare the results
+ assertEquals(res1, res2);
+ }
+
+ // Test a set of random subtracts at high precision.
+ @Test
+ public void testHighPrecisionDecimal128Subtract() {
+ final int N = 10000;
+ for (int i = 0; i < N; i++) {
+ verifyHighPrecisionSubtractSingle();
+ }
+ }
+
+ // Test one random high-precision subtract.
+ private void verifyHighPrecisionSubtractSingle() {
+
+ Decimal128 a, b, r;
+ String sA, sB;
+
+ a = new Decimal128();
+ sA = makeNumericString(37);
+ a.update(sA, (short) 0);
+ b = new Decimal128();
+ sB = makeNumericString(37);
+ b.update(sB, (short) 0);
+
+ r = new Decimal128();
+ r.subtractDestructive(b, (short) 0);
+
+ String res1 = r.toFormalString();
+
+ // Now do the add with Java BigDecimal
+ BigDecimal bdA = new BigDecimal(sA);
+ BigDecimal bdB = new BigDecimal(sB);
+ BigDecimal bdR = bdA.subtract(bdB);
+
+ String res2 = bdR.toPlainString();
+
+ // Compare the results
+ assertEquals(res1, res2);
+ }
+
+ // Test a set of random multiplications at high precision.
+ @Test
+ public void testHighPrecisionDecimal128Multiply() {
+ final int N = 10000;
+ for (int i = 0; i < N; i++) {
+ verifyHighPrecisionMultiplySingle();
+ }
+ }
+
+ // Test a single, high-precision multiply of random inputs.
+ private void verifyHighPrecisionMultiplySingle() {
+
+ Decimal128 a, b, r;
+ String sA, sB;
+
+ Random rand = new Random();
+ int aDigits = rand.nextInt(37) + 1; // number of digits in a (1..37)
+ int bDigits = 38 - aDigits; // number of digits in b (1..37)
+ assertTrue(aDigits + bDigits == 38 && aDigits > 0 && bDigits > 0);
+
+ a = new Decimal128();
+ a.update(sA, (short) 0);
+ b = new Decimal128();
+ sB = makeNumericString(bDigits);
+ b.update(sB, (short) 0);
+
+ r = new Decimal128();
+ r.multiplyDestructive(b, (short) 0);
+
+ String res1 = r.toFormalString();
+
+ // Now do the add with Java BigDecimal
+ BigDecimal bdA = new BigDecimal(sA);
+ BigDecimal bdB = new BigDecimal(sB);
+ BigDecimal bdR = bdA.multiply(bdB);
+
+ String res2 = bdR.toPlainString();
+
+ // Compare the results
+ assertEquals(res1, res2);
+ }
+
+ // Test a set of random divisions at high precision.
+ @Test
+ public void testHighPrecisionDecimal128Divide() {
+ final int N = 10000;
+ for (int i = 0; i < N; i++) {
+ verifyHighPrecisionDivideSingle();
+ }
+ }
+
+ // Test a single, high-precision divide of random inputs.
+ private void verifyHighPrecisionDivideSingle() {
+
+ Decimal128 a, b, r;
+ String sA, sB;
+
+ Random rand = new Random();
+ int aDigits = rand.nextInt(37) + 1; // number of digits in a (1..37)
+ int bDigits = 38 - aDigits; // number of digits in b (1..37)
+ int temp;
+
+ // make sure b will have less digits than A
+ if (bDigits > aDigits) {
+ bDigits = temp;
+ }
+ if (bDigits == aDigits) {
+ return;
+ }
+ assertTrue(aDigits + bDigits == 38 && aDigits > 0 && bDigits > 0);
+
+ a = new Decimal128();
+ a.update(sA, (short) 0);
+ b = new Decimal128();
+ sB = makeNumericString(bDigits);
+ b.update(sB, (short) 0);
+ if (b.isZero()) {
+
+ // don't do zero-divide if one comes up at random
+ return;
+ }
+
+ r = new Decimal128();
+ r.divideDestructive(b, (short) 0);
+
+ String res1 = r.toFormalString();
+
+ // Now do the operation with Java BigDecimal
+ BigDecimal bdA = new BigDecimal(sA);
+ BigDecimal bdB = new BigDecimal(sB);
+ BigDecimal bdR = bdA.divide(bdB, 0, RoundingMode.HALF_UP);
+
+ String res2 = bdR.toPlainString();
+
+ // Compare the results
+ assertEquals(res1, res2);
+ }
+
+ /* Return a random number with length digits, as a string. Results may be
+ * negative or positive.
+ */
+ private String makeNumericString(int length) {
+ Random r = new Random();
+ StringBuilder b = new StringBuilder();
+ for(int i = 0; i < length; i++) {
+ b.append(r.nextInt(10));
+ }
+
+ // choose a random sign
+ String sign = r.nextInt(2) == 0 ? "-" : "";
+ return sign + b.toString();
+ }
+
@Test
public void testPiNewton() {

## Related Discussions

 view thread | post posts ‹ prev | 1 of 1 | next ›
Discussion Overview
 group commits categories hive, hadoop posted Jan 31, '14 at 11:28p active Jan 31, '14 at 11:28p posts 1 users 1 website hive.apache.org

### 1 user in discussion

Content

People

Support

Translate

site design / logo © 2021 Grokbase