mirror of https://github.com/golang/go.git
spec: clarify numeric conversions where IEEE-754 produces -0.0
The spec defines precise numeric constants which do not overflow. Consequently, +/-Inf and NaN values were excluded. The case was not clear for -0.0 but they are mostly of interest to determine the sign of infinities which don't exist. That said, the conversion rules explicitly say that T(x) (for a numeric x and floating-point type T) is the value after rounding per IEEE-754. The result is constant if x is constant. Rounding per IEEE-754 can produce a -0.0 which we cannot represent as a constant. Thus, the spec is inconsistent. Attempt to fix the inconsistency by adjusting the rounding rule rather than letting -0.0 into the language. For more details, see the issue below. Open to discussion. Fixes #12576. Change-Id: Ibe3c676372ab16d9229f1f9daaf316f761e074ee Reviewed-on: https://go-review.googlesource.com/14727 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
27838f3990
commit
55ecda4ffd
|
|
@ -1,6 +1,6 @@
|
||||||
<!--{
|
<!--{
|
||||||
"Title": "The Go Programming Language Specification",
|
"Title": "The Go Programming Language Specification",
|
||||||
"Subtitle": "Version of September 24, 2015",
|
"Subtitle": "Version of October 20, 2015",
|
||||||
"Path": "/ref/spec"
|
"Path": "/ref/spec"
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
|
|
@ -558,7 +558,9 @@ and are discussed in that section.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Numeric constants represent values of arbitrary precision and do not overflow.
|
Numeric constants represent exact values of arbitrary precision and do not overflow.
|
||||||
|
Consequently, there are no constants denoting the IEEE-754 negative zero, infinity,
|
||||||
|
and not-a-number values.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -593,16 +595,6 @@ respectively, depending on whether it is a boolean, rune, integer, floating-poin
|
||||||
complex, or string constant.
|
complex, or string constant.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
|
||||||
There are no constants denoting the IEEE-754 infinity and not-a-number values,
|
|
||||||
but the <a href="/pkg/math/"><code>math</code> package</a>'s
|
|
||||||
<a href="/pkg/math/#Inf">Inf</a>,
|
|
||||||
<a href="/pkg/math/#NaN">NaN</a>,
|
|
||||||
<a href="/pkg/math/#IsInf">IsInf</a>, and
|
|
||||||
<a href="/pkg/math/#IsNaN">IsNaN</a>
|
|
||||||
functions return and test for those values at run time.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Implementation restriction: Although numeric constants have arbitrary
|
Implementation restriction: Although numeric constants have arbitrary
|
||||||
precision in the language, a compiler may implement them using an
|
precision in the language, a compiler may implement them using an
|
||||||
|
|
@ -3795,7 +3787,8 @@ type <code>T</code> in any of these cases:
|
||||||
<code>T</code> is a floating-point type,
|
<code>T</code> is a floating-point type,
|
||||||
and <code>x</code> is representable by a value
|
and <code>x</code> is representable by a value
|
||||||
of type <code>T</code> after rounding using
|
of type <code>T</code> after rounding using
|
||||||
IEEE 754 round-to-even rules.
|
IEEE 754 round-to-even rules, but with an IEEE <code>-0.0</code>
|
||||||
|
further rounded to an unsigned <code>0.0</code>.
|
||||||
The constant <code>T(x)</code> is the rounded value.
|
The constant <code>T(x)</code> is the rounded value.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -3815,6 +3808,7 @@ uint(iota) // iota value of type uint
|
||||||
float32(2.718281828) // 2.718281828 of type float32
|
float32(2.718281828) // 2.718281828 of type float32
|
||||||
complex128(1) // 1.0 + 0.0i of type complex128
|
complex128(1) // 1.0 + 0.0i of type complex128
|
||||||
float32(0.49999999) // 0.5 of type float32
|
float32(0.49999999) // 0.5 of type float32
|
||||||
|
float64(-1e-1000) // 0.0 of type float64
|
||||||
string('x') // "x" of type string
|
string('x') // "x" of type string
|
||||||
string(0x266c) // "♬" of type string
|
string(0x266c) // "♬" of type string
|
||||||
MyString("foo" + "bar") // "foobar" of type MyString
|
MyString("foo" + "bar") // "foobar" of type MyString
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue