Data.Complex shouldn't use default implementation of (**)
Prelude Data.Complex> 0**2
0.0
Prelude Data.Complex> 0**2 :: Complex Double
NaN :+ NaN
Prelude Data.Complex> exp $ 2 * log 0 :: Complex Double
NaN :+ NaN
Prelude Data.Complex> log 0 :: Complex Double
(-Infinity) :+ 0.0
Prelude Data.Complex> 2 * it :: Complex Double
(-Infinity) :+ NaN
Prelude Data.Complex> exp it :: Complex Double
NaN :+ NaN
So Complex uses the default implementation of (!**). Then when 2*(-inf :+ 0) is evaluated. We do (2 * -inf - 0*0) :+ (2*0 + -inf*0). Which because of -inf*0 sets the imaginary part to NaN.
Then exp (-inf :+ NaN) = exp x cos y :+ exp x sin y which becomes 0 * cos NaN :+ 0 * sin NaN. So we end up with NaN :+ NaN.
Ross Paterson suggested:
I would say the default implementation of (!**) is wrong: to match the Float/Double instances it should be
x !** y = if x == 0 then 0 else exp (log x * y)
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Prelude |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |