Skip to content

spec: Float to int conversions underspecified #19405

@cznic

Description

@cznic

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)
}

playground

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions