-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Closed
Labels
Description
What version of Go are you using (go version
)?
go version go1.8 linux/amd64
What operating system and processor architecture are you using (go env
)?
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jnml"
GORACE=""
GOROOT="/home/jnml/go"
GOTOOLDIR="/home/jnml/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build750966123=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
What did you do?
If possible, provide a recipe for reproducing the error.
package main
import (
"fmt"
"math"
)
func main() {
f := float32(math.MaxInt32 - 64)
i := int32(f)
fmt.Printf("%.10v, %v %#x\n", f, i, i)
f = float32(math.MaxInt32 - 63)
i = int32(f)
fmt.Printf("%.10v, %v %#x\n", f, i, i)
}
What did you expect to see?
2147483520, 2147483520 0x7fffff80
2147483648, 2147483647 0x7fffffff
What did you see instead?
2147483520, 2147483520 0x7fffff80
2147483648, -2147483648 -0x80000000
Discussion
The only relevant specs part I've found says
For the conversion of non-constant numeric values, the following rules apply:
...
2. When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero).
...
IOW, the outcome on overflow seems to be unspecified. However, changing the sign on overflow is surprising. Note that this is not a case of modular arithmetic. Bigger values of f
keep the value of i
unchanged
FWIW, gcc
has also a cut-off, but w/o sign change: 20031003-1.c, although it has to be said that in C the overflow is UB, with some mostly related discussion for example here.