diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 36623f3..d97b4ac 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,8 +11,8 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        elixir: ["1.12.0"]
-        otp: ["24.0"]
+        elixir: ["1.18.0"]
+        otp: ["27.0"]
     env:
       MIX_ENV: test
     steps:
@@ -22,7 +22,7 @@ jobs:
           otp-version: ${{ matrix.otp }}
           elixir-version: ${{ matrix.elixir }}
       - name: Retrieve dependencies cache
-        uses: actions/cache@v1
+        uses: actions/cache@v4
         id: mix-cache # id to use in retrieve action
         with:
           path: deps
@@ -42,8 +42,8 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        elixir: ["1.12.0"]
-        otp: ["24.0"]
+        elixir: ["1.18.0"]
+        otp: ["27.0"]
     env:
       MIX_ENV: test
     steps:
@@ -57,7 +57,7 @@ jobs:
           otp-version: ${{ matrix.otp }}
           elixir-version: ${{ matrix.elixir }}
       - name: Retrieve dependencies cache
-        uses: actions/cache@v1
+        uses: actions/cache@v4
         id: mix-cache # id to use in retrieve action
         with:
           path: deps
diff --git a/lib/complex.ex b/lib/complex.ex
index 8542a29..4c48d39 100644
--- a/lib/complex.ex
+++ b/lib/complex.ex
@@ -389,6 +389,12 @@ defmodule Complex do
   @spec add(t | number | non_finite_number, t | number | non_finite_number) ::
           t | number | non_finite_number
 
+  def add(z, %Complex{re: re, im: im}) when z in [:infinity, :neg_infinity, :nan],
+    do: Complex.new(add(z, re), im)
+
+  def add(%Complex{re: re, im: im}, z) when z in [:infinity, :neg_infinity, :nan],
+    do: Complex.new(add(z, re), im)
+
   def add(:nan, _), do: :nan
   def add(_, :nan), do: :nan
 
@@ -431,6 +437,12 @@ defmodule Complex do
   @spec subtract(t | number | non_finite_number, t | number | non_finite_number) ::
           t | number | non_finite_number
 
+  def subtract(z, %Complex{re: re, im: im}) when z in [:infinity, :neg_infinity, :nan],
+    do: Complex.new(subtract(z, re), negate(im))
+
+  def subtract(%Complex{re: re, im: im}, z) when z in [:infinity, :neg_infinity, :nan],
+    do: Complex.new(subtract(re, z), im)
+
   def subtract(:nan, _), do: :nan
   def subtract(_, :nan), do: :nan
   def subtract(:infinity, :infinity), do: :nan
@@ -472,12 +484,22 @@ defmodule Complex do
       %Complex{im: 6.0, re: 3.0}
 
       iex> Complex.multiply(-2, Complex.new(:infinity, :neg_infinity))
-      %Complex{im: :infinity, re: :neg_infinity}
+      %Complex{im: :nan, re: :nan}
 
   """
   @spec multiply(t | number | non_finite_number, t | number | non_finite_number) ::
           t | number | non_finite_number
 
+  def multiply(x, c = %Complex{re: _re, im: _im}) when is_non_finite_number(x) or is_number(x) do
+    z = new(x, 0)
+    multiply(z, c)
+  end
+
+  def multiply(c = %Complex{re: _re, im: _im}, x) when is_non_finite_number(x) or is_number(x) do
+    z = new(x, 0)
+    multiply(c, z)
+  end
+
   def multiply(:infinity, right) when is_number(right) and right > 0, do: :infinity
   def multiply(:infinity, right) when right == 0, do: :nan
   def multiply(:infinity, right) when is_number(right) and right < 0, do: :neg_infinity
@@ -500,28 +522,6 @@ defmodule Complex do
   def multiply(:infinity, :neg_infinity), do: :neg_infinity
   def multiply(:infinity, :infinity), do: :infinity
 
-  def multiply(x, %Complex{re: re, im: im}) when is_non_finite_number(x) or is_number(x) do
-    new(multiply(re, x), multiply(im, x))
-  end
-
-  def multiply(%Complex{re: re, im: im}, x) when is_non_finite_number(x) or is_number(x) do
-    new(multiply(re, x), multiply(im, x))
-  end
-
-  def multiply(%Complex{re: re_l, im: im_l}, %Complex{re: re_r, im: im_r}) when im_r == 0 do
-    new(multiply(re_r, re_l), multiply(re_r, im_l))
-  end
-
-  def multiply(%Complex{re: re_l, im: im_l}, %Complex{re: re_r, im: im_r}) when re_r == 0 do
-    re_result =
-      case multiply(im_l, im_r) do
-        result when result == 0 -> 0
-        result -> negate(result)
-      end
-
-    new(re_result, multiply(re_l, im_r))
-  end
-
   def multiply(left, right) when is_number(left) and is_number(right), do: left * right
 
   def multiply(left, right) do
@@ -569,33 +569,43 @@ defmodule Complex do
   def divide(x, y) when is_non_finite_number(x) and is_non_finite_number(y), do: :nan
   def divide(x, y) when is_non_finite_number(x) and is_number(y) and y >= 0, do: x
   def divide(x, y) when x == 0 and y == 0, do: :nan
-  def divide(:nan, _), do: :nan
-  def divide(_, :nan), do: :nan
+  def divide(:nan, a) when is_number(a), do: :nan
+  def divide(a, :nan) when is_number(a), do: :nan
   def divide(:infinity, y) when is_number(y) and y < 0, do: :neg_infinity
   def divide(:neg_infinity, y) when is_number(y) and y < 0, do: :infinity
-  def divide(_, :infinity), do: 0
-  def divide(_, :neg_infinity), do: 0
+  def divide(a, :infinity) when is_number(a), do: 0
+  def divide(a, :neg_infinity) when is_number(a), do: 0
 
   def divide(x, y) when is_number(x) and is_number(y), do: x / y
 
+  def divide(n, b) when is_number(n) and b in [:infinity, :neg_infinity] do
+    0
+  end
+
+  def divide(n, %Complex{re: re_r, im: im_r})
+      when is_number(n) and re_r in [:infinity, :neg_infinity] and im_r == 0 do
+    new(0, 0)
+  end
+
+  def divide(%Complex{re: re, im: im}, b)
+      when is_number(re) and is_number(im) and b in [:infinity, :neg_infinity] do
+    new(0, 0)
+  end
+
+  def divide(%Complex{re: re, im: im}, %Complex{re: re_r, im: im_r})
+      when is_number(re) and is_number(im) and re_r in [:infinity, :neg_infinity] and im_r == 0 do
+    new(0, 0)
+  end
+
   def divide(x, y) do
     %Complex{re: r1, im: i1} = as_complex(x)
     %Complex{re: r2, im: i2} = as_complex(y)
 
-    cond do
-      i2 == 0 ->
-        new(divide(r1, r2), divide(i1, r2))
-
-      r2 == 0 ->
-        new(divide(i1, i2), negate(divide(r1, i2)))
-
-      true ->
-        num_re = add(multiply(r1, r2), multiply(i1, i2))
-        num_im = subtract(multiply(i1, r2), multiply(r1, i2))
-        den = add(square(r2), square(i2))
+    num_re = add(multiply(r1, r2), multiply(i1, i2))
+    num_im = subtract(multiply(i1, r2), multiply(r1, i2))
+    den = add(square(r2), square(i2))
 
-        new(divide(num_re, den), divide(num_im, den))
-    end
+    new(divide(num_re, den), divide(num_im, den))
   end
 
   @doc """
@@ -939,13 +949,49 @@ defmodule Complex do
   def log10(z)
 
   def log10(:infinity), do: :infinity
-  def log10(:neg_infinity), do: divide(log(:neg_infinity), :math.log(10))
+
+  def log10(:neg_infinity) do
+    new(:infinity, :math.pi() / :math.log(10))
+  end
+
   def log10(:nan), do: :nan
   def log10(n) when is_number(n) and n == 0, do: :neg_infinity
   def log10(n) when is_number(n) and n < 0, do: :nan
 
   def log10(n) when is_number(n), do: :math.log10(n)
 
+  def log10(%Complex{re: :infinity, im: im}) when is_number(im) do
+    new(:infinity, 0)
+  end
+
+  def log10(%Complex{re: :neg_infinity, im: im}) when is_number(im) do
+    new(:infinity, :math.pi() / :math.log(10))
+  end
+
+  def log10(%Complex{im: :infinity, re: re}) when is_number(re) do
+    new(:infinity, :math.pi() / (2 * :math.log(10)))
+  end
+
+  def log10(%Complex{im: :neg_infinity, re: re}) when is_number(re) do
+    new(:infinity, -:math.pi() / (2 * :math.log(10)))
+  end
+
+  def log10(%Complex{re: :infinity, im: :infinity}) do
+    new(:infinity, :math.pi() / (4 * :math.log(10)))
+  end
+
+  def log10(%Complex{re: :infinity, im: :neg_infinity}) do
+    new(:infinity, -:math.pi() / (4 * :math.log(10)))
+  end
+
+  def log10(%Complex{re: :neg_infinity, im: :neg_infinity}) do
+    new(:infinity, -3 * :math.pi() / (4 * :math.log(10)))
+  end
+
+  def log10(%Complex{re: :neg_infinity, im: :infinity}) do
+    new(:infinity, 3 * :math.pi() / (4 * :math.log(10)))
+  end
+
   def log10(z = %Complex{}) do
     divide(log(z), new(:math.log(10.0), 0.0))
   end
@@ -975,6 +1021,38 @@ defmodule Complex do
 
   def log2(n) when is_number(n), do: :math.log2(n)
 
+  def log2(%Complex{re: :infinity, im: im}) when is_number(im) do
+    new(:infinity, 0)
+  end
+
+  def log2(%Complex{re: :neg_infinity, im: im}) when is_number(im) do
+    new(:infinity, :math.pi() / :math.log(2))
+  end
+
+  def log2(%Complex{im: :infinity, re: re}) when is_number(re) do
+    new(:infinity, :math.pi() / (2 * :math.log(2)))
+  end
+
+  def log2(%Complex{im: :neg_infinity, re: re}) when is_number(re) do
+    new(:infinity, -:math.pi() / (2 * :math.log(2)))
+  end
+
+  def log2(%Complex{re: :infinity, im: :infinity}) do
+    new(:infinity, :math.pi() / (4 * :math.log(2)))
+  end
+
+  def log2(%Complex{re: :infinity, im: :neg_infinity}) do
+    new(:infinity, -:math.pi() / (4 * :math.log(2)))
+  end
+
+  def log2(%Complex{re: :neg_infinity, im: :neg_infinity}) do
+    new(:infinity, -3 * :math.pi() / (4 * :math.log(2)))
+  end
+
+  def log2(%Complex{re: :neg_infinity, im: :infinity}) do
+    new(:infinity, 3 * :math.pi() / (4 * :math.log(2)))
+  end
+
   def log2(z = %Complex{}) do
     divide(log(z), new(:math.log(2.0), 0.0))
   end
@@ -996,6 +1074,18 @@ defmodule Complex do
   @spec pow(t | non_finite_number | number, t | non_finite_number | number) ::
           t | non_finite_number | number
 
+  def pow(%Complex{re: re, im: im}, :infinity) when re == 0 and im == 0, do: new(0, 0)
+
+  def pow(%Complex{re: re, im: im}, %Complex{re: :infinity, im: im_r})
+      when re == 0 and im == 0 and im_r == 0,
+      do: new(0, 0)
+
+  def pow(z, %Complex{}) when is_non_finite_number(z), do: new(:nan, :nan)
+  def pow(%Complex{}, z) when is_non_finite_number(z), do: new(:nan, :nan)
+  def pow(%Complex{re: z}, _) when is_non_finite_number(z), do: new(:nan, :nan)
+  def pow(%Complex{im: z}, _) when is_non_finite_number(z), do: new(:nan, :nan)
+  def pow(_, %Complex{re: z}) when is_non_finite_number(z), do: new(:nan, :nan)
+  def pow(_, %Complex{im: z}) when is_non_finite_number(z), do: new(:nan, :nan)
   def pow(:nan, _), do: :nan
   def pow(_, :nan), do: :nan
 
@@ -1015,9 +1105,8 @@ defmodule Complex do
   def pow(:neg_infinity, y) when is_number(y) and y < 0, do: 0
 
   def pow(x, :infinity) when x == 0, do: 0
-  def pow(%Complex{re: re, im: im}, :infinity) when re == 0 and im == 0, do: 0
   def pow(x, :neg_infinity) when x == 0, do: :infinity
-  def pow(%Complex{re: re, im: im}, :neg_infinity) when re == 0 and im == 0, do: :infinity
+  def pow(%Complex{re: re, im: im}, :neg_infinity) when re == 0 and im == 0, do: new(:infinity, 0)
   def pow(_, :neg_infinity), do: 0
   def pow(_, :infinity), do: :infinity
 
@@ -1308,14 +1397,16 @@ defmodule Complex do
   def atan2(:infinity, :infinity), do: :math.pi() / 4
   def atan2(:infinity, :neg_infinity), do: 3 * :math.pi() / 4
   def atan2(:infinity, :nan), do: :nan
-  def atan2(:infinity, _), do: :math.pi() / 2
+  def atan2(:infinity, a) when is_number(a), do: :math.pi() / 2
   def atan2(:neg_infinity, :infinity), do: -:math.pi() / 4
   def atan2(:neg_infinity, :neg_infinity), do: -3 * :math.pi() / 4
   def atan2(:neg_infinity, :nan), do: :nan
-  def atan2(:neg_infinity, _), do: -:math.pi() / 2
-  def atan2(:nan, _), do: :nan
-  def atan2(_, :infinity), do: 0
-  def atan2(_, :neg_infinity), do: :math.pi()
+  def atan2(:neg_infinity, a) when is_number(a), do: -:math.pi() / 2
+  def atan2(:nan, a) when is_number(a) or is_non_finite_number(a), do: :nan
+  def atan2(a, :nan) when is_number(a) or is_non_finite_number(a), do: :nan
+  def atan2(:nan, :nan), do: :nan
+  def atan2(a, :infinity) when is_number(a), do: 0
+  def atan2(a, :neg_infinity) when is_number(a), do: :math.pi()
 
   def atan2(b, a) do
     a = as_complex(a)
@@ -1416,7 +1507,7 @@ defmodule Complex do
   ### Examples
 
       iex> Complex.asec(Complex.from_polar(2,:math.pi))
-      %Complex{im: 0.0, re: 2.0943951023931957}
+      %Complex{im: -0.0, re: 2.0943951023931957}
 
       iex> Complex.sec(Complex.asec(Complex.new(2,3)))
       %Complex{im: 2.9999999999999982, re: 1.9999999999999987}
diff --git a/test/complex_test.exs b/test/complex_test.exs
index 9e7cd62..5c66c8c 100644
--- a/test/complex_test.exs
+++ b/test/complex_test.exs
@@ -169,27 +169,22 @@ defmodule ComplexTest do
       assert Complex.divide(x, 0) == x
       assert Complex.divide(x, 1) == x
 
-      if y == :nan do
-        assert Complex.divide(Complex.new(x), Complex.new(y)) == Complex.new(:nan, :nan)
-      else
-        assert Complex.divide(Complex.new(x), Complex.new(y)) == Complex.new(:nan)
-      end
-
-      assert Complex.divide(Complex.new(x), 0) == Complex.new(x, :nan)
-      assert Complex.divide(Complex.new(x), 1) == Complex.new(x)
+      assert Complex.divide(Complex.new(x), Complex.new(y)) == Complex.new(:nan, :nan)
+      assert Complex.divide(Complex.new(x), 0) == Complex.new(:nan, :nan)
+      assert Complex.divide(Complex.new(x), 1) == Complex.new(x, :nan)
     end
 
     assert Complex.divide(:nan, 1) == :nan
     assert Complex.divide(1, :nan) == :nan
 
-    assert Complex.divide(Complex.new(:nan), 1) == Complex.new(:nan, 0)
+    assert Complex.divide(Complex.new(:nan), 1) == Complex.new(:nan, :nan)
     assert Complex.divide(1, Complex.new(:nan)) == Complex.new(:nan, :nan)
 
     assert Complex.divide(:infinity, -1) == :neg_infinity
     assert Complex.divide(:neg_infinity, -1) == :infinity
 
-    assert Complex.divide(Complex.new(:infinity), -1) == Complex.new(:neg_infinity, 0)
-    assert Complex.divide(Complex.new(:neg_infinity), -1) == Complex.new(:infinity, 0)
+    assert Complex.divide(Complex.new(:infinity), -1) == Complex.new(:neg_infinity, :nan)
+    assert Complex.divide(Complex.new(:neg_infinity), -1) == Complex.new(:infinity, :nan)
 
     assert Complex.divide(-1, :infinity) == 0
     assert Complex.divide(0, :infinity) == 0
@@ -425,8 +420,8 @@ defmodule ComplexTest do
     assert Complex.pow(:neg_infinity, :neg_infinity) == 0
     assert Complex.pow(0, :neg_infinity) == :infinity
     assert Complex.pow(0, :infinity) == 0
-    assert Complex.pow(Complex.new(0, 0), :neg_infinity) == :infinity
-    assert Complex.pow(Complex.new(0, 0), :infinity) == 0
+    assert Complex.pow(Complex.new(0, 0), :neg_infinity) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(0, 0), :infinity) == Complex.new(0, 0)
   end
 
   test "log, log10, log2 (non-finite)" do
@@ -499,7 +494,7 @@ defmodule ComplexTest do
              Complex.new(:infinity, :math.pi() / :math.log(10))
 
     assert Complex.log2(:infinity) == :infinity
-    assert Complex.log2(:neg_infinity) == Complex.new(:infinity, :math.pi() / :math.log(2))
+    assert Complex.log2(:neg_infinity) == Complex.new(:infinity, :nan)
     assert Complex.log2(:nan) == :nan
 
     assert Complex.log2(Complex.new(:infinity, :infinity)) ==
@@ -783,6 +778,227 @@ defmodule ComplexTest do
     assert Complex.erf_inv(-1) == :neg_infinity
   end
 
+  test "complex casting - add/2" do
+    assert Complex.add(:infinity, 1) == :infinity
+    assert Complex.add(:neg_infinity, 1) == :neg_infinity
+
+    assert Complex.add(:infinity, Complex.new(:neg_infinity, 0)) == Complex.new(:nan, 0)
+    assert Complex.add(:neg_infinity, Complex.new(:infinity, 0)) == Complex.new(:nan, 0)
+    assert Complex.add(:infinity, Complex.new(:infinity, 0)) == Complex.new(:infinity, 0)
+
+    assert Complex.add(:neg_infinity, Complex.new(:neg_infinity, 0)) ==
+             Complex.new(:neg_infinity, 0)
+
+    assert Complex.add(Complex.new(:neg_infinity, 0), :infinity) == Complex.new(:nan, 0)
+    assert Complex.add(Complex.new(:infinity, 0), :neg_infinity) == Complex.new(:nan, 0)
+    assert Complex.add(Complex.new(:infinity, 0), :infinity) == Complex.new(:infinity, 0)
+
+    assert Complex.add(Complex.new(:neg_infinity, 0), :neg_infinity) ==
+             Complex.new(:neg_infinity, 0)
+
+    assert Complex.add(:infinity, Complex.new(1, 2)) == Complex.new(:infinity, 2)
+    assert Complex.add(Complex.new(1, 2), :infinity) == Complex.new(:infinity, 2)
+  end
+
+  test "complex casting - subtract/2" do
+    assert Complex.subtract(:infinity, 1) == :infinity
+    assert Complex.subtract(:neg_infinity, 1) == :neg_infinity
+
+    assert Complex.subtract(:infinity, Complex.new(:neg_infinity, 0)) == Complex.new(:infinity, 0)
+
+    assert Complex.subtract(:neg_infinity, Complex.new(:infinity, 0)) ==
+             Complex.new(:neg_infinity, 0)
+
+    assert Complex.subtract(:infinity, Complex.new(:infinity, 0)) == Complex.new(:nan, 0)
+
+    assert Complex.subtract(:neg_infinity, Complex.new(:neg_infinity, 0)) ==
+             Complex.new(:nan, 0)
+
+    assert Complex.subtract(Complex.new(:neg_infinity, 0), :infinity) ==
+             Complex.new(:neg_infinity, 0)
+
+    assert Complex.subtract(Complex.new(:infinity, 0), :neg_infinity) == Complex.new(:infinity, 0)
+    assert Complex.subtract(Complex.new(:infinity, 0), :infinity) == Complex.new(:nan, 0)
+
+    assert Complex.subtract(Complex.new(:neg_infinity, 0), :neg_infinity) ==
+             Complex.new(:nan, 0)
+
+    assert Complex.subtract(:infinity, Complex.new(1, 2)) == Complex.new(:infinity, -2)
+    assert Complex.subtract(Complex.new(1, 2), :infinity) == Complex.new(:neg_infinity, 2)
+  end
+
+  test "complex casting - multiply/2" do
+    assert Complex.multiply(1, 1) == 1
+    assert Complex.multiply(:infinity, Complex.new(1, 1)) == Complex.new(:infinity, :infinity)
+
+    assert Complex.multiply(:neg_infinity, Complex.new(1, 1)) ==
+             Complex.new(:neg_infinity, :neg_infinity)
+
+    assert Complex.multiply(:infinity, :infinity) == :infinity
+    assert Complex.multiply(:neg_infinity, :infinity) == :neg_infinity
+    assert Complex.multiply(:infinity, :neg_infinity) == :neg_infinity
+    assert Complex.multiply(:neg_infinity, :neg_infinity) == :infinity
+
+    # First direction
+    assert Complex.multiply(Complex.new(:infinity, 1), :infinity) == Complex.new(:infinity, :nan)
+
+    assert Complex.multiply(Complex.new(:neg_infinity, 1), :neg_infinity) ==
+             Complex.new(:infinity, :nan)
+
+    assert Complex.multiply(Complex.new(:infinity, 1), :neg_infinity) ==
+             Complex.new(:neg_infinity, :nan)
+
+    assert Complex.multiply(Complex.new(:neg_infinity, 1), :infinity) ==
+             Complex.new(:neg_infinity, :nan)
+
+    assert Complex.multiply(Complex.new(1, :infinity), :infinity) == Complex.new(:nan, :infinity)
+
+    assert Complex.multiply(Complex.new(1, :infinity), :neg_infinity) ==
+             Complex.new(:nan, :neg_infinity)
+
+    assert Complex.multiply(Complex.new(1, :neg_infinity), :neg_infinity) ==
+             Complex.new(:nan, :infinity)
+
+    assert Complex.multiply(Complex.new(1, :neg_infinity), :infinity) ==
+             Complex.new(:nan, :neg_infinity)
+
+    # Second direction
+    assert Complex.multiply(:infinity, Complex.new(:infinity, 1)) == Complex.new(:infinity, :nan)
+
+    assert Complex.multiply(:neg_infinity, Complex.new(:neg_infinity, 1)) ==
+             Complex.new(:infinity, :nan)
+
+    assert Complex.multiply(:neg_infinity, Complex.new(:infinity, 1)) ==
+             Complex.new(:neg_infinity, :nan)
+
+    assert Complex.multiply(:infinity, Complex.new(:neg_infinity, 1)) ==
+             Complex.new(:neg_infinity, :nan)
+
+    assert Complex.multiply(:infinity, Complex.new(1, :infinity)) == Complex.new(:nan, :infinity)
+
+    assert Complex.multiply(:neg_infinity, Complex.new(1, :infinity)) ==
+             Complex.new(:nan, :neg_infinity)
+
+    assert Complex.multiply(:neg_infinity, Complex.new(1, :neg_infinity)) ==
+             Complex.new(:nan, :infinity)
+
+    assert Complex.multiply(:infinity, Complex.new(1, :neg_infinity)) ==
+             Complex.new(:nan, :neg_infinity)
+
+    # NaNs
+    assert Complex.multiply(:nan, 1) == :nan
+    assert Complex.multiply(1, :nan) == :nan
+
+    ## First direction
+    assert Complex.multiply(:nan, Complex.new(1, 1)) == Complex.new(:nan, :nan)
+    assert Complex.multiply(1, Complex.new(:nan, 1)) == Complex.new(:nan, :nan)
+    assert Complex.multiply(1, Complex.new(1, :nan)) == Complex.new(:nan, :nan)
+
+    ## Second direction
+    assert Complex.multiply(Complex.new(1, 1), :nan) == Complex.new(:nan, :nan)
+    assert Complex.multiply(Complex.new(:nan, 1), 1) == Complex.new(:nan, :nan)
+    assert Complex.multiply(Complex.new(1, :nan), 1) == Complex.new(:nan, :nan)
+  end
+
+  test "complex casting - divide/2" do
+    assert Complex.divide(1, 1) == 1
+
+    assert Complex.divide(:infinity, Complex.new(:infinity, 1)) == Complex.new(:nan, :nan)
+    assert Complex.divide(:neg_infinity, Complex.new(:neg_infinity, 1)) == Complex.new(:nan, :nan)
+
+    assert Complex.divide(:infinity, Complex.new(1, 1)) == Complex.new(:infinity, :neg_infinity)
+
+    assert Complex.divide(:neg_infinity, Complex.new(1, 1)) ==
+             Complex.new(:neg_infinity, :infinity)
+
+    assert Complex.divide(Complex.new(1, 1), :infinity) == Complex.new(0, 0)
+    assert Complex.divide(Complex.new(1, 1), :neg_infinity) == Complex.new(0, 0)
+
+    assert Complex.divide(Complex.new(:infinity, 1), :infinity) == Complex.new(:nan, :nan)
+    assert Complex.divide(Complex.new(1, :infinity), :infinity) == Complex.new(:nan, :nan)
+    assert Complex.divide(Complex.new(:infinity, 1), :neg_infinity) == Complex.new(:nan, :nan)
+    assert Complex.divide(Complex.new(1, :infinity), :neg_infinity) == Complex.new(:nan, :nan)
+
+    # NaNs
+    assert Complex.divide(:nan, 1) == :nan
+    assert Complex.divide(1, :nan) == :nan
+
+    ## First direction
+    assert Complex.divide(:nan, Complex.new(1, 1)) == Complex.new(:nan, :nan)
+    assert Complex.divide(1, Complex.new(:nan, 1)) == Complex.new(:nan, :nan)
+    assert Complex.divide(1, Complex.new(1, :nan)) == Complex.new(:nan, :nan)
+
+    ## Second direction
+    assert Complex.divide(Complex.new(1, 1), :nan) == Complex.new(:nan, :nan)
+    assert Complex.divide(Complex.new(:nan, 1), 1) == Complex.new(:nan, :nan)
+    assert Complex.divide(Complex.new(1, :nan), 1) == Complex.new(:nan, :nan)
+  end
+
+  test "complex casting - pow/2" do
+    # With NaN, if either argument is complex we return complex NaN
+    assert Complex.pow(1, :nan) == :nan
+    assert Complex.pow(:nan, 1) == :nan
+    assert Complex.pow(Complex.new(1, 1), :nan) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, :nan), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(:nan, 1), 1) == Complex.new(:nan, :nan)
+
+    # Infinities
+    ## Real
+    assert Complex.pow(:infinity, 3) == :infinity
+    assert Complex.pow(3, :infinity) == :infinity
+    assert Complex.pow(3, :neg_infinity) == 0.0
+    assert Complex.pow(:neg_infinity, 3) == :neg_infinity
+
+    assert Complex.pow(0, :infinity) == 0.0
+    assert Complex.pow(0, :neg_infinity) == :infinity
+    assert Complex.pow(:infinity, 0) == 1.0
+    assert Complex.pow(:neg_infinity, 0) == 1.0
+
+    ## Complex
+    ### If inf or -inf is in any argument, we return complex NaN
+    assert Complex.pow(Complex.new(:infinity, 1), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, :infinity), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, 1), :infinity) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(:infinity, 1)) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(1, :infinity)) == Complex.new(:nan, :nan)
+    assert Complex.pow(:infinity, Complex.new(1, 1)) == Complex.new(:nan, :nan)
+
+    assert Complex.pow(Complex.new(:neg_infinity, 1), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, :neg_infinity), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, 1), :neg_infinity) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(:neg_infinity, 1)) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(1, :neg_infinity)) == Complex.new(:nan, :nan)
+    assert Complex.pow(:neg_infinity, Complex.new(1, 1)) == Complex.new(:nan, :nan)
+
+    assert Complex.pow(Complex.new(:nan, 1), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, :nan), 1) == Complex.new(:nan, :nan)
+    assert Complex.pow(Complex.new(1, 1), :nan) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(:nan, 1)) == Complex.new(:nan, :nan)
+    assert Complex.pow(1, Complex.new(1, :nan)) == Complex.new(:nan, :nan)
+    assert Complex.pow(:nan, Complex.new(1, 1)) == Complex.new(:nan, :nan)
+  end
+
+  test "complex casting - atan2/2" do
+    assert Complex.atan2(Complex.new(1, 0), 1) == Complex.new(0.7853981633974483, 0)
+    assert Complex.atan2(1, Complex.new(1, 0)) == Complex.new(0.7853981633974483, 0)
+
+    assert Complex.atan2(:nan, Complex.new(1, 0)) == Complex.new(:nan, 0)
+    assert Complex.atan2(Complex.new(1, 0), :nan) == Complex.new(:nan, 0)
+    assert Complex.atan2(:nan, 1) == :nan
+    assert Complex.atan2(1, :nan) == :nan
+    assert Complex.atan2(:nan, :nan) == :nan
+
+    assert Complex.atan2(:infinity, 1) == :math.pi() / 2
+    assert Complex.atan2(:infinity, Complex.new(1, 0)) == Complex.new(:math.pi() / 2, 0)
+    assert Complex.atan2(Complex.new(1, 0), :infinity) == Complex.new(0, 0)
+    assert Complex.atan2(1, :infinity) == 0
+
+    assert Complex.atan2(:neg_infinity, 1) == -:math.pi() / 2
+    assert Complex.atan2(:neg_infinity, Complex.new(1, 0)) == Complex.new(-:math.pi() / 2, 0)
+    assert Complex.atan2(Complex.new(1, 0), :neg_infinity) == Complex.new(:math.pi(), 0)
+    assert Complex.atan2(1, :neg_infinity) == :math.pi()
+  end
+
   defp assert_close(left, right, opts \\ []) do
     eps = opts[:eps] || 1.0e-5