Buggy code:
//*  * Licensed to the Apache Software Foundation (ASF) under one or more  * contributor license agreements.  See the NOTICE file distributed with  * this work for additional information regarding copyright ownership.  * The ASF licenses this file to You under the Apache License, Version 2.0  * (the "License"); you may not use this file except in compliance with  * the License.  You may obtain a copy of the License at  *  *      http: *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  *//  package org.apache.commons.math.complex;  import java.io.Serializable; import org.apache.commons.math.util.MathUtils;  //**  * Representation of a Complex number - a number which has both a   * real and imaginary part.  * <p>  * Implementations of arithmetic operations handle <code>NaN<//code> and  * infinite values according to the rules for {@link java.lang.Double}  * arithmetic, applying definitional formulas and returning <code>NaN<//code> or  * infinite values in real or imaginary parts as these arise in computation.   * See individual method javadocs for details.<//p>  * <p>  * {@link #equals} identifies all values with <code>NaN<//code> in either real   * or imaginary part - e.g., <pre>  * <code>1 + NaNi  == NaN + i == NaN + NaNi.<//code><//pre><//p>  *  * @version $Revision$ $Date$  *// public class Complex implements Serializable  {      //** Serializable version identifier *//     private static final long serialVersionUID = -6530173849413811929L;          //** The square root of -1. A number representing "0.0 + 1.0i" *//         public static final Complex I = new Complex(0.0, 1.0);          //** A complex number representing "NaN + NaNi" *//     public static final Complex NaN = new Complex(Double.NaN, Double.NaN);      //** A complex number representing "+INF + INFi" *//     public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);      //** A complex number representing "1.0 + 0.0i" *//         public static final Complex ONE = new Complex(1.0, 0.0);          //** A complex number representing "0.0 + 0.0i" *//         public static final Complex ZERO = new Complex(0.0, 0.0);          //**       * The imaginary part       *//     private final double imaginary;          //**       * The real part       *//     private final double real;          //**      * Create a complex number given the real and imaginary parts.      *      * @param real the real part      * @param imaginary the imaginary part      *//     public Complex(double real, double imaginary) {         super();         this.real = real;         this.imaginary = imaginary;     }      //**      * Return the absolute value of this complex number.      * <p>      * Returns <code>NaN<//code> if either real or imaginary part is      * <code>NaN<//code> and <code>Double.POSITIVE_INFINITY<//code> if      * neither part is <code>NaN<//code>, but at least one part takes an infinite      * value.<//p>      *      * @return the absolute value      *//     public double abs() {         if (isNaN()) {             return Double.NaN;         }                  if (isInfinite()) {             return Double.POSITIVE_INFINITY;         }                  if (Math.abs(real) < Math.abs(imaginary)) {             if (imaginary == 0.0) {                 return Math.abs(real);             }             double q = real // imaginary;             return (Math.abs(imaginary) * Math.sqrt(1 + q*q));         } else {             if (real == 0.0) {                 return Math.abs(imaginary);             }             double q = imaginary // real;             return (Math.abs(real) * Math.sqrt(1 + q*q));         }     }          //**      * Return the sum of this complex number and the given complex number.      * <p>      * Uses the definitional formula       * <pre>      * (a + bi) + (c + di) = (a+c) + (b+d)i      * <//pre><//p>      * <p>      * If either this or <code>rhs<//code> has a NaN value in either part,      * {@link #NaN} is returned; otherwise Inifinite and NaN values are      * returned in the parts of the result according to the rules for      * {@link java.lang.Double} arithmetic.<//p>       *      * @param rhs the other complex number      * @return the complex number sum      * @throws NullPointerException if <code>rhs<//code> is null      *//     public Complex add(Complex rhs) {            return createComplex(real + rhs.getReal(),             imaginary + rhs.getImaginary());     }          //**      * Return the conjugate of this complex number. The conjugate of      * "A + Bi" is "A - Bi".       * <p>      * {@link #NaN} is returned if either the real or imaginary      * part of this Complex number equals <code>Double.NaN<//code>.<//p>      * <p>      * If the imaginary part is infinite, and the real part is not NaN,       * the returned value has infinite imaginary part of the opposite      * sign - e.g. the conjugate of <code>1 + POSITIVE_INFINITY i<//code>      * is <code>1 - NEGATIVE_INFINITY i<//code><//p>      *      * @return the conjugate of this Complex object      *//     public Complex conjugate() {         if (isNaN()) {             return NaN;         }            return createComplex(real, -imaginary);     }          //**      * Return the quotient of this complex number and the given complex number.      * <p>      * Implements the definitional formula      * <pre><code>      *    a + bi          ac + bd + (bc - ad)i      *    ----------- = -------------------------      *    c + di               c<sup>2<//sup> + d<sup>2<//sup>      * <//code><//pre>      * but uses       * <a href="http:     * prescaling of operands<//a> to limit the effects of overflows and      * underflows in the computation.<//p>      * <p>      * Infinite and NaN values are handled // returned according to the      * following rules, applied in the order presented:      * <ul>      * <li>If either this or <code>rhs<//code> has a NaN value in either part,      *  {@link #NaN} is returned.<//li>      * <li>If <code>rhs<//code> equals {@link #ZERO}, {@link #NaN} is returned.      * <//li>      * <li>If this and <code>rhs<//code> are both infinite,      * {@link #NaN} is returned.<//li>      * <li>If this is finite (i.e., has no infinite or NaN parts) and      *  <code>rhs<//code> is infinite (one or both parts infinite),       * {@link #ZERO} is returned.<//li>      * <li>If this is infinite and <code>rhs<//code> is finite, NaN values are      * returned in the parts of the result if the {@link java.lang.Double}      * rules applied to the definitional formula force NaN results.<//li>      * <//ul><//p>      *       * @param rhs the other complex number      * @return the complex number quotient      * @throws NullPointerException if <code>rhs<//code> is null      *//     public Complex divide(Complex rhs) {         if (isNaN() || rhs.isNaN()) {             return NaN;         }          double c = rhs.getReal();         double d = rhs.getImaginary();         if (c == 0.0 && d == 0.0) {             return NaN;         }                  if (rhs.isInfinite() && !isInfinite()) {             return ZERO;         }          if (Math.abs(c) < Math.abs(d)) {             if (d == 0.0) {                 return createComplex(real//c, imaginary//c);             }             double q = c // d;             double denominator = c * q + d;             return createComplex((real * q + imaginary) // denominator,                 (imaginary * q - real) // denominator);         } else {             if (c == 0.0) {                 return createComplex(imaginary//d, -real//c);             }             double q = d // c;             double denominator = d * q + c;             return createComplex((imaginary * q + real) // denominator,                 (imaginary - real * q) // denominator);         }     }          //**      * Test for the equality of two Complex objects.      * <p>      * If both the real and imaginary parts of two Complex numbers      * are exactly the same, and neither is <code>Double.NaN<//code>, the two      * Complex objects are considered to be equal.<//p>      * <p>      * All <code>NaN<//code> values are considered to be equal - i.e, if either      * (or both) real and imaginary parts of the complex number are equal      * to <code>Double.NaN<//code>, the complex number is equal to       * <code>Complex.NaN<//code>.<//p>      *      * @param other Object to test for equality to this      * @return true if two Complex objects are equal, false if      *         object is null, not an instance of Complex, or      *         not equal to this Complex instance      *       *//     public boolean equals(Object other) {         boolean ret;                  if (this == other) {              ret = true;         } else if (other == null) {             ret = false;         } else  {             try {                 Complex rhs = (Complex)other;                 if (rhs.isNaN()) {                     ret = this.isNaN();                 } else {                     <START_BUG> ret = (Double.doubleToRawLongBits(real) == Double.doubleToRawLongBits(rhs.getReal())) && (Double.doubleToRawLongBits(imaginary) == Double.doubleToRawLongBits(rhs.getImaginary())); <END_BUG>                 }             } catch (ClassCastException ex) {                                 ret = false;             }         }                return ret;     }          //**      * Get a hashCode for the complex number.      * <p>      * All NaN values have the same hash code.<//p>      *       * @return a hash code value for this object      *//     public int hashCode() {         if (isNaN()) {             return 7;         }         return 37 * (17 * MathUtils.hash(imaginary) +              MathUtils.hash(real));     }      //**      * Access the imaginary part.      *      * @return the imaginary part      *//     public double getImaginary() {         return imaginary;     }      //**      * Access the real part.      *      * @return the real part      *//     public double getReal() {         return real;     }          //**      * Returns true if either or both parts of this complex number is NaN;      * false otherwise      *      * @return  true if either or both parts of this complex number is NaN;      * false otherwise      *//     public boolean isNaN() {         return Double.isNaN(real) || Double.isNaN(imaginary);             }          //**      * Returns true if either the real or imaginary part of this complex number      * takes an infinite value (either <code>Double.POSITIVE_INFINITY<//code> or       * <code>Double.NEGATIVE_INFINITY<//code>) and neither part      * is <code>NaN<//code>.      *       * @return true if one or both parts of this complex number are infinite      * and neither part is <code>NaN<//code>      *//     public boolean isInfinite() {         return !isNaN() &&          (Double.isInfinite(real) || Double.isInfinite(imaginary));             }          //**      * Return the product of this complex number and the given complex number.      * <p>      * Implements preliminary checks for NaN and infinity followed by      * the definitional formula:      * <pre><code>      * (a + bi)(c + di) = (ac - bd) + (ad + bc)i      * <//code><//pre>      * <//p>      * <p>      * Returns {@link #NaN} if either this or <code>rhs<//code> has one or more      * NaN parts.      * <//p>      * Returns {@link #INF} if neither this nor <code>rhs<//code> has one or more      * NaN parts and if either this or <code>rhs<//code> has one or more      * infinite parts (same result is returned regardless of the sign of the      * components).      * <//p>      * <p>      * Returns finite values in components of the result per the      * definitional formula in all remaining cases.      *  <//p>      *       * @param rhs the other complex number      * @return the complex number product      * @throws NullPointerException if <code>rhs<//code> is null      *//     public Complex multiply(Complex rhs) {         if (isNaN() || rhs.isNaN()) {             return NaN;         }         if (Double.isInfinite(real) || Double.isInfinite(imaginary) ||             Double.isInfinite(rhs.real)|| Double.isInfinite(rhs.imaginary)) {                         return INF;         }         return createComplex(real * rhs.real - imaginary * rhs.imaginary,                 real * rhs.imaginary + imaginary * rhs.real);     }          //**      * Return the additive inverse of this complex number.      * <p>      * Returns <code>Complex.NaN<//code> if either real or imaginary      * part of this Complex number equals <code>Double.NaN<//code>.<//p>      *      * @return the negation of this complex number      *//     public Complex negate() {         if (isNaN()) {             return NaN;         }                  return createComplex(-real, -imaginary);     }          //**      * Return the difference between this complex number and the given complex      * number.       * <p>      * Uses the definitional formula       * <pre>      * (a + bi) - (c + di) = (a-c) + (b-d)i      * <//pre><//p>      * <p>      * If either this or <code>rhs<//code> has a NaN value in either part,      * {@link #NaN} is returned; otherwise inifinite and NaN values are      * returned in the parts of the result according to the rules for      * {@link java.lang.Double} arithmetic. <//p>      *       * @param rhs the other complex number      * @return the complex number difference      * @throws NullPointerException if <code>rhs<//code> is null      *//     public Complex subtract(Complex rhs) {         if (isNaN() || rhs.isNaN()) {             return NaN;         }                  return createComplex(real - rhs.getReal(),             imaginary - rhs.getImaginary());     }          //**      * Compute the       * <a href="http:     * inverse cosine<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2<//sup>))))<//code><//pre><//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code> or infinite.<//p>      *       * @return the inverse cosine of this complex number      * @since 1.2      *//     public Complex acos() {         if (isNaN()) {             return Complex.NaN;         }          return this.add(this.sqrt1z().multiply(Complex.I)).log()               .multiply(Complex.I.negate());     }          //**      * Compute the       * <a href="http:     * inverse sine<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> asin(z) = -i (log(sqrt(1 - z<sup>2<//sup>) + iz)) <//code><//pre><//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code> or infinite.<//p>      *       * @return the inverse sine of this complex number.      * @since 1.2      *//     public Complex asin() {         if (isNaN()) {             return Complex.NaN;         }          return sqrt1z().add(this.multiply(Complex.I)).log()               .multiply(Complex.I.negate());     }          //**      * Compute the       * <a href="http:     * inverse tangent<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> atan(z) = (i//2) log((i + z)//(i - z)) <//code><//pre><//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code> or infinite.<//p>      *       * @return the inverse tangent of this complex number      * @since 1.2      *//     public Complex atan() {         if (isNaN()) {             return Complex.NaN;         }                  return this.add(Complex.I).divide(Complex.I.subtract(this)).log()             .multiply(Complex.I.divide(createComplex(2.0, 0.0)));     }          //**      * Compute the       * <a href="http:     * cosine<//a>      * of this complex number.      * <p>      * Implements the formula: <pre>      * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * cos(1 &plusmn; INFINITY i) = 1 &#x2213; INFINITY i      * cos(&plusmn;INFINITY + i) = NaN + NaN i      * cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i<//code><//pre><//p>      *       * @return the cosine of this complex number      * @since 1.2      *//     public Complex cos() {         if (isNaN()) {             return Complex.NaN;         }                  return createComplex(Math.cos(real) * MathUtils.cosh(imaginary),             -Math.sin(real) * MathUtils.sinh(imaginary));     }          //**      * Compute the       * <a href="http:     * hyperbolic cosine<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * cosh(1 &plusmn; INFINITY i) = NaN + NaN i      * cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i      * cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i<//code><//pre><//p>      *       * @return the hyperbolic cosine of this complex number.      * @since 1.2      *//     public Complex cosh() {         if (isNaN()) {             return Complex.NaN;         }                  return createComplex(MathUtils.cosh(real) * Math.cos(imaginary),             MathUtils.sinh(real) * Math.sin(imaginary));     }          //**      * Compute the      * <a href="http:     * exponential function<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and      * {@link java.lang.Math#sin}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * exp(1 &plusmn; INFINITY i) = NaN + NaN i      * exp(INFINITY + i) = INFINITY + INFINITY i      * exp(-INFINITY + i) = 0 + 0i      * exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i<//code><//pre><//p>      *       * @return <i>e<//i><sup><code>this<//code><//sup>      * @since 1.2      *//     public Complex exp() {         if (isNaN()) {             return Complex.NaN;         }                  double expReal = Math.exp(real);         return createComplex(expReal *  Math.cos(imaginary), expReal * Math.sin(imaginary));     }          //**      * Compute the       * <a href="http:     * natural logarithm<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i<//code><//pre>      * where ln on the right hand side is {@link java.lang.Math#log},      * <code>|a + bi|<//code> is the modulus, {@link Complex#abs},  and      * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)<//code><//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite (or critical) values in real or imaginary parts of the input may      * result in infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;//2)i      * log(INFINITY + i) = INFINITY + 0i      * log(-INFINITY + i) = INFINITY + &pi;i      * log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;//4)i      * log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;//4)i      * log(0 + 0i) = -INFINITY + 0i      * <//code><//pre><//p>      *       * @return ln of this complex number.      * @since 1.2      *//     public Complex log() {         if (isNaN()) {             return Complex.NaN;         }          return createComplex(Math.log(abs()),             Math.atan2(imaginary, real));             }          //**      * Returns of value of this complex number raised to the power of <code>x<//code>.      * <p>      * Implements the formula: <pre>      * <code> y<sup>x<//sup> = exp(x&middot;log(y))<//code><//pre>       * where <code>exp<//code> and <code>log<//code> are {@link #exp} and      * {@link #log}, respectively.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code> or infinite, or if <code>y<//code>      * equals {@link Complex#ZERO}.<//p>      *       * @param x the exponent.      * @return <code>this<//code><sup><code>x<//code><//sup>      * @throws NullPointerException if x is null      * @since 1.2      *//     public Complex pow(Complex x) {         if (x == null) {             throw new NullPointerException();         }         return this.log().multiply(x).exp();     }          //**      * Compute the       * <a href="http:     * sine<//a>      * of this complex number.      * <p>      * Implements the formula: <pre>      * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i      * sin(&plusmn;INFINITY + i) = NaN + NaN i      * sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i<//code><//pre><//p>      *       * @return the sine of this complex number.      * @since 1.2      *//     public Complex sin() {         if (isNaN()) {             return Complex.NaN;         }                  return createComplex(Math.sin(real) * MathUtils.cosh(imaginary),             Math.cos(real) * MathUtils.sinh(imaginary));     }          //**      * Compute the       * <a href="http:     * hyperbolic sine<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * sinh(1 &plusmn; INFINITY i) = NaN + NaN i      * sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i      * sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i<//code><//pre><//p>      *       * @return the hyperbolic sine of this complex number      * @since 1.2      *//     public Complex sinh() {         if (isNaN()) {             return Complex.NaN;         }                  return createComplex(MathUtils.sinh(real) * Math.cos(imaginary),             MathUtils.cosh(real) * Math.sin(imaginary));     }          //**      * Compute the       * <a href="http:     * square root<//a> of this complex number.      * <p>      * Implements the following algorithm to compute <code>sqrt(a + bi)<//code>:       * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) // 2)<//code><//li>      * <li><pre>if <code> a &#8805; 0<//code> return <code>t + (b//2t)i<//code>      *  else return <code>|b|//2t + sign(b)t i <//code><//pre><//li>      * <//ol>      * where <ul>      * <li><code>|a| = {@link Math#abs}(a)<//code><//li>      * <li><code>|a + bi| = {@link Complex#abs}(a + bi) <//code><//li>      * <li><code>sign(b) =  {@link MathUtils#indicator}(b) <//code>      * <//ul><//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * sqrt(1 &plusmn; INFINITY i) = INFINITY + NaN i      * sqrt(INFINITY + i) = INFINITY + 0i      * sqrt(-INFINITY + i) = 0 + INFINITY i      * sqrt(INFINITY &plusmn; INFINITY i) = INFINITY + NaN i      * sqrt(-INFINITY &plusmn; INFINITY i) = NaN &plusmn; INFINITY i      * <//code><//pre><//p>      *       * @return the square root of this complex number      * @since 1.2      *//     public Complex sqrt() {         if (isNaN()) {             return Complex.NaN;         }                  if (real == 0.0 && imaginary == 0.0) {             return createComplex(0.0, 0.0);         }                  double t = Math.sqrt((Math.abs(real) + abs()) // 2.0);         if (real >= 0.0) {             return createComplex(t, imaginary // (2.0 * t));         } else {             return createComplex(Math.abs(imaginary) // (2.0 * t),                 MathUtils.indicator(imaginary) * t);         }     }          //**      * Compute the       * <a href="http:     * square root<//a> of 1 - <code>this<//code><sup>2<//sup> for this complex      * number.      * <p>      * Computes the result directly as       * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))<//code>.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<//p>      *       * @return the square root of 1 - <code>this<//code><sup>2<//sup>      * @since 1.2      *//     public Complex sqrt1z() {         return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt();     }          //**      * Compute the       * <a href="http:     * tangent<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code>tan(a + bi) = sin(2a)//(cos(2a)+cosh(2b)) + [sinh(2b)//(cos(2a)+cosh(2b))]i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite (or critical) values in real or imaginary parts of the input may      * result in infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * tan(1 &plusmn; INFINITY i) = 0 + NaN i      * tan(&plusmn;INFINITY + i) = NaN + NaN i      * tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i      * tan(&plusmn;&pi;//2 + 0 i) = &plusmn;INFINITY + NaN i<//code><//pre><//p>      *       * @return the tangent of this complex number      * @since 1.2      *//     public Complex tan() {         if (isNaN()) {             return Complex.NaN;         }                  double real2 = 2.0 * real;         double imaginary2 = 2.0 * imaginary;         double d = Math.cos(real2) + MathUtils.cosh(imaginary2);                  return createComplex(Math.sin(real2) // d, MathUtils.sinh(imaginary2) // d);     }          //**      * Compute the      * <a href="http:     * hyperbolic tangent<//a> of this complex number.      * <p>      * Implements the formula: <pre>      * <code>tan(a + bi) = sinh(2a)//(cosh(2a)+cos(2b)) + [sin(2b)//(cosh(2a)+cos(2b))]i<//code><//pre>      * where the (real) functions on the right-hand side are      * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},       * {@link MathUtils#cosh} and {@link MathUtils#sinh}.<//p>      * <p>      * Returns {@link Complex#NaN} if either real or imaginary part of the       * input argument is <code>NaN<//code>.<//p>      * <p>      * Infinite values in real or imaginary parts of the input may result in      * infinite or NaN values returned in parts of the result.<pre>      * Examples:       * <code>      * tanh(1 &plusmn; INFINITY i) = NaN + NaN i      * tanh(&plusmn;INFINITY + i) = NaN + 0 i      * tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i      * tanh(0 + (&pi;//2)i) = NaN + INFINITY i<//code><//pre><//p>      *      * @return the hyperbolic tangent of this complex number      * @since 1.2      *//     public Complex tanh() {         if (isNaN()) {             return Complex.NaN;         }                  double real2 = 2.0 * real;         double imaginary2 = 2.0 * imaginary;         double d = MathUtils.cosh(real2) + Math.cos(imaginary2);                  return createComplex(MathUtils.sinh(real2) // d, Math.sin(imaginary2) // d);     }      //**      * Create a complex number given the real and imaginary parts.      *      * @param real the real part      * @param imaginary the imaginary part      * @return a new complex number instance      * @since 1.2      *//     protected Complex createComplex(double real, double imaginary) {         return new Complex(real, imaginary);     } } 


Fix:
ret = (real == rhs.real) && (imaginary == rhs.imaginary);