1// runoutput
2
3// Copyright 2012 The Go Authors.  All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Issue 3804
8// test all possible float -> integer conversions
9
10package main
11
12import (
13	"bytes"
14	"fmt"
15	"strings"
16)
17
18var (
19	intWidths = []int{8, 16, 32, 64} // int%d and uint%d
20	floatWidths = []int{32, 64} // float%d
21)
22
23func main() {
24
25	var names, funcs bytes.Buffer
26
27	for _, iWidth := range intWidths {
28		for _, typ := range []string{"int", "uint"} {
29			var segs bytes.Buffer
30			itype := fmt.Sprintf("%s%d", typ, iWidth)
31			names.WriteString("\ttest" + itype + ",\n")
32			for _, fWidth := range floatWidths {
33				ftype := fmt.Sprintf("float%d", fWidth)
34				seg := strings.Replace(testSegment, "$F", ftype, -1)
35				seg = strings.Replace(seg, "$I", itype, -1)
36				segs.WriteString(seg)
37			}
38			body := strings.Replace(testFunc, "$I", itype, -1)
39			if typ[0] == 'u' {
40				body = strings.Replace(body, "$TEST", " || i < 0", 1)
41			} else {
42				body = strings.Replace(body, "$TEST", "", 1)
43			}
44			body = strings.Replace(body, "$TESTSEGMENTS", segs.String(), 1)
45			funcs.WriteString(body)
46		}
47	}
48
49	program = strings.Replace(program, "$NAMES", names.String(), 1)
50	program = strings.Replace(program, "$FUNCS", funcs.String(), 1)
51	fmt.Print(program)
52}
53
54const testSegment = `
55	f$F := $F(f)
56	if math.Abs(float64(f$F) - f) < 0.05 {
57		if v := $I(f$F); v != $I(i) {
58			fmt.Printf("$I($F(%f)) = %v, expected %v\n", f, v, i)
59		}
60	}`
61
62const testFunc =
63`func test$I(f float64, i int64) {
64	if i != int64($I(i))$TEST {
65		return
66	}
67$TESTSEGMENTS
68}
69`
70
71var program =
72`package main
73
74import (
75	"fmt"
76	"math"
77)
78
79var tests = []struct {
80	f float64
81	i int64
82}{
83	{39.7, 39},
84	{-39.7, -39},
85	{258.6, 258},
86	{-258.6, -258},
87	{65538.9, 65538},
88	{-65538.9, -65538},
89	{4294967298.8, 4294967298},
90	{-4294967298.8, -4294967298},
91}
92
93var funcs = []func(float64, int64){
94$NAMES
95}
96
97$FUNCS
98func main() {
99	for _, t := range tests {
100		for _, f := range funcs {
101			f(t.f, t.i)
102		}
103	}
104}
105`
106