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

spec: arithmetic on complex numbers is underspecified #29846

Open
aykevl opened this issue Jan 20, 2019 · 4 comments
Open

spec: arithmetic on complex numbers is underspecified #29846

aykevl opened this issue Jan 20, 2019 · 4 comments
Labels
ExpertNeeded NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@aykevl
Copy link

aykevl commented Jan 20, 2019

I can't find much about the precise behavior of floating point and complex arithmetic (+, -, *, /). For floating point this is relatively easy. For complex numbers, not so much, due to special numbers (Infinity, -Infinity, NaN) and rounding: https://medium.com/@smcallis_71148/complex-arithmetic-is-complicated-873ec0c69fc5.

Would it be possible to better specify the exact behavior of complex numbers, or point to the relevant spec? It appears that IEEE-754 doesn't say anything about complex numbers.
Of course, one can take a look at the source code of the compiler, but I would expect such details to be included in the specification.

Background: I am working on a compiler for the Go language called TinyGo. I would like to implement complex arithmetic but I'm not sure how it is supposed to be implemented.

@randall77
Copy link
Contributor

Yes, our complex numbers are pretty underspecified.

Complex arithmetic has lots of corner cases. There are multiple versions of infinity (inf+0i, 0+inf*i, etc.) and nans. As far as I know we don't normalize any of these corner cases.

Also the rounding story for complex numbers is unclear. You have to compute floating-point expressions like a*b+c*d, but how many roundings are allowed while doing that?

@ianlancetaylor
Copy link
Contributor

It will help us if you write down in more detail what you think we should specify.

In general the complex number supports follows Annex G of the C11 programming language standard, which describes how complex numbers should work in C.

@FiloSottile FiloSottile added this to the Unplanned milestone Jan 23, 2019
@FiloSottile FiloSottile added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 23, 2019
@FiloSottile
Copy link
Contributor

/cc @griesemer for spec-related issues.

@aykevl
Copy link
Author

aykevl commented Jan 30, 2019

It will help us if you write down in more detail what you think we should specify.

For example, based on the compiler source code, it appears that this is how addition is implemented, assuming a and b are complex numbers:

return complex(real(a) + real(b), imag(a) + imag(b))

Multiplication appears to be done this way (ignoring widening/narrowing to do the multiplication in float64 instead of float32 for complex64):

r := real(a) * real(b) - imag(a) * imag(b)
i := real(a) * imag(b) + imag(a) * real(b)
return complex(r, i)

The spec could list this as pseudo-code, for example. That would make an implementation trivial. Of course, the spec should then also specify whether the widening done here is required or not - because I would want to avoid it in my implementation if it is not absolutely necessary.

When I take a look at the C11 spec regarding complex numbers, the given code is quite big. It takes special care of NaN and Infinity, which the Go compiler appears to completely ignore. So perhaps this is even a bug in the Go compiler, I don't know what the intended behavior is. It certainly shows that the Go language could use some more words regarding how complex numbers ought to work (and if the spec doesn't care about NaN/Inf, that's fine to me, but it should be specified IMHO).

aykevl added a commit to tinygo-org/tinygo that referenced this issue May 4, 2019
This is hard to do correctly, so copy the relevant files from the Go
compiler itself.

For related discussions:
* golang/go#14644
* golang/go#29846
aykevl added a commit to tinygo-org/tinygo that referenced this issue May 10, 2019
This is hard to do correctly, so copy the relevant files from the Go
compiler itself.

For related discussions:
* golang/go#14644
* golang/go#29846
deadprogram pushed a commit to tinygo-org/tinygo that referenced this issue May 11, 2019
This is hard to do correctly, so copy the relevant files from the Go
compiler itself.

For related discussions:
* golang/go#14644
* golang/go#29846
torntrousers pushed a commit to HarringayMakerSpace/tinygo that referenced this issue May 18, 2019
This is hard to do correctly, so copy the relevant files from the Go
compiler itself.

For related discussions:
* golang/go#14644
* golang/go#29846
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ExpertNeeded NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants