Merge branch 'port_commons_lang_Fraction' of https://github.com/XenoAmess/commons-numbers into XenoAmess-port_commons_lang_Fraction
diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
index b2bb256..bbd8292 100644
--- a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
@@ -266,6 +266,16 @@
     /**
      * Raise an int to an int power.
      *
+     * <p>Special cases:</p>
+     * <ul>
+     *   <li>{@code k^0} returns {@code 1} (including {@code k=0})
+     *   <li>{@code k^1} returns {@code k} (including {@code k=0})
+     *   <li>{@code 0^0} returns {@code 1}
+     *   <li>{@code 0^e} returns {@code 0}
+     *   <li>{@code 1^e} returns {@code 1}
+     *   <li>{@code (-1)^e} returns {@code -1 or 1} if {@code e} is odd or even
+     * </ul>
+     *
      * @param k Number to raise.
      * @param e Exponent (must be positive or zero).
      * @return \( k^e \)
@@ -278,6 +288,22 @@
             throw new IllegalArgumentException(NEGATIVE_EXPONENT_1 + e + NEGATIVE_EXPONENT_2);
         }
 
+        if (k == 0) {
+            return e == 0 ? 1 : 0;
+        }
+
+        if (k == 1) {
+            return 1;
+        }
+
+        if (k == -1) {
+            return (e & 1) == 0 ? 1 : -1;
+        }
+
+        if (e >= 31) {
+            throw new ArithmeticException("integer overflow");
+        }
+
         int exp = e;
         int result = 1;
         int k2p    = k;
@@ -300,6 +326,16 @@
     /**
      * Raise a long to an int power.
      *
+     * <p>Special cases:</p>
+     * <ul>
+     *   <li>{@code k^0} returns {@code 1} (including {@code k=0})
+     *   <li>{@code k^1} returns {@code k} (including {@code k=0})
+     *   <li>{@code 0^0} returns {@code 1}
+     *   <li>{@code 0^e} returns {@code 0}
+     *   <li>{@code 1^e} returns {@code 1}
+     *   <li>{@code (-1)^e} returns {@code -1 or 1} if {@code e} is odd or even
+     * </ul>
+     *
      * @param k Number to raise.
      * @param e Exponent (must be positive or zero).
      * @return \( k^e \)
@@ -312,6 +348,22 @@
             throw new IllegalArgumentException(NEGATIVE_EXPONENT_1 + e + NEGATIVE_EXPONENT_2);
         }
 
+        if (k == 0L) {
+            return e == 0 ? 1L : 0L;
+        }
+
+        if (k == 1L) {
+            return 1L;
+        }
+
+        if (k == -1L) {
+            return (e & 1) == 0 ? 1L : -1L;
+        }
+
+        if (e >= 63) {
+            throw new ArithmeticException("long overflow");
+        }
+
         int exp = e;
         long result = 1;
         long k2p    = k;
diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
index 5a4bb73..5f466a2 100644
--- a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
+++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
@@ -422,6 +422,25 @@
     }
 
     @Test
+    void testPowEdgeCases() {
+        Assertions.assertEquals(0, ArithmeticUtils.pow(0, 2));
+        Assertions.assertEquals(0L, ArithmeticUtils.pow(0L, 2));
+        Assertions.assertEquals(0, ArithmeticUtils.pow(0, 1));
+        Assertions.assertEquals(0L, ArithmeticUtils.pow(0L, 1));
+        Assertions.assertEquals(1, ArithmeticUtils.pow(0, 0));
+        Assertions.assertEquals(1L, ArithmeticUtils.pow(0L, 0));
+
+        for (int i = 20; i <= 35; i++) {
+            final int ti = i;
+            Assertions.assertThrows(ArithmeticException.class, () -> ArithmeticUtils.pow(3, ti));
+        }
+        for (int i = 40; i <= 70; i++) {
+            final int ti = i;
+            Assertions.assertThrows(ArithmeticException.class, () -> ArithmeticUtils.pow(3L, ti));
+        }
+    }
+
+    @Test
     void testIsPowerOfTwo() {
         final int n = 1025;
         final boolean[] expected = new boolean[n];
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 9c2aa6e..eedf591 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -72,6 +72,9 @@
         "Fraction/BigFraction": Fixed pow(int) to handle Integer.MIN_VALUE and throw
         ArithmeticException for negative exponents to a fraction of zero.
       </action>
+      <action dev="aherbert" type="update" issue="NUMBERS-151" due-to="Jin Xu">
+        "ArithmeticUtils": Refine pow(int, int) and pow(long, int) for edge cases.
+      </action>
     </release>
 
     <release version="1.0-beta1" date="2020-04-08" description="