Update exp() control flow for edge cases.

Added C99 edge cases in the comments.
diff --git a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
index 0adc915..68dc607 100644
--- a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
+++ b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
@@ -2016,37 +2016,55 @@
      * @see <a href="http://functions.wolfram.com/ElementaryFunctions/Exp/">Exp</a>
      */
     public Complex exp() {
-        // Set the values used to compute exp(real) * cis(im)
-        double expReal;
-        double im = imaginary;
         if (Double.isInfinite(real)) {
+            // Set the scale factor applied to cis(y)
+            double zeroOrInf;
             if (real < 0) {
-                expReal = 0;
-                if (!Double.isFinite(im)) {
-                    // Preserve conjugate equality
-                    im = Math.copySign(1, im);
+                if (!Double.isFinite(imaginary)) {
+                    // (−∞ + i∞) or (−∞ + iNaN) returns (±0 ± i0) (where the signs of the
+                    // real and imaginary parts of the result are unspecified).
+                    // Here we preserve the conjugate equality.
+                    return new Complex(0, Math.copySign(0, imaginary));
                 }
+                // (−∞ + iy) returns +0 cis(y), for finite y
+                zeroOrInf = 0;
             } else {
-                if (im == 0 || !Double.isFinite(im)) {
-                    return Double.isInfinite(im) ?
-                        new Complex(real, Double.NaN) :
-                        this;
+                // (+∞ + i0) returns +∞ + i0.
+                if (imaginary == 0) {
+                    return this;
                 }
-                expReal = real;
+                // (+∞ + i∞) or (+∞ + iNaN) returns (±∞ + iNaN) and raises the invalid
+                // floating-point exception (where the sign of the real part of the
+                // result is unspecified).
+                if (!Double.isFinite(imaginary)) {
+                    return new Complex(real, Double.NaN);
+                }
+                // (+∞ + iy) returns (+∞ cis(y)), for finite nonzero y.
+                zeroOrInf = real;
             }
-        } else if (imaginary == 0) {
-            // Real-only number
-            return Double.isNaN(real) ?
-                this :
-                new Complex(Math.exp(real), imaginary);
+            return new Complex(zeroOrInf * Math.cos(imaginary),
+                               zeroOrInf * Math.sin(imaginary));
         } else if (Double.isNaN(real)) {
+            // (NaN + i0) returns (NaN + i0);
+            // (NaN + iy) returns (NaN + iNaN) and optionally raises the invalid floating-point exception
+            // (NaN + iNaN) returns (NaN + iNaN)
+            return imaginary == 0 ? this : NAN;
+        } else if (!Double.isFinite(imaginary)) {
+            // (x + i∞) or (x + iNaN) returns (NaN + iNaN) and raises the invalid
+            // floating-point exception, for finite x.
             return NAN;
-        } else {
-            // real is finite
-            expReal = Math.exp(real);
         }
-        return new Complex(expReal * Math.cos(im),
-                           expReal * Math.sin(im));
+        // real and imaginary are finite.
+        // Compute e^a * (cos(b) + i sin(b)).
+
+        // Special case:
+        // (±0 + i0) returns (1 + i0)
+        final double exp = Math.exp(real);
+        if (imaginary == 0) {
+            return new Complex(exp, imaginary);
+        }
+        return new Complex(exp * Math.cos(imaginary),
+                           exp * Math.sin(imaginary));
     }
 
     /**
@@ -2105,6 +2123,12 @@
      * @see #arg()
      */
     private Complex log(UnaryOperation log, double logOf2, ComplexConstructor constructor) {
+        // TODO - Add edge cases with values for abs() close to 1
+        // These should be handled correctly.
+
+        // Change this to use a method based on glibc with detection of values of
+        // abs() close to 1 and switch to using log1p(abs - 1).
+
         // All ISO C99 edge cases satisfied by the Math library.
         // Make computation overflow safe.
 
@@ -2116,6 +2140,7 @@
 
         // Use the safe region defined for atanh to avoid over/underflow for x^2
         if (inRegion(x, y, SAFE_LOWER, SAFE_UPPER)) {
+            //return constructor.create(log.apply(abs()), arg());
             return constructor.create(0.5 * log.apply(x * x + y * y), arg());
         }