mirror of
https://github.com/golang/go
synced 2024-11-25 11:37:57 -07:00
5e21cb7865
Don't measure wall time in map.go. Keep it portable and only test NaN, but not time. Move time tests to mapnan.go and only measure user CPU time, not wall time. It builds on Darwin and Linux, the primary platforms where people hack on the runtime & in particular maps. The runtime is shared, though, so we don't need it to run on all of the platforms. Fixes flaky build failures like: http://build.golang.org/log/ba67eceefdeaa1142cb6c990a62fa3ffd8fd73f8 R=golang-dev, r CC=golang-dev https://golang.org/cl/8479043
685 lines
15 KiB
Go
685 lines
15 KiB
Go
// run
|
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Test maps, almost exhaustively.
|
|
// NaN complexity test is in mapnan.go.
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
)
|
|
|
|
const count = 100
|
|
|
|
func P(a []string) string {
|
|
s := "{"
|
|
for i := 0; i < len(a); i++ {
|
|
if i > 0 {
|
|
s += ","
|
|
}
|
|
s += `"` + a[i] + `"`
|
|
}
|
|
s += "}"
|
|
return s
|
|
}
|
|
|
|
func main() {
|
|
testbasic()
|
|
testfloat()
|
|
testnan()
|
|
}
|
|
|
|
func testbasic() {
|
|
// Test a map literal.
|
|
mlit := map[string]int{"0": 0, "1": 1, "2": 2, "3": 3, "4": 4}
|
|
for i := 0; i < len(mlit); i++ {
|
|
s := string([]byte{byte(i) + '0'})
|
|
if mlit[s] != i {
|
|
panic(fmt.Sprintf("mlit[%s] = %d\n", s, mlit[s]))
|
|
}
|
|
}
|
|
|
|
mib := make(map[int]bool)
|
|
mii := make(map[int]int)
|
|
mfi := make(map[float32]int)
|
|
mif := make(map[int]float32)
|
|
msi := make(map[string]int)
|
|
mis := make(map[int]string)
|
|
mss := make(map[string]string)
|
|
mspa := make(map[string][]string)
|
|
// BUG need an interface map both ways too
|
|
|
|
type T struct {
|
|
i int64 // can't use string here; struct values are only compared at the top level
|
|
f float32
|
|
}
|
|
mipT := make(map[int]*T)
|
|
mpTi := make(map[*T]int)
|
|
mit := make(map[int]T)
|
|
// mti := make(map[T] int)
|
|
|
|
type M map[int]int
|
|
mipM := make(map[int]M)
|
|
|
|
var apT [2 * count]*T
|
|
|
|
for i := 0; i < count; i++ {
|
|
s := strconv.Itoa(i)
|
|
s10 := strconv.Itoa(i * 10)
|
|
f := float32(i)
|
|
t := T{int64(i), f}
|
|
apT[i] = new(T)
|
|
apT[i].i = int64(i)
|
|
apT[i].f = f
|
|
apT[2*i] = new(T) // need twice as many entries as we use, for the nonexistence check
|
|
apT[2*i].i = int64(i)
|
|
apT[2*i].f = f
|
|
m := M{i: i + 1}
|
|
mib[i] = (i != 0)
|
|
mii[i] = 10 * i
|
|
mfi[float32(i)] = 10 * i
|
|
mif[i] = 10.0 * f
|
|
mis[i] = s
|
|
msi[s] = i
|
|
mss[s] = s10
|
|
mss[s] = s10
|
|
as := make([]string, 2)
|
|
as[0] = s10
|
|
as[1] = s10
|
|
mspa[s] = as
|
|
mipT[i] = apT[i]
|
|
mpTi[apT[i]] = i
|
|
mipM[i] = m
|
|
mit[i] = t
|
|
// mti[t] = i
|
|
}
|
|
|
|
// test len
|
|
if len(mib) != count {
|
|
panic(fmt.Sprintf("len(mib) = %d\n", len(mib)))
|
|
}
|
|
if len(mii) != count {
|
|
panic(fmt.Sprintf("len(mii) = %d\n", len(mii)))
|
|
}
|
|
if len(mfi) != count {
|
|
panic(fmt.Sprintf("len(mfi) = %d\n", len(mfi)))
|
|
}
|
|
if len(mif) != count {
|
|
panic(fmt.Sprintf("len(mif) = %d\n", len(mif)))
|
|
}
|
|
if len(msi) != count {
|
|
panic(fmt.Sprintf("len(msi) = %d\n", len(msi)))
|
|
}
|
|
if len(mis) != count {
|
|
panic(fmt.Sprintf("len(mis) = %d\n", len(mis)))
|
|
}
|
|
if len(mss) != count {
|
|
panic(fmt.Sprintf("len(mss) = %d\n", len(mss)))
|
|
}
|
|
if len(mspa) != count {
|
|
panic(fmt.Sprintf("len(mspa) = %d\n", len(mspa)))
|
|
}
|
|
if len(mipT) != count {
|
|
panic(fmt.Sprintf("len(mipT) = %d\n", len(mipT)))
|
|
}
|
|
if len(mpTi) != count {
|
|
panic(fmt.Sprintf("len(mpTi) = %d\n", len(mpTi)))
|
|
}
|
|
// if len(mti) != count {
|
|
// panic(fmt.Sprintf("len(mti) = %d\n", len(mti)))
|
|
// }
|
|
if len(mipM) != count {
|
|
panic(fmt.Sprintf("len(mipM) = %d\n", len(mipM)))
|
|
}
|
|
// if len(mti) != count {
|
|
// panic(fmt.Sprintf("len(mti) = %d\n", len(mti)))
|
|
// }
|
|
if len(mit) != count {
|
|
panic(fmt.Sprintf("len(mit) = %d\n", len(mit)))
|
|
}
|
|
|
|
// test construction directly
|
|
for i := 0; i < count; i++ {
|
|
s := strconv.Itoa(i)
|
|
s10 := strconv.Itoa(i * 10)
|
|
f := float32(i)
|
|
// BUG m := M(i, i+1)
|
|
if mib[i] != (i != 0) {
|
|
panic(fmt.Sprintf("mib[%d] = %t\n", i, mib[i]))
|
|
}
|
|
if mii[i] != 10*i {
|
|
panic(fmt.Sprintf("mii[%d] = %d\n", i, mii[i]))
|
|
}
|
|
if mfi[f] != 10*i {
|
|
panic(fmt.Sprintf("mfi[%d] = %d\n", i, mfi[f]))
|
|
}
|
|
if mif[i] != 10.0*f {
|
|
panic(fmt.Sprintf("mif[%d] = %g\n", i, mif[i]))
|
|
}
|
|
if mis[i] != s {
|
|
panic(fmt.Sprintf("mis[%d] = %s\n", i, mis[i]))
|
|
}
|
|
if msi[s] != i {
|
|
panic(fmt.Sprintf("msi[%s] = %d\n", s, msi[s]))
|
|
}
|
|
if mss[s] != s10 {
|
|
panic(fmt.Sprintf("mss[%s] = %g\n", s, mss[s]))
|
|
}
|
|
for j := 0; j < len(mspa[s]); j++ {
|
|
if mspa[s][j] != s10 {
|
|
panic(fmt.Sprintf("mspa[%s][%d] = %s\n", s, j, mspa[s][j]))
|
|
}
|
|
}
|
|
if mipT[i].i != int64(i) || mipT[i].f != f {
|
|
panic(fmt.Sprintf("mipT[%d] = %v\n", i, mipT[i]))
|
|
}
|
|
if mpTi[apT[i]] != i {
|
|
panic(fmt.Sprintf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]]))
|
|
}
|
|
// if(mti[t] != i) {
|
|
// panic(fmt.Sprintf("mti[%s] = %s\n", s, mti[t]))
|
|
// }
|
|
if mipM[i][i] != i+1 {
|
|
panic(fmt.Sprintf("mipM[%d][%d] = %d\n", i, i, mipM[i][i]))
|
|
}
|
|
// if(mti[t] != i) {
|
|
// panic(fmt.Sprintf("mti[%v] = %d\n", t, mti[t]))
|
|
// }
|
|
if mit[i].i != int64(i) || mit[i].f != f {
|
|
panic(fmt.Sprintf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f))
|
|
}
|
|
}
|
|
|
|
// test existence with tuple check
|
|
// failed lookups yield a false value for the boolean.
|
|
for i := 0; i < count; i++ {
|
|
s := strconv.Itoa(i)
|
|
f := float32(i)
|
|
{
|
|
_, b := mib[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mib[%d]\n", i))
|
|
}
|
|
_, b = mib[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mib[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mii[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mii[%d]\n", i))
|
|
}
|
|
_, b = mii[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mii[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mfi[f]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mfi[%d]\n", i))
|
|
}
|
|
_, b = mfi[f]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mfi[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mif[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mif[%d]\n", i))
|
|
}
|
|
_, b = mif[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mif[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mis[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mis[%d]\n", i))
|
|
}
|
|
_, b = mis[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mis[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := msi[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: msi[%d]\n", i))
|
|
}
|
|
_, b = msi[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: msi[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mss[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mss[%d]\n", i))
|
|
}
|
|
_, b = mss[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mss[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mspa[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mspa[%d]\n", i))
|
|
}
|
|
_, b = mspa[s]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mspa[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mipT[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mipT[%d]\n", i))
|
|
}
|
|
_, b = mipT[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mipT[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mpTi[apT[i]]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mpTi[apT[%d]]\n", i))
|
|
}
|
|
_, b = mpTi[apT[i]]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mpTi[apT[%d]]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mipM[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mipM[%d]\n", i))
|
|
}
|
|
_, b = mipM[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mipM[%d]\n", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mit[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence decl: mit[%d]\n", i))
|
|
}
|
|
_, b = mit[i]
|
|
if !b {
|
|
panic(fmt.Sprintf("tuple existence assign: mit[%d]\n", i))
|
|
}
|
|
}
|
|
// {
|
|
// _, b := mti[t]
|
|
// if !b {
|
|
// panic(fmt.Sprintf("tuple existence decl: mti[%d]\n", i))
|
|
// }
|
|
// _, b = mti[t]
|
|
// if !b {
|
|
// panic(fmt.Sprintf("tuple existence assign: mti[%d]\n", i))
|
|
// }
|
|
// }
|
|
}
|
|
|
|
// test nonexistence with tuple check
|
|
// failed lookups yield a false value for the boolean.
|
|
for i := count; i < 2*count; i++ {
|
|
s := strconv.Itoa(i)
|
|
f := float32(i)
|
|
{
|
|
_, b := mib[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mib[%d]", i))
|
|
}
|
|
_, b = mib[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mib[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mii[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mii[%d]", i))
|
|
}
|
|
_, b = mii[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mii[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mfi[f]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mfi[%d]", i))
|
|
}
|
|
_, b = mfi[f]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mfi[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mif[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mif[%d]", i))
|
|
}
|
|
_, b = mif[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mif[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mis[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mis[%d]", i))
|
|
}
|
|
_, b = mis[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mis[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := msi[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: msi[%d]", i))
|
|
}
|
|
_, b = msi[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: msi[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mss[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mss[%d]", i))
|
|
}
|
|
_, b = mss[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mss[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mspa[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mspa[%d]", i))
|
|
}
|
|
_, b = mspa[s]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mspa[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mipT[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mipT[%d]", i))
|
|
}
|
|
_, b = mipT[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mipT[%d]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mpTi[apT[i]]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mpTi[apt[%d]]", i))
|
|
}
|
|
_, b = mpTi[apT[i]]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mpTi[apT[%d]]", i))
|
|
}
|
|
}
|
|
{
|
|
_, b := mipM[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mipM[%d]", i))
|
|
}
|
|
_, b = mipM[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mipM[%d]", i))
|
|
}
|
|
}
|
|
// {
|
|
// _, b := mti[t]
|
|
// if b {
|
|
// panic(fmt.Sprintf("tuple nonexistence decl: mti[%d]", i))
|
|
// }
|
|
// _, b = mti[t]
|
|
// if b {
|
|
// panic(fmt.Sprintf("tuple nonexistence assign: mti[%d]", i))
|
|
// }
|
|
// }
|
|
{
|
|
_, b := mit[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence decl: mit[%d]", i))
|
|
}
|
|
_, b = mit[i]
|
|
if b {
|
|
panic(fmt.Sprintf("tuple nonexistence assign: mit[%d]", i))
|
|
}
|
|
}
|
|
}
|
|
|
|
// tests for structured map element updates
|
|
for i := 0; i < count; i++ {
|
|
s := strconv.Itoa(i)
|
|
mspa[s][i%2] = "deleted"
|
|
if mspa[s][i%2] != "deleted" {
|
|
panic(fmt.Sprintf("update mspa[%s][%d] = %s\n", s, i%2, mspa[s][i%2]))
|
|
|
|
}
|
|
|
|
mipT[i].i += 1
|
|
if mipT[i].i != int64(i)+1 {
|
|
panic(fmt.Sprintf("update mipT[%d].i = %d\n", i, mipT[i].i))
|
|
|
|
}
|
|
mipT[i].f = float32(i + 1)
|
|
if mipT[i].f != float32(i+1) {
|
|
panic(fmt.Sprintf("update mipT[%d].f = %g\n", i, mipT[i].f))
|
|
|
|
}
|
|
|
|
mipM[i][i]++
|
|
if mipM[i][i] != (i+1)+1 {
|
|
panic(fmt.Sprintf("update mipM[%d][%d] = %d\n", i, i, mipM[i][i]))
|
|
|
|
}
|
|
}
|
|
|
|
// test range on nil map
|
|
var mnil map[string]int
|
|
for _, _ = range mnil {
|
|
panic("range mnil")
|
|
}
|
|
}
|
|
|
|
func testfloat() {
|
|
// Test floating point numbers in maps.
|
|
// Two map keys refer to the same entry if the keys are ==.
|
|
// The special cases, then, are that +0 == -0 and that NaN != NaN.
|
|
|
|
{
|
|
var (
|
|
pz = float32(0)
|
|
nz = math.Float32frombits(1 << 31)
|
|
nana = float32(math.NaN())
|
|
nanb = math.Float32frombits(math.Float32bits(nana) ^ 2)
|
|
)
|
|
|
|
m := map[float32]string{
|
|
pz: "+0",
|
|
nana: "NaN",
|
|
nanb: "NaN",
|
|
}
|
|
if m[pz] != "+0" {
|
|
panic(fmt.Sprintln("float32 map cannot read back m[+0]:", m[pz]))
|
|
}
|
|
if m[nz] != "+0" {
|
|
fmt.Sprintln("float32 map does not treat", pz, "and", nz, "as equal for read")
|
|
panic(fmt.Sprintln("float32 map does not treat -0 and +0 as equal for read"))
|
|
}
|
|
m[nz] = "-0"
|
|
if m[pz] != "-0" {
|
|
panic(fmt.Sprintln("float32 map does not treat -0 and +0 as equal for write"))
|
|
}
|
|
if _, ok := m[nana]; ok {
|
|
panic(fmt.Sprintln("float32 map allows NaN lookup (a)"))
|
|
}
|
|
if _, ok := m[nanb]; ok {
|
|
panic(fmt.Sprintln("float32 map allows NaN lookup (b)"))
|
|
}
|
|
if len(m) != 3 {
|
|
panic(fmt.Sprintln("float32 map should have 3 entries:", m))
|
|
}
|
|
m[nana] = "NaN"
|
|
m[nanb] = "NaN"
|
|
if len(m) != 5 {
|
|
panic(fmt.Sprintln("float32 map should have 5 entries:", m))
|
|
}
|
|
}
|
|
|
|
{
|
|
var (
|
|
pz = float64(0)
|
|
nz = math.Float64frombits(1 << 63)
|
|
nana = float64(math.NaN())
|
|
nanb = math.Float64frombits(math.Float64bits(nana) ^ 2)
|
|
)
|
|
|
|
m := map[float64]string{
|
|
pz: "+0",
|
|
nana: "NaN",
|
|
nanb: "NaN",
|
|
}
|
|
if m[nz] != "+0" {
|
|
panic(fmt.Sprintln("float64 map does not treat -0 and +0 as equal for read"))
|
|
}
|
|
m[nz] = "-0"
|
|
if m[pz] != "-0" {
|
|
panic(fmt.Sprintln("float64 map does not treat -0 and +0 as equal for write"))
|
|
}
|
|
if _, ok := m[nana]; ok {
|
|
panic(fmt.Sprintln("float64 map allows NaN lookup (a)"))
|
|
}
|
|
if _, ok := m[nanb]; ok {
|
|
panic(fmt.Sprintln("float64 map allows NaN lookup (b)"))
|
|
}
|
|
if len(m) != 3 {
|
|
panic(fmt.Sprintln("float64 map should have 3 entries:", m))
|
|
}
|
|
m[nana] = "NaN"
|
|
m[nanb] = "NaN"
|
|
if len(m) != 5 {
|
|
panic(fmt.Sprintln("float64 map should have 5 entries:", m))
|
|
}
|
|
}
|
|
|
|
{
|
|
var (
|
|
pz = complex64(0)
|
|
nz = complex(0, math.Float32frombits(1<<31))
|
|
nana = complex(5, float32(math.NaN()))
|
|
nanb = complex(5, math.Float32frombits(math.Float32bits(float32(math.NaN()))^2))
|
|
)
|
|
|
|
m := map[complex64]string{
|
|
pz: "+0",
|
|
nana: "NaN",
|
|
nanb: "NaN",
|
|
}
|
|
if m[nz] != "+0" {
|
|
panic(fmt.Sprintln("complex64 map does not treat -0 and +0 as equal for read"))
|
|
}
|
|
m[nz] = "-0"
|
|
if m[pz] != "-0" {
|
|
panic(fmt.Sprintln("complex64 map does not treat -0 and +0 as equal for write"))
|
|
}
|
|
if _, ok := m[nana]; ok {
|
|
panic(fmt.Sprintln("complex64 map allows NaN lookup (a)"))
|
|
}
|
|
if _, ok := m[nanb]; ok {
|
|
panic(fmt.Sprintln("complex64 map allows NaN lookup (b)"))
|
|
}
|
|
if len(m) != 3 {
|
|
panic(fmt.Sprintln("complex64 map should have 3 entries:", m))
|
|
}
|
|
m[nana] = "NaN"
|
|
m[nanb] = "NaN"
|
|
if len(m) != 5 {
|
|
panic(fmt.Sprintln("complex64 map should have 5 entries:", m))
|
|
}
|
|
}
|
|
|
|
{
|
|
var (
|
|
pz = complex128(0)
|
|
nz = complex(0, math.Float64frombits(1<<63))
|
|
nana = complex(5, float64(math.NaN()))
|
|
nanb = complex(5, math.Float64frombits(math.Float64bits(float64(math.NaN()))^2))
|
|
)
|
|
|
|
m := map[complex128]string{
|
|
pz: "+0",
|
|
nana: "NaN",
|
|
nanb: "NaN",
|
|
}
|
|
if m[nz] != "+0" {
|
|
panic(fmt.Sprintln("complex128 map does not treat -0 and +0 as equal for read"))
|
|
}
|
|
m[nz] = "-0"
|
|
if m[pz] != "-0" {
|
|
panic(fmt.Sprintln("complex128 map does not treat -0 and +0 as equal for write"))
|
|
}
|
|
if _, ok := m[nana]; ok {
|
|
panic(fmt.Sprintln("complex128 map allows NaN lookup (a)"))
|
|
}
|
|
if _, ok := m[nanb]; ok {
|
|
panic(fmt.Sprintln("complex128 map allows NaN lookup (b)"))
|
|
}
|
|
if len(m) != 3 {
|
|
panic(fmt.Sprintln("complex128 map should have 3 entries:", m))
|
|
}
|
|
m[nana] = "NaN"
|
|
m[nanb] = "NaN"
|
|
if len(m) != 5 {
|
|
panic(fmt.Sprintln("complex128 map should have 5 entries:", m))
|
|
}
|
|
}
|
|
}
|
|
|
|
func testnan() {
|
|
n := 500
|
|
m := map[float64]int{}
|
|
nan := math.NaN()
|
|
for i := 0; i < n; i++ {
|
|
m[nan] = 1
|
|
}
|
|
if len(m) != n {
|
|
panic("wrong size map after nan insertion")
|
|
}
|
|
iters := 0
|
|
for k, v := range m {
|
|
iters++
|
|
if !math.IsNaN(k) {
|
|
panic("not NaN")
|
|
}
|
|
if v != 1 {
|
|
panic("wrong value")
|
|
}
|
|
}
|
|
if iters != n {
|
|
panic("wrong number of nan range iters")
|
|
}
|
|
}
|