Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile, runtime: complex (-1+0i)/0.0 results in +inf #14644

Closed
martisch opened this issue Mar 4, 2016 · 30 comments
Closed

cmd/compile, runtime: complex (-1+0i)/0.0 results in +inf #14644

martisch opened this issue Mar 4, 2016 · 30 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@martisch
Copy link
Contributor

martisch commented Mar 4, 2016

at least go1.4, go 1.6, go tip

found this writing fmt tests for float formatting.
But i do not think this time its a formatting error:

https://play.golang.org/p/UonwOD_TT3

package main
func main() {
    v := -1+0i
    print(real(v)/0.0) // float 0 division
    print(" vs ")
    print(real(v/0.0)) // complex 0 division
    print("\n")
}

Output:

-Inf vs +Inf

would have expected -Inf for the complex case too.

@martisch martisch changed the title complex (-1+0i)/0.0 results in +inf all: complex (-1+0i)/0.0 results in +inf Mar 4, 2016
@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

CC @griesemer

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

if this is considered a bug it can be fixed in runtime/complex.go
in complex128div function in this if branch:

case real(d) == 0 && imag(d) == 0:
        if real(n) == 0 && imag(n) == 0 {
            return complex(nan(), nan())
        } else 

returning

return complex(neginf(), neginf())

when needed.

There might be some other edge cases here that need there own case distinctions.
And other parts of the library were inf cases for complex values are not correct.

If this is considered/confirmed a bug i like to submit a patch for this.

@griesemer
Copy link
Contributor

Definitively a bug: imag(v) is 0, so there should be no difference between (-1+0i)/0.0 and -1/0.0 (executed at runtime). The result should be -Inf.

@griesemer
Copy link
Contributor

PS: The spec doesn't really specify what should happen in these cases, but since the implementation doesn't panic in these cases (div by 0) and produces +/-Inf values, it should be consistent.

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

Since as you say the spec does not specify any of this i was unsure if this was considered a bug.
But i also would find it weird if a 0 imag part complex would behave different than a float. Also other cases correctly produce -inf so it would make the whole complex arithmetic a bit inconsistent.

Will craft a patch and look around if this issue happens elsewhere.

@ianlancetaylor ianlancetaylor changed the title all: complex (-1+0i)/0.0 results in +inf cmd/compile, runtime: complex (-1+0i)/0.0 results in +inf Mar 4, 2016
@ianlancetaylor
Copy link
Contributor

For the record, gccgo prints -Inf vs -Inf.

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone Mar 4, 2016
@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

@ianlancetaylor
thanks. i have a look at gccgo how other cases such as (-1+1i)/0 are handled there too.

@randall77
Copy link
Contributor

I'm not sure this is a bug. Unlike reals, there are many directions you can go to get to infinity, not just two. Having -1/0 go to -Inf and all other numerators/0 go to +Inf seems non-symmetrical.

What should the return values be in these cases? http://play.golang.org/p/POOTEwRIxp

@griesemer
Copy link
Contributor

@randall77 Point taken for all the other complex values. But for a value z where imag(z) == 0, we have at least a consistency issue in the compiler here - it does seem odd that we wouldn't get the same result as for the identical value of real type. As mentioned before, the spec doesn't really specify the result.

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

Complex arithmetic with 0 and -inf/+inf has definitely some weird behavior overall even with imag parts 0:
((1.0+0i)/zero)*((1.0+0i)/zero)
is (NaN+Infi)

i would just suggest to make those (imag(z)==0) consistent with float behavior.

@cldorian
Copy link
Contributor

cldorian commented Mar 4, 2016

The answer is correct. Look at the Wikipedia entry: https://en.wikipedia.org/wiki/Infinity#Complex_analysis

@griesemer
Copy link
Contributor

@cldorian Interesting. Thanks for the link. I've definitively forgotten my complex analysis...

So, for any complex number, z/0 would be +Inf (+Inf + 0i to be precise), except when z = 0 itself, in which case it's (probably) NaN + NaNi?

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

Should complex +Inf be treated as an unsigned infinity in the Riemann sphere model of the extended complex plane then https://en.wikipedia.org/wiki/Riemann_sphere ?
z * inf = inf
z + inf = inf
z / 0 = inf
z / inf = 0
int + inf = NaN
inf – inf = NaN
inf * inf = inf

Because if +Inf is correct for (-1+0i)/0.0 by that view the other operations may not be consistent e.g. inf+inf and inf*inf.

@cldorian
Copy link
Contributor

cldorian commented Mar 4, 2016

@robert -- If you review the source code for cmplx.IsInf and cmplx.IsNan,
you'll see you're correct.

@martin -- I don't understand the questions you've posed. Perhaps you could
ask them in different words?
For reference:
cmplx.IsInf((1.0+0i)/0.0) == true and cmplx.Inf() returns
complex(math.Inf(1), math.Inf(1))
real(+Inf+0i) == +Inf and imag(+Inf+0i) == 0

On Fri, Mar 4, 2016 at 2:00 PM, Martin Möhrmann notifications@github.com
wrote:

If for complex +Inf is treated as an unsigned infinity then:
((1.0+0i)/zero)+((1.0+0i)/zero) = (+Inf+Infi) should be NaN + NaNi too?
and should real and imag on +Inf+0i yield NaN?


Reply to this email directly or view it on GitHub
#14644 (comment).

@cldorian
Copy link
Contributor

cldorian commented Mar 4, 2016

@robert -- Sorry, I misspoke. The "+Inf + 0i to be precise" is wrong. There
are infinitely many complex values for which cmplx.IsInf(z) is true.

On Fri, Mar 4, 2016 at 2:33 PM, Charlie Dorian cldorian@gmail.com wrote:

@robert -- If you review the source code for cmplx.IsInf and cmplx.IsNan,
you'll see you're correct.

@martin -- I don't understand the questions you've posed. Perhaps you
could ask them in different words?
For reference:
cmplx.IsInf((1.0+0i)/0.0) == true and cmplx.Inf() returns
complex(math.Inf(1), math.Inf(1))
real(+Inf+0i) == +Inf and imag(+Inf+0i) == 0

On Fri, Mar 4, 2016 at 2:00 PM, Martin Möhrmann notifications@github.com
wrote:

If for complex +Inf is treated as an unsigned infinity then:
((1.0+0i)/zero)+((1.0+0i)/zero) = (+Inf+Infi) should be NaN + NaNi too?
and should real and imag on +Inf+0i yield NaN?


Reply to this email directly or view it on GitHub
#14644 (comment).

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

@cldorian
sorry, tried to reformulate in my post. The questions for me are:

  1. If +inf is correct then should (+inf+infi)+(+inf+infi) yield NaN+NaNi instead of +inf+infi
    since unsigned infinities should not be added.
  2. If we treat +Inf for complex as an unsigned infinity (which 1.0+0i)/0.0 == +Inf suggests) then is it ok that real(+inf+infi) returns a signed float infinity?
    Answer from myself: The spec would not allow otherwise as real and imag are the reverse of complex and x == y means real(x)==real(y) and imag(x)==imag(y)

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

@cldorian
Looking at cmplx i think i now understand it better.
Is it true that (+inf+0) is as correct as is (-inf+0) for (-1+0i)/0.0 ( both satisfies cmplx.IsInf ). So it would not be incorrect but is not the only correct result?

@cldorian
Copy link
Contributor

cldorian commented Mar 4, 2016

@martin -- 1. I'm pretty sure the usual computer rules can be followed. So,
if z and w are complex, we can define z + w = complex(real(z) + real(w),
imag(z) + imag(w)) and ignore the question of an unsigned infinity.

If you look at the source for cmplx.IsInf(z), you'll see that if either
real(z) or imag(z) is Inf, then z is Inf, even if the other part is NaN.
For example, cmplx.IsInf(complex(math.Inf(1), math.NaN())) == true and
cmplx.IsNaN(complex(math.Inf(1), math.NaN())) == false.

  1. We can ignore the question of an unsigned infinity, the way we do in
    cmplx.IsInf(z). We don't care if it is +math.Inf(1) or math.Inf(-1). And
    real(complex(math.Inf(1), math.Inf(1))) returns math.Inf(1).

On Fri, Mar 4, 2016 at 2:44 PM, Martin Möhrmann notifications@github.com
wrote:

@cldorian https://github.com/cldorian
sorry, tried to reformulate in my post. The questions for me are:

if +inf is correct then should (+inf+infi)+(+inf+infi) yield NaN+NaNi
instead of +inf+infi since unsigned infinities should not be added.
2.

If we treat +Inf for complex as an unsigned infinity (which
1.0+0i)/0.0 = +Inf suggests) then is it ok that real(+inf+infi) returns a
signed float infinity?


Reply to this email directly or view it on GitHub
#14644 (comment).

@cldorian
Copy link
Contributor

cldorian commented Mar 4, 2016

@martin -- Yes. If z is (+inf+0) and w is (-inf+0), it is true that
cmplx.IsInf(z) == cmplx.IsInf(w), even if real(z) == real(w) is false.

On Fri, Mar 4, 2016 at 4:16 PM, Charlie Dorian cldorian@gmail.com wrote:

@martin -- 1. I'm pretty sure the usual computer rules can be followed.
So, if z and w are complex, we can define z + w = complex(real(z) +
real(w), imag(z) + imag(w)) and ignore the question of an unsigned infinity.

If you look at the source for cmplx.IsInf(z), you'll see that if either
real(z) or imag(z) is Inf, then z is Inf, even if the other part is NaN.
For example, cmplx.IsInf(complex(math.Inf(1), math.NaN())) == true and
cmplx.IsNaN(complex(math.Inf(1), math.NaN())) == false.

  1. We can ignore the question of an unsigned infinity, the way we do in
    cmplx.IsInf(z). We don't care if it is +math.Inf(1) or math.Inf(-1). And
    real(complex(math.Inf(1), math.Inf(1))) returns math.Inf(1).

On Fri, Mar 4, 2016 at 2:44 PM, Martin Möhrmann notifications@github.com
wrote:

@cldorian https://github.com/cldorian
sorry, tried to reformulate in my post. The questions for me are:

if +inf is correct then should (+inf+infi)+(+inf+infi) yield NaN+NaNi
instead of +inf+infi since unsigned infinities should not be added.
2.

If we treat +Inf for complex as an unsigned infinity (which
1.0+0i)/0.0 = +Inf suggests) then is it ok that real(+inf+infi) returns a
signed float infinity?


Reply to this email directly or view it on GitHub
#14644 (comment).

@martisch
Copy link
Contributor Author

martisch commented Mar 4, 2016

Thanks for the explanations. Under this model the behavior seems fine to me now. However the question remains if it would be fruitful to change the behavior to -inf (which would still be correct) so that complex operations with imag(z)==0 behave the same as floats which would be less surprising (at least to me) and compatible e.g. with gccgo.

@minux
Copy link
Member

minux commented Mar 5, 2016

I'm rather surprised by this bug, because we have a test (test/cmplxdivide.go)
that verifies our complex divide results for all corner cases against C.

However, now that I take a closer look at the test, it's actually not correct.
For example, it allows +Inf and -Inf to be considered equal (which is the
reason this bug is left unnoticed until now.)

If I strengthen the test so that both the real and imag parts must match C's
result exactly, I got quite a lot of test failures:

BUG
(0+1i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(0-1i)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(0+2i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(1+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(1-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-1+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-1-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(2+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(2-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)

I always thought our complex arithmetic matches C99's, but
I'm wrong. I don't know what should be done as people can
argue that changing this is a breaking change.

(According to comments in runtime/complex.go, I think the
intention was to match C99's handling of corner cases.)

@dr2chase
Copy link
Contributor

dr2chase commented Mar 5, 2016

Do we believe that C gets this right? If so, I'm somewhat in favor of
breaking Go compatibility on this one, because I don't want to be in the
business of explaining different, "wrong" floating point complex behavior
(this assumes we believe we're actually wrong and that C is right.).

Or we should at least give it a try and see what goes "boom!"

On Fri, Mar 4, 2016 at 10:20 PM, Minux Ma notifications@github.com wrote:

I'm rather surprised by this bug, because we have a test
(test/cmplxdivide.go)
that verifies our complex divide results for all corner cases against C.

However, now that I take a closer look at the test, it's actually not
correct.
For example, it allows +Inf and -Inf to be considered equal (which is the
reason this bug is left unnoticed until now.)

If I strengthen the test so that both the real and imag parts must match
C's
result exactly, I got quite a lot of test failures:

BUG
(0+1i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(0-1i)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(0+2i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(1+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(1-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-1+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-1-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(2+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(2-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)

I always thought our complex arithmetic matches C99's, but
I'm wrong. I don't know what should be done as people can
argue that changing this is a breaking change.


Reply to this email directly or view it on GitHub
#14644 (comment).

@bradfitz
Copy link
Contributor

bradfitz commented Mar 5, 2016

I don't know what should be done as people can
argue that changing this is a breaking change.

Let's ask those people. I doubt there are many.

@cldorian
Copy link
Contributor

cldorian commented Mar 5, 2016

@minux Ma -- You're revisiting 2010, when the tests were initially
developed. Russ said then, "gcc is wrong".

For a more recent conservation about complex infinity, see
https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/495874.
Near the bottom, there's even mention of C99 Annex G (complex arithmetic),
with reference to some rules.

G.5.1, paragraph 4:

The * and / operators satisfy the following infinity properties for all
real, imaginary, and complex operands:315)
— if one operand is an infinity and the other operand is a nonzero finite
number or an
infinity, then the result of the * operator is an infinity;
— if the first operand is an infinity and the second operand is a finite
number, then the
result of the / operator is an infinity;
— if the first operand is a finite number and the second operand is an
infinity, then the
result of the / operator is a zero;
— if the first operand is a nonzero finite number or an infinity and the
second operand is
a zero, then the result of the / operator is an infinity.

On Fri, Mar 4, 2016 at 10:20 PM, Minux Ma notifications@github.com wrote:

I'm rather surprised by this bug, because we have a test
(test/cmplxdivide.go)
that verifies our complex divide results for all corner cases against C.

However, now that I take a closer look at the test, it's actually not
correct.
For example, it allows +Inf and -Inf to be considered equal (which is the
reason this bug is left unnoticed until now.)

If I strengthen the test so that both the real and imag parts must match
C's
result exactly, I got quite a lot of test failures:

BUG
(0+1i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(0-1i)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(0+2i)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(1+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(1-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-1+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-1-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-1+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(2+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(2-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+0i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+0i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+0i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+0i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf-1i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf-1i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf-1i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+1i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0-1i): expected (NaN+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(0+2i): expected (NaN-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(+Inf+2i)/(-1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(+Inf+2i)/(2+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(+Inf+2i)/(2+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+0i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+0i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+0i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf-1i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf-1i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+0i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+1i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0-1i): expected (NaN-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(0+2i): expected (NaN+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(-1+0i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(-1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+0i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(-Inf+2i)/(2+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(-Inf+2i)/(2+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(0+1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0-1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(0+2i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN+Infi)/(1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(1-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1-1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(-1+2i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN+Infi)/(2-1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(0+1i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0-1i): expected (+Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(0+2i): expected (-Inf+NaNi) error; got (+Inf+Infi)
(NaN-Infi)/(1+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(1+2i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+0i): expected (NaN+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+1i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(-1+2i): expected (-Inf+Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+0i): expected (NaN-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+1i): expected (-Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2-1i): expected (+Inf-Infi) error; got (+Inf+Infi)
(NaN-Infi)/(2+2i): expected (-Inf-Infi) error; got (+Inf+Infi)

I always thought our complex arithmetic matches C99's, but
I'm wrong. I don't know what should be done as people can
argue that changing this is a breaking change.


Reply to this email directly or view it on GitHub
#14644 (comment).

@minux
Copy link
Member

minux commented Mar 5, 2016 via email

@rsc
Copy link
Contributor

rsc commented May 17, 2016

We're in the Go 1.7 freeze now and limiting work to low-risk, high-reward changes. This bug has been in multiple past Go releases and is a bit of a corner case, so it's OK to have in one more and avoid any risk of breaking something else (like more common divisions).

@rsc rsc added this to the Go1.8 milestone May 17, 2016
@rsc rsc removed this from the Go1.7 milestone May 17, 2016
@griesemer
Copy link
Contributor

Talking to a complex analysis expert, the Riemann sphere (mentioned by @martisch above) is indeed a useful tool to deal with infinity, and all infinities are mapped to a single point at the top of the sphere (the "north pole"). Or in other words, +Inf and -Inf are indistinguishable using this model.

Whether this is the correct approach in a computational (rather than mathematical) environment is a different question. We should talk to an expert in the field of complex numerics for an authoritative answer.

@quentinmit quentinmit added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Oct 10, 2016
@rsc
Copy link
Contributor

rsc commented Oct 21, 2016

I'd like to match the C/C++ standards here. If someone can make the case that Go disagrees with those, then we should fix it. But probably not for this round.

@rsc rsc modified the milestones: Go1.9Early, Go1.8 Oct 21, 2016
@martisch martisch self-assigned this Feb 28, 2017
@martisch
Copy link
Contributor Author

Working on this and made a CL at http://golang.org/cl/37441

Needs documentation and benchmark before review can start.

@gopherbot
Copy link

CL https://golang.org/cl/37441 mentions this issue.

@golang golang locked and limited conversation to collaborators Mar 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests