Skip to content

Data.Complex doesn't consistently distinguish -0.0

Summary

This is a bit of a nitpick.

I'm implementing a numeric system for an interpreter that supports complex numbers. I want to piggyback off of Data.Complex as much as possible since it would be pretty silly to just duplicate all of the code that already exists.

Normal Haskell Doubles are IEEE doubles, which means there is both a +0.0 and a -0.0. Haskell does (because it would be more effort not to) distinguish between these values in computations, notably 1 / 0.0 = Infinity but 1 / (-0.0) = -Infinity. When working with Complex Double, this means that the difference between 0.0 and -0.0 is observable. However the implementation of phase has a short-circuit for when the argument is equal to 0 so that the phase is always 0.

As a result, since many Floating operations are defined in terms of log, which is defined in terms of phase, the results are incosistent with other languages at -0. Other languages (including, hopefully, mine) which distinguish 0.0 and -0.0 give log 0.0 = -Infinity but log (-0.0) = -Infinity + pi*i. Using Data.Complex, both are always -Infinity.

Note that the standard example of log's branch cut, log (-1-0i) behaves correctly, giving 0 :+ (-pi).

Steps to reproduce

Apply phase ((-0.0) :+ 0).

Expected behavior

Result is pi.

Environment

  • base-4.14.0.0
Edited by JKTKops
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information