Repository: go
Issue: cmd/vet: add math check for erroneous math expressions
Labels: Proposal,Proposal-Accepted,Analysis

Go constants can be extended to support -0, NaN, +Inf, and -Inf, as constant values.
There is no special name for any of these constants; this is support for values, not new tokens. The model for this is mythical "IEEE Reals", which is the combination of Real numbers (not floating point) with the rules for IEEE -0, NaN, +Inf, and -Inf added where they fit, in accordance with the rules for IEEE floating point.

Why should we do this?

1.  It brings us closer to no-surprises support for IEEE floating point. I would say "zero surprises" except that there are still cases where large-precision constant arithmetic provides different answers; I think we handle that using the "IEEE real numbers" explanation.
2. A corollary of the first, is that numerically oriented people and code coming from other languages will experience one fewer surprise or speed bump in their use of Go.  Sure, the workaround is easy, but it's not as easy as not needing to know it.
3. It brings constant evaluation slightly closer to run-time evaluation of Go programs; one more difference/surprise is avoided.
4. It breaks zero programs except for tests targeted specifically to this behavior.
5. I have never, ever, heard of support for these constant values causing problems for anyone in any other language that supports them.

The following conversion-from-constant-value rules are added: when converting to integer, -0 becomes 0, and NaN and Inf become errors.  When converting to floating point (or component of a complex number), the obvious mapping to IEEE floats occurs.  In the case of tiny negative fraction underflow when converting to float, -0 results; in the case of positive or negative overflow on conversion to float, +Inf or -Inf results, as appropriate.

This arithmetic rules are enumerated in the following tables, which were checked against the IEEE specification and run-time arithmetic evaluation in both Java (expected to conform to IEEE) and Go (since this [commit for 1.13](https://github.com/golang/go/commit/653579138555ff2728ba16f841b640e06deab8df) , believed to conform to IEEE).

Legend:
```
R = real numbers
P = { x in R such that x > 0} (but not +Inf)
N = { x in R such that x < 0} (but not -Inf)
Z = 0
NZ = -0
PI = positive infinity
NI = negative infinity
NaN = not-a-number
```
In the tables below, "R" as a result means to use the rules for real numbers. "RZ" means use the rule for real numbers with NZ replaced by Z.

addition|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|R|RZ|PI|NI|NaN
N|R|R|R|RZ|PI|NI|NaN
Z|R|R|R|Z|PI|NI|NaN
NZ|RZ|RZ|Z|NZ|PI|NI|NaN
PI|PI|PI|PI|PI|PI|NaN|NaN
NI|NI|NI|NI|NI|NaN|NI|NaN
NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN

subtraction (column - row)|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|R|RZ|NI|PI|NaN
N|R|R|R|RZ|NI|PI|NaN
Z|R|R|R|Z|NI|PI|NaN
NZ|RZ|RZ|NZ|Z|NI|PI|NaN
PI|PI|PI|PI|PI|NaN|PI|NaN
NI|NI|NI|NI|NI|NI|NaN|NaN
NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN

multiplication|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|Z|NZ|PI|NI|NaN
N|R|R|NZ|Z|NI|PI|NaN
Z|Z|NZ|Z|NZ|NaN|NaN|NaN
NZ|NZ|Z|NZ|Z|NaN|NaN|NaN
PI|PI|NI|NaN|NaN|PI|NI|NaN
NI|NI|PI|NaN|NaN|NI|PI|NaN
NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN

division (row/column)|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|PI|NI|Z|NZ|NaN
N|R|R|NI|PI|NZ|Z|NaN
Z|Z|NZ|NaN|NaN|Z|NZ|NaN
NZ|NZ|Z|NaN|NaN|NZ|Z|NaN
PI|PI|NI|PI|NI|NaN|NaN|NaN
NI|NI|PI|NI|PI|NaN|NaN|NaN
NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN

remainder (row REM column)|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|NaN|NaN|x|x|NaN
N|R|NZ|NaN|NaN|x|x|NaN
Z|Z|Z|NaN|NaN|Z|Z|NaN
NZ|NZ|NZ|NaN|NaN|NZ|NZ|NaN
PI|NaN|NaN|NaN|NaN|NaN|NaN|NaN
NI|NaN|NaN|NaN|NaN|NaN|NaN|NaN
NaN|NaN|NaN|NaN|NaN|NaN|NaN|NaN

equality|P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|R|RZ|F|F|F
N|R|R|R|RZ|F|F|F
Z|R|R|R|RZ|F|F|F
NZ|RZ|RZ|RZ|RZ|F|F|F
PI|F|F|F|F|T|F|F
NI|F|F|F|F|F|T|F
NaN|F|F|F|F|F|F|F

less than (row < column) |P|N|Z|NZ|PI|NI|NaN
-|-|-|-|-|-|-|-
P|R|R|R|RZ|T|F|F
N|R|R|R|RZ|T|F|F
Z|R|R|R|RZ|T|F|F
NZ|RZ|RZ|RZ|RZ|T|F|F
PI|F|F|F|F|F|F|F
NI|T|T|T|T|T|F|F
NaN|F|F|F|F|F|F|F