diff --git a/spec/std/complex_spec.cr b/spec/std/complex_spec.cr index 65add18f8533..2b90239d0796 100644 --- a/spec/std/complex_spec.cr +++ b/spec/std/complex_spec.cr @@ -265,6 +265,12 @@ describe "Complex" do it "complex / complex" do ((Complex.new(4, 6.2))/(Complex.new(0.5, 2.7))).should eq(Complex.new(2.485411140583554, -1.0212201591511936)) ((Complex.new(4.1, 6.0))/(Complex.new(10, 2.2))).should eq(Complex.new(0.5169782525753529, 0.48626478443342236)) + + (1.to_c / -1.to_c).should eq(-1.to_c) + assert_complex_nan 1.to_c / Float64::NAN + + (1.to_c / 0.to_c).real.abs.should eq(Float64::INFINITY) + (1.to_c / 0.to_c).imag.nan?.should be_true end it "complex / number" do diff --git a/src/complex.cr b/src/complex.cr index 65fbc9204b59..e2a5830b395a 100644 --- a/src/complex.cr +++ b/src/complex.cr @@ -237,14 +237,28 @@ struct Complex # Divides `self` by *other*. def /(other : Complex) : Complex - if other.real <= other.imag - r = other.real / other.imag - d = other.imag + r * other.real - Complex.new((@real * r + @imag) / d, (@imag * r - @real) / d) - else + if other.real.nan? || other.imag.nan? + Complex.new(Float64::NAN, Float64::NAN) + elsif other.imag.abs < other.real.abs r = other.imag / other.real d = other.real + r * other.imag - Complex.new((@real + @imag * r) / d, (@imag - @real * r) / d) + + if d.nan? || d == 0 + Complex.new(Float64::NAN, Float64::NAN) + else + Complex.new((@real + @imag * r) / d, (@imag - @real * r) / d) + end + elsif other.imag == 0 # other.real == 0 + Complex.new(@real / other.real, @imag / other.real) + else # 0 < other.real.abs <= other.imag.abs + r = other.real / other.imag + d = other.imag + r * other.real + + if d.nan? || d == 0 + Complex.new(Float64::NAN, Float64::NAN) + else + Complex.new((@real * r + @imag) / d, (@imag * r - @real) / d) + end end end