1// Copyright 2020 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build ignore
16
17package main
18
19// print-render-number-f64-tests.go prints the
20// test_wuffs_strconv_render_number_f64 test cases.
21//
22// Usage: go run print-render-number-f64-tests.go
23
24import (
25	"fmt"
26	"math"
27	"os"
28	"sort"
29	"strconv"
30)
31
32func main() {
33	if err := main1(); err != nil {
34		os.Stderr.WriteString(err.Error() + "\n")
35		os.Exit(1)
36	}
37}
38
39func main1() error {
40	testCases := append([]uint64(nil), u64TestCases...)
41	for _, f := range f64TestCases {
42		testCases = append(testCases, math.Float64bits(f))
43	}
44
45	sort.Slice(testCases, func(i int, j int) bool {
46		return testCases[i] < testCases[j]
47	})
48
49	for i, tc := range testCases {
50		f := math.Float64frombits(tc)
51
52		if (i > 0) && (tc == testCases[i-1]) {
53			return fmt.Errorf("duplicate test case (f=%g, tc=0x%X)", f, tc)
54		}
55
56		// Check that calling strconv.FormatFloat with a precision of -1 (round
57		// to shortest) does indeed return a string that, when parsed, recovers
58		// the original number.
59		shortest := strconv.FormatFloat(f, 'g', -1, 64)
60		g, err := strconv.ParseFloat(shortest, 64)
61		if err != nil {
62			return fmt.Errorf("ParseFloat failed (f=%g, tc=0x%X): %v", f, tc, err)
63		}
64		equal := tc == math.Float64bits(g)
65		if math.IsNaN(f) {
66			equal = math.IsNaN(g)
67		}
68		if !equal {
69			return fmt.Errorf("round-trip failed (f=%g, tc=0x%X)", f, tc)
70		}
71	}
72
73	for _, tc := range testCases {
74		f := math.Float64frombits(tc)
75		fmt.Printf(`{
76	.x = 0x%016X,
77	.want__e = %s,
78	.want__f = %s,
79	.want_0g = %s,
80	.want_2e = %s,
81	.want_3f = %s,
82	.want_4g = %s,
83},`+"\n",
84			tc,
85			do(f, -1, 'e'),
86			do(f, -1, 'f'),
87			do(f, +0, 'g'),
88			do(f, +2, 'e'),
89			do(f, +3, 'f'),
90			do(f, +4, 'g'),
91		)
92	}
93	return nil
94}
95
96func do(f float64, precision int, format byte) (ret string) {
97	s := strconv.FormatFloat(f, format, precision, 64)
98	for ; len(s) > 50; s = s[50:] {
99		ret += fmt.Sprintf("%q\n\t\t", s[:50])
100	}
101	ret += fmt.Sprintf("%q", s)
102	if ret == `"+Inf"` {
103		ret = `"Inf"`
104	}
105	return ret
106}
107
108var f64TestCases = []float64{
109	// Approximations of e, the base of the natural logarithm.
110	2.7,
111	2.72,
112	2.718,
113	2.7183,
114	2.71828,
115	2.718282,
116	2.7182818,
117	2.71828183,
118
119	// Approximations of N_A, the Avogadro constant.
120	6.0e23,
121	6.02e23,
122	6.022e23,
123	6.0221e23,
124	6.02214e23,
125	6.022141e23,
126	6.0221408e23,
127	6.02214076e23,
128}
129
130var u64TestCases = []uint64{
131	0x0000000000000000,
132	0x0000000000000001,
133	0x0000000000000002,
134	0x0000000000000003,
135	0x000730D67819E8D2,
136	0x000FFFFFFFFFFFFF,
137	0x0010000000000000,
138	0x0031FA182C40C60D,
139	0x369C314ABE948EB1,
140	0x3F88000000000000,
141	0x3FD0000000000000,
142	0x3FD3333333333333,
143	0x3FD3333333333334,
144	0x3FD5555555555555,
145	0x3FEFFFFFFFFFFFFF,
146	0x3FF0000000000000,
147	0x3FF0000000000001,
148	0x3FF0000000000002,
149	0x3FF4000000000000,
150	0x3FF8000000000000,
151	0x4008000000000000,
152	0x400921F9F01B866E,
153	0x400921FB54442D11,
154	0x400921FB54442D18,
155	0x400C000000000000,
156	0x4014000000000000,
157	0x4036000000000000,
158	0x4037000000000000,
159	0x4038000000000000,
160	0x40FE240C9FCB0C02,
161	0x41E0246690000001,
162	0x4202A05F20000000,
163	0x4330000000000000,
164	0x4330000000000001,
165	0x4330000000000002,
166	0x433FFFFFFFFFFFFE,
167	0x433FFFFFFFFFFFFF,
168	0x4340000000000000,
169	0x4340000000000001,
170	0x4340000000000002,
171	0x4370000000000000,
172	0x43F002F1776DDA67,
173	0x4415AF1D78B58C40,
174	0x44B52D02C7E14AF6,
175	0x46293E5939A08CEA,
176	0x54B249AD2594C37D,
177	0x7BBA44DF832B8D46,
178	0x7BF06B0BB1FB384C,
179	0x7C2485CE9E7A065F,
180	0x7FAC7B1F3CAC7433,
181	0x7FE1CCF385EBC8A0,
182	0x7FEFFFFFFFFFFFFF,
183	0x7FF0000000000000,
184	0x7FFFFFFFFFFFFFFF,
185	0x8000000000000000,
186	0xC008000000000000,
187	0xFFF0000000000000,
188	0xFFFFFFFFFFFFFFFF,
189}
190