Add new Java 8 methods in BigInteger.

Change-Id: I4265ca2583abf3ddc151861e76fedb43a4b8f583
diff --git a/user/super/com/google/gwt/emul/java/math/BigInteger.java b/user/super/com/google/gwt/emul/java/math/BigInteger.java
index 600c873..545b861 100644
--- a/user/super/com/google/gwt/emul/java/math/BigInteger.java
+++ b/user/super/com/google/gwt/emul/java/math/BigInteger.java
@@ -607,6 +607,21 @@
   }
 
   /**
+   * Converts value of this {@code BigInteger} to a {@code byte} if it fits it,
+   * otherwise {@code ArithmeticException} is thrown.
+   *
+   * @return this {@code BigInteger} converted to a {@code byte}.
+   * @throws ArithmeticException if the value of this {@code BigInteger}
+   *         does not fit in a {@code byte}.
+   */
+  public byte byteValueExact() {
+    if (numberLength <= 1 && bitLength() <= 7) {
+      return byteValue();
+    }
+    throw new ArithmeticException("out of byte range");
+  }
+
+  /**
    * Returns a new {@code BigInteger} which has the same binary representation
    * as {@code this} but with the bit at position n cleared. The result is
    * equivalent to {@code this & ~(2^n)}.
@@ -900,6 +915,21 @@
   }
 
   /**
+   * Converts value of this {@code BigInteger} to an {@code int} if it fits it,
+   * otherwise {@code ArithmeticException} is thrown.
+   *
+   * @return this {@code BigInteger} converted to an {@code int}.
+   * @throws ArithmeticException if the value of this {@code BigInteger}
+   *         does not fit in an {@code int}.
+   */
+  public int intValueExact() {
+    if (numberLength <= 1 && bitLength() <= 31) {
+      return intValue();
+    }
+    throw new ArithmeticException("out of int range");
+  }
+
+  /**
    * Tests whether this {@code BigInteger} is probably prime. If {@code true} is
    * returned, then this is prime with a probability beyond (1-1/2^certainty).
    * If {@code false} is returned, then this is definitely composite. If the
@@ -927,6 +957,21 @@
   }
 
   /**
+   * Converts value of this {@code BigInteger} to a {@code long} if it fits it,
+   * otherwise {@code ArithmeticException} is thrown.
+   *
+   * @return this {@code BigInteger} converted to a {@code long}.
+   * @throws ArithmeticException if the value of this {@code BigInteger}
+   *         does not fit in a {@code long}.
+   */
+  public long longValueExact() {
+    if (numberLength <= 2 && bitLength() <= 63) {
+      return longValue();
+    }
+    throw new ArithmeticException("out of long range");
+  }
+
+  /**
    * Returns the maximum of this {@code BigInteger} and {@code val}.
    *
    * @param val value to be used to compute the maximum with {@code this}
@@ -1251,6 +1296,21 @@
   }
 
   /**
+   * Converts value of this {@code BigInteger} to a {@code short} if it fits it,
+   * otherwise {@code ArithmeticException} is thrown.
+   *
+   * @return this {@code BigInteger} converted to a {@code short}.
+   * @throws ArithmeticException if the value of this {@code BigInteger}
+   *         does not fit in a {@code short}.
+   */
+  public short shortValueExact() {
+    if (numberLength <= 1 && bitLength() <= 15) {
+      return shortValue();
+    }
+    throw new ArithmeticException("out of short range");
+  }
+
+  /**
    * Returns the sign of this {@code BigInteger}.
    *
    * @return {@code -1} if {@code this < 0}, {@code 0} if {@code this == 0},
diff --git a/user/test/com/google/gwt/emultest/java/math/BigIntegerConvertTest.java b/user/test/com/google/gwt/emultest/java/math/BigIntegerConvertTest.java
index 2ca911c..e21ac63 100644
--- a/user/test/com/google/gwt/emultest/java/math/BigIntegerConvertTest.java
+++ b/user/test/com/google/gwt/emultest/java/math/BigIntegerConvertTest.java
@@ -46,6 +46,26 @@
  * valueOf(long val), floatValue(), doubleValue().
  */
 public class BigIntegerConvertTest extends EmulTestBase {
+
+  public void testByteValueExact() {
+    assertEquals(-1, BigInteger.valueOf(-1).byteValueExact());
+    assertEquals(0, BigInteger.valueOf(0).byteValueExact());
+    assertEquals(1, BigInteger.valueOf(1).byteValueExact());
+    assertEquals(Byte.MAX_VALUE, BigInteger.valueOf(Byte.MAX_VALUE).byteValueExact());
+    assertEquals(Byte.MIN_VALUE, BigInteger.valueOf(Byte.MIN_VALUE).byteValueExact());
+
+    try {
+      BigInteger.valueOf(Byte.MAX_VALUE + 1).byteValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+    try {
+      BigInteger.valueOf(Byte.MIN_VALUE - 1).byteValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+  }
+
   /**
    * Convert a negative number to a double value. The number's bit length is
    * less than 64 bits.
@@ -634,6 +654,25 @@
     assertEquals(resInt, aNumber);
   }
 
+  public void testIntValueExact() {
+    assertEquals(-1, BigInteger.valueOf(-1).intValueExact());
+    assertEquals(0, BigInteger.valueOf(0).intValueExact());
+    assertEquals(1, BigInteger.valueOf(1).intValueExact());
+    assertEquals(Integer.MAX_VALUE, BigInteger.valueOf(Integer.MAX_VALUE).intValueExact());
+    assertEquals(Integer.MIN_VALUE, BigInteger.valueOf(Integer.MIN_VALUE).intValueExact());
+
+    try {
+      BigInteger.valueOf(Integer.MAX_VALUE + 1L).intValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+    try {
+      BigInteger.valueOf(Integer.MIN_VALUE - 1L).intValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+  }
+
   /**
    * Convert a number to a negative long value The BigInteger is longer than
    * int.
@@ -676,6 +715,44 @@
     assertEquals(result, aNumber);
   }
 
+  public void testLongValueExact() {
+    assertEquals(-1, BigInteger.valueOf(-1).longValueExact());
+    assertEquals(0, BigInteger.valueOf(0).longValueExact());
+    assertEquals(1, BigInteger.valueOf(1).longValueExact());
+    assertEquals(Long.MAX_VALUE, BigInteger.valueOf(Long.MAX_VALUE).longValueExact());
+    assertEquals(Long.MIN_VALUE, BigInteger.valueOf(Long.MIN_VALUE).longValueExact());
+
+    try {
+      BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE).longValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+    try {
+      BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE).longValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+  }
+
+  public void testShortValueExact() {
+    assertEquals(-1, BigInteger.valueOf(-1).shortValueExact());
+    assertEquals(0, BigInteger.valueOf(0).shortValueExact());
+    assertEquals(1, BigInteger.valueOf(1).shortValueExact());
+    assertEquals(Short.MAX_VALUE, BigInteger.valueOf(Short.MAX_VALUE).shortValueExact());
+    assertEquals(Short.MIN_VALUE, BigInteger.valueOf(Short.MIN_VALUE).shortValueExact());
+
+    try {
+      BigInteger.valueOf(Short.MAX_VALUE + 1).shortValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+    try {
+      BigInteger.valueOf(Short.MIN_VALUE - 1).shortValueExact();
+      fail("overflow expected");
+    } catch (Exception expected) {
+    }
+  }
+
   /**
    * valueOf (long val): convert Integer.MAX_VALUE to a BigInteger.
    */