Simplify sinh, cosh and tanh
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 bc91838..a126040 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
@@ -1932,56 +1932,22 @@
      * @return the hyperbolic cosine of the complex number
      */
     private static Complex cosh(double real, double imaginary, ComplexConstructor constructor) {
-        if (Double.isFinite(real)) {
-            if (Double.isFinite(imaginary)) {
-                return constructor.create(Math.cosh(real) * Math.cos(imaginary),
-                                          Math.sinh(real) * Math.sin(imaginary));
-            }
-            // ISO C99: Preserve the even function by mapping to positive
-            // f(z) = f(-z)
-            double re;
-            double im;
-            if (negative(real)) {
-                re = -real;
-                im = -imaginary;
-            } else {
-                re = real;
-                im = imaginary;
-            }
-            // Special case for real == 0
-            return constructor.create(Double.NaN,
-                                      re == 0 ? Math.copySign(0, im) : Double.NaN);
+        // ISO C99: Preserve the even function by mapping to positive
+        // f(z) = f(-z)
+        if (Double.isInfinite(real) && !Double.isFinite(imaginary)) {
+            return constructor.create(Math.abs(real), Double.NaN);
         }
-        if (Double.isInfinite(real)) {
-            if (Double.isFinite(imaginary)) {
-                if (imaginary == 0) {
-                    // Determine sign
-                    final double im = real > 0 ? imaginary : -imaginary;
-                    return constructor.create(Double.POSITIVE_INFINITY, im);
-                }
-                // inf * cis(y)
-                // ISO C99: Preserve the even function
-                // f(z) = f(-z)
-                double re;
-                double im;
-                if (real < 0) {
-                    re = -real;
-                    im = -imaginary;
-                } else {
-                    re = real;
-                    im = imaginary;
-                }
-                return constructor.create(re * Math.cos(im), re * Math.sin(im));
-            }
-            // imaginary is infinite or NaN
-            return constructor.create(Double.POSITIVE_INFINITY, Double.NaN);
+        if (real == 0 && !Double.isFinite(imaginary)) {
+            return constructor.create(Double.NaN, changeSign(real, imaginary));
         }
-        // real is NaN
-        if (imaginary == 0) {
-            return constructor.create(Double.NaN, imaginary);
+        if (real == 0 && imaginary == 0) {
+            return constructor.create(1, changeSign(real, imaginary));
         }
-        // optionally raises the ‘‘invalid’’ floating-point exception, for nonzero y.
-        return NAN;
+        if (imaginary == 0 && !Double.isFinite(real)) {
+            return constructor.create(Math.abs(real), changeSign(imaginary, real));
+        }
+        return constructor.create(Math.cosh(real) * Math.cos(imaginary),
+                                  Math.sinh(real) * Math.sin(imaginary));
     }
 
     /**
@@ -2008,7 +1974,7 @@
                     im = Math.copySign(1, im);
                 }
             } else {
-                if (im == 0 || !Double.isFinite(im)){
+                if (im == 0 || !Double.isFinite(im)) {
                     return Double.isInfinite(im) ?
                         new Complex(real, Double.NaN) :
                         this;
@@ -2236,41 +2202,15 @@
      * @return the hyperbolic sine of the complex number
      */
     private static Complex sinh(double real, double imaginary, ComplexConstructor constructor) {
-        if (Double.isFinite(real)) {
-            if (Double.isFinite(imaginary)) {
-                return constructor.create(Math.sinh(real) * Math.cos(imaginary),
-                                          Math.cosh(real) * Math.sin(imaginary));
-            }
-            // Special case for real == 0
-            final double re = real == 0 ? real : Double.NaN;
-            return constructor.create(re, Double.NaN);
+        if ((Double.isInfinite(real) && !Double.isFinite(imaginary)) ||
+            (real == 0 && !Double.isFinite(imaginary))) {
+            return constructor.create(real, Double.NaN);
         }
-        if (Double.isInfinite(real)) {
-            if (Double.isFinite(imaginary)) {
-                if (imaginary == 0) {
-                    return constructor.create(real, imaginary);
-                }
-                // inf * cis(y)
-                // ISO C99: Preserve the equality
-                // sinh(conj(z)) = conj(sinh(z))
-                // and the odd function: f(z) = -f(-z)
-                // by always computing on a positive valued Complex number.
-                // Math.cos(-x) == Math.cos(x) so ignore sign transform.
-                final double signIm = imaginary < 0 ? -1 : 1;
-                final double re = Double.POSITIVE_INFINITY * Math.cos(imaginary);
-                final double im = Double.POSITIVE_INFINITY * Math.sin(imaginary * signIm);
-                // Transform back
-                return constructor.create(real < 0 ? -re : re, im * signIm);
-            }
-            // imaginary is infinite or NaN
-            return constructor.create(Double.POSITIVE_INFINITY, Double.NaN);
+        if (imaginary == 0 && !Double.isFinite(real)) {
+            return constructor.create(real, imaginary);
         }
-        // real is NaN
-        if (imaginary == 0) {
-            return constructor.create(Double.NaN, Math.copySign(0, imaginary));
-        }
-        // optionally raises the ‘‘invalid’’ floating-point exception, for nonzero y.
-        return NAN;
+        return constructor.create(Math.sinh(real) * Math.cos(imaginary),
+                                  Math.cosh(real) * Math.sin(imaginary));
     }
 
     /**
@@ -2438,42 +2378,6 @@
      * @return the hyperbolic tangent of the complex number
      */
     private static Complex tanh(double real, double imaginary, ComplexConstructor constructor) {
-        // Math.cos and Math.sin return NaN for infinity.
-        // Perform edge-condition checks on twice the imaginary value.
-        // This handles very big imaginary numbers as infinite.
-
-        if (Double.isFinite(real)) {
-            if (Double.isFinite(imaginary)) {
-                if (real == 0) {
-                    // Identity: sin x / (1 + cos x) = tan(x/2)
-                    return constructor.create(real, Math.tan(imaginary));
-                }
-                if (imaginary == 0) {
-                    // Identity: sinh x / (1 + cosh x) = tanh(x/2)
-                    return constructor.create(Math.tanh(real), imaginary);
-                }
-
-                final double real2 = 2 * real;
-
-                // Math.cosh returns positive infinity for infinity.
-                // cosh -> inf
-                final double divisor = Math.cosh(real2) + cos2(imaginary);
-
-                // Math.sinh returns the input infinity for infinity.
-                // sinh -> inf for positive x; else -inf
-                final double sinhRe2 = Math.sinh(real2);
-
-                // Avoid inf / inf
-                if (Double.isInfinite(sinhRe2) && Double.isInfinite(divisor)) {
-                    // Handle as if real was infinite
-                    return constructor.create(Math.copySign(1, real), Math.copySign(0, sin2(imaginary)));
-                }
-                return constructor.create(sinhRe2 / divisor,
-                                          sin2(imaginary) / divisor);
-            }
-            // imaginary is infinite or NaN
-            return NAN;
-        }
         if (Double.isInfinite(real)) {
             if (Double.isFinite(imaginary)) {
                 return constructor.create(Math.copySign(1, real), Math.copySign(0, sin2(imaginary)));
@@ -2481,12 +2385,39 @@
             // imaginary is infinite or NaN
             return constructor.create(Math.copySign(1, real), Math.copySign(0, imaginary));
         }
-        // real is NaN
-        if (imaginary == 0) {
-            return constructor.create(Double.NaN, Math.copySign(0, imaginary));
+
+        if (real == 0) {
+            if (Double.isFinite(imaginary)) {
+                // Identity: sin x / (1 + cos x) = tan(x/2)
+                return constructor.create(real, Math.tan(imaginary));
+            }
+            return constructor.create(Double.NaN, Double.NaN);
         }
-        // optionally raises the ‘‘invalid’’ floating-point exception, for nonzero y.
-        return NAN;
+        if (imaginary == 0) {
+            if (Double.isNaN(real)) {
+                return constructor.create(Double.NaN, imaginary);
+            }
+            // Identity: sinh x / (1 + cosh x) = tanh(x/2)
+            return constructor.create(Math.tanh(real), imaginary);
+        }
+
+        final double real2 = 2 * real;
+
+        // Math.cosh returns positive infinity for infinity.
+        // cosh -> inf
+        final double divisor = Math.cosh(real2) + cos2(imaginary);
+
+        // Math.sinh returns the input infinity for infinity.
+        // sinh -> inf for positive x; else -inf
+        final double sinhRe2 = Math.sinh(real2);
+
+        // Avoid inf / inf
+        if (Double.isInfinite(sinhRe2) && Double.isInfinite(divisor)) {
+            // Handle as if real was infinite
+            return constructor.create(Math.copySign(1, real), Math.copySign(0, imaginary));
+        }
+        return constructor.create(sinhRe2 / divisor,
+                                  sin2(imaginary) / divisor);
     }
 
     /**