Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testing/quick: float64 values generated by quick seems to be always with either 307 or 308 as the exponent #46162

Closed
fishy opened this issue May 13, 2021 · 3 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.

Comments

@fishy
Copy link

fishy commented May 13, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env | grep -v GOPRIVATE
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/fishy/.cache/go-build"
GOENV="/home/fishy/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/fishy/.gopath/pkg/mod"
GONOPROXY="github.snooguts.net"
GONOSUMDB="github.snooguts.net"
GOOS="linux"
GOPATH="/home/fishy/.gopath"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.4"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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-build745604388=/tmp/go-build -gno-record-gcc-switches"

What did you do?

for this simple code (also on https://play.golang.org/p/kDpslSUu9TU):

package main

import (
	"fmt"
	"testing/quick"
)

func main() {
	f := func(f float64) bool {
		fmt.Println(f)
		return true
	}
	quick.Check(f, nil)
}

This is a sample run result:

sample run result
-8.969297190834214e+307
-7.831502607950853e+307
-1.017836961875757e+308
-1.3535751487940019e+308
-1.0076771554548313e+308
1.5997952344730588e+308
8.781329881346274e+307
-1.3977246332351983e+308
-1.751345981843834e+308
-9.631105926402765e+307
5.030474460950956e+307
3.876000984935831e+307
-1.1535064513352566e+308
1.3875544571022683e+308
-4.648007116071519e+307
7.188399232752114e+307
-1.3574878601546032e+308
1.261589184475622e+308
-1.6771816056107048e+308
-2.42151768274873e+307
1.1920696411173799e+308
-1.3300938482110913e+308
-4.086526852707076e+306
1.5138365057324555e+308
-1.7831898065982803e+308
-1.5282247902123299e+308
2.74415810998631e+307
-7.700957625830366e+307
-6.025008154543404e+307
-9.018143289448598e+307
1.7196416203371837e+308
4.437871976111745e+307
5.198598612029313e+307
1.2541837395241708e+308
-1.8320076381127488e+307
-6.794426608480807e+307
1.3939903945166529e+308
6.255768911187045e+306
-1.4041471148240002e+308
-1.0247217122729754e+307
1.0562505691933051e+308
-9.862600142373213e+307
-1.9262745415816453e+307
1.1526780768769353e+308
1.163069460741152e+308
-1.636561386523683e+308
4.2476422348216977e+307
1.4410000066850539e+308
2.860856778503435e+307
-1.5866460164755353e+308
1.6503501024802302e+308
5.426324032221941e+307
-3.603715626519023e+307
1.323903837439158e+308
5.0449013048191815e+305
9.551754924809232e+307
-1.0543348710831613e+308
-1.642940515370404e+306
1.4550744333101965e+308
8.182620662559106e+307
-8.922210718825109e+307
9.040087837966524e+307
-5.36823685782382e+307
-4.802679973452924e+307
-1.3546873332103518e+308
1.2611247332949247e+307
1.6504146962965598e+308
8.925768707654734e+307
6.060864720400443e+307
1.1301702437308016e+308
6.105902625074679e+307
-1.674967049759634e+308
8.745158550227989e+307
1.1208811120768472e+307
-1.2102992440400202e+308
1.0776478306055392e+308
5.628120988763797e+307
-1.4407082690504483e+308
4.193133448091252e+307
-5.794148903093446e+307
1.5698645197590104e+307
9.859992431318722e+307
-9.178064834795386e+307
-1.5420679636315293e+308
-1.617161482409336e+308
1.460437073524614e+308
2.8185445872762836e+306
-5.367650929597339e+306
9.609881583583266e+307
5.657253317822904e+307
-1.5686427694906407e+308
-6.783812982876687e+307
4.375877840364708e+307
1.7149998628682812e+308
-3.099088507108448e+307
-1.679346515941985e+308
1.7124637777922935e+308
1.783875652982286e+307
-1.4394015012167398e+308
1.6758357523528137e+308

As you can see from the sample result, every single one of them are either e+307 or e+308. I've noticed this from several different runs, from both local and go playground.

What did you expect to see?

Something more random? I'm not sure if this is something "expected"/"intended", or a bug.

What did you see instead?

@AlexRouSg
Copy link
Contributor

AlexRouSg commented May 14, 2021

If you run quick.Check in a loop, within a reasonable amount of time the range is between +300 and +308

e.g. https://play.golang.org/p/7jArGyIlWjk (do not run in playground due to timeouts)

You can also provide your own random number generator through https://golang.org/pkg/testing/quick/#Config

@ALTree
Copy link
Member

ALTree commented May 14, 2021

testing/quick generates float64 values as

rand.Float64() * math.MaxFloat64

which of course is heavily biased towards big numbers (because ieee-754 numbers are not uniformly spaced).

0.06 * math.MaxFloat64 already has e+307 as the exponent, so in practice you only have a ~4% chance to see a number with exponent less than 307.

That's not a great way to generate random ieee-754 floats (precisely due to this bias towards big exponents), but the testing/quick package is frozen:

The testing/quick package is frozen and is not accepting new features.

so I don't think this will be changed.

@ALTree ALTree added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label May 14, 2021
@fishy
Copy link
Author

fishy commented May 14, 2021

testing/quick generates float64 values as

rand.Float64() * math.MaxFloat64

which of course is heavily biased towards big numbers (because ieee-754 numbers are not uniformly spaced).

0.06 * math.MaxFloat64 already has e+307 as the exponent, so in practice you only have a ~4% chance to see a number with exponent less than 307.

That's not a great way to generate random ieee-754 floats (precisely due to this bias towards big exponents), but the testing/quick package is frozen:

The testing/quick package is frozen and is not accepting new features.

so I don't think this will be changed.

Thanks! Yes I think that explained it.

So 1e309 is actually larger than math.MaxFloat64, and 1e307 / math.MaxFloat64 is roughly 0.05562684646268004, so indeed there's only less than 6% chance random float64 generated this way has an exponent less than 307.

Please feel free to close this issue.

@ALTree ALTree closed this as completed May 14, 2021
@golang golang locked and limited conversation to collaborators May 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

4 participants