class ComplexMathUtils {

  public static ComplexNumber sqrt(final ComplexNumber z) {
    ArgumentChecker.notNull(z, "z");
    final double c = z.getReal();
    final double d = z.getImaginary();
    if (c == 0.0 && d == 0.0) {
      return z;
    }
    double w;
    if (Math.abs(c) > Math.abs(d)) {
      final double dOverC = d / c;
      w = Math.sqrt(Math.abs(c)) * Math.sqrt((1 + Math.sqrt(1 + dOverC * dOverC)) / 2);
    } else {
      final double cOverD = c / d;
      w = Math.sqrt(Math.abs(d)) * Math.sqrt((Math.abs(cOverD) + Math.sqrt(1 + cOverD * cOverD)) / 2);
    }
    if (c >= 0.0) {
      return new ComplexNumber(w, d / 2 / w);
    }
    if (d >= 0.0) {
      return new ComplexNumber(d / 2 / w, w);
    }
    return new ComplexNumber(-d / 2 / w, -w);
  }

}