Closed
Description
What version of Go are you using (go version
)?
$ go version go version go1.13.5 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
linux/amd64
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/x448/.cache/go-build" GOENV="/home/x448/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/x448/gocode1.13" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/home/x448/go1.13" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/x448/go1.13/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/x448/gocode1.13/mysrc/cbor-go/float16/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build276233946=/tmp/go-build -gno-record-gcc-switches"
What did you do?
- Cast float64 to float32 with sNaN value (turns into qNaN).
- Cast float32 to float64 with sNaN value (keeps sNaN).
More at fxamacker/cbor#93
Bug reproducer:
https://play.golang.org/p/kzLI9A07wRv
package main
import (
"fmt"
"math"
)
func main() {
// init float32 with sNaN
const u32 = uint32(0x7f800001) // IEEE 754 binary32 representation of sNaN
f32 := math.Float32frombits(u32)
// cast float32 to float64
f64 := float64(f32)
u64 := math.Float64bits(f64)
// test passes
sbit64 := uint64(0x8000000000000) // the signalling/quiet bit for IEEE 754 binary64
if (u64 & sbit64) != 0 {
fmt.Printf("Go/Golang lost bit when casting float32 to float64, forced sNaN to qNaN\n")
}
f32bis := float32(f64)
u32bis := math.Float32bits(f32bis)
diff := u32bis ^ u32
// test fails
if diff != 0 {
fmt.Printf("Go/Golang lost bit when casting float64 to float32, forced sNaN to qNaN\n")
fmt.Printf("u32=0x%08x, u32bis=0x%08x, diff=0x%08x\n", u32, u32bis, diff)
}
}
What did you expect to see?
Consistent behavior when casting from float64 to float32 and vice versa regarding the NaN signalling bit (quiet bit).
What did you see instead?
Inconsistent behavior when casting float with NaN signalling bit.
Go/Golang lost bit when casting float64 to float32, forced sNaN to qNaN
u32=0x7f800001, u32bis=0x7fc00001, diff=0x00400000