Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / strconv / fp_test.go
blob305adcc0c41068b0df134f7ed22cb671eabaf691
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package strconv_test
7 import (
8 "bufio"
9 "fmt"
10 "os"
11 "strconv"
12 "strings"
13 "testing"
16 func pow2(i int) float64 {
17 switch {
18 case i < 0:
19 return 1 / pow2(-i)
20 case i == 0:
21 return 1
22 case i == 1:
23 return 2
25 return pow2(i/2) * pow2(i-i/2)
28 // Wrapper around strconv.Atof64. Handles dddddp+ddd (binary exponent)
29 // itself, passes the rest on to strconv.Atof64.
30 func myatof64(s string) (f float64, ok bool) {
31 a := strings.Split(s, "p", 2)
32 if len(a) == 2 {
33 n, err := strconv.Atoi64(a[0])
34 if err != nil {
35 return 0, false
37 e, err1 := strconv.Atoi(a[1])
38 if err1 != nil {
39 println("bad e", a[1])
40 return 0, false
42 v := float64(n)
43 // We expect that v*pow2(e) fits in a float64,
44 // but pow2(e) by itself may not. Be careful.
45 if e <= -1000 {
46 v *= pow2(-1000)
47 e += 1000
48 for e < 0 {
49 v /= 2
50 e++
52 return v, true
54 if e >= 1000 {
55 v *= pow2(1000)
56 e -= 1000
57 for e > 0 {
58 v *= 2
59 e--
61 return v, true
63 return v * pow2(e), true
65 f1, err := strconv.Atof64(s)
66 if err != nil {
67 return 0, false
69 return f1, true
72 // Wrapper around strconv.Atof32. Handles dddddp+ddd (binary exponent)
73 // itself, passes the rest on to strconv.Atof32.
74 func myatof32(s string) (f float32, ok bool) {
75 a := strings.Split(s, "p", 2)
76 if len(a) == 2 {
77 n, err := strconv.Atoi(a[0])
78 if err != nil {
79 println("bad n", a[0])
80 return 0, false
82 e, err1 := strconv.Atoi(a[1])
83 if err1 != nil {
84 println("bad p", a[1])
85 return 0, false
87 return float32(float64(n) * pow2(e)), true
89 f1, err1 := strconv.Atof32(s)
90 if err1 != nil {
91 return 0, false
93 return f1, true
96 func TestFp(t *testing.T) {
97 f, err := os.Open("testfp.txt", os.O_RDONLY, 0)
98 if err != nil {
99 t.Fatal("testfp: open testfp.txt:", err.String())
101 defer f.Close()
103 b := bufio.NewReader(f)
105 lineno := 0
106 for {
107 line, err2 := b.ReadString('\n')
108 if err2 == os.EOF {
109 break
111 if err2 != nil {
112 t.Fatal("testfp: read testfp.txt: " + err2.String())
114 line = line[0 : len(line)-1]
115 lineno++
116 if len(line) == 0 || line[0] == '#' {
117 continue
119 a := strings.Split(line, " ", -1)
120 if len(a) != 4 {
121 t.Error("testfp.txt:", lineno, ": wrong field count")
122 continue
124 var s string
125 var v float64
126 switch a[0] {
127 case "float64":
128 var ok bool
129 v, ok = myatof64(a[2])
130 if !ok {
131 t.Error("testfp.txt:", lineno, ": cannot atof64 ", a[2])
132 continue
134 s = fmt.Sprintf(a[1], v)
135 case "float32":
136 v1, ok := myatof32(a[2])
137 if !ok {
138 t.Error("testfp.txt:", lineno, ": cannot atof32 ", a[2])
139 continue
141 s = fmt.Sprintf(a[1], v1)
142 v = float64(v1)
144 if s != a[3] {
145 t.Error("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
146 "want ", a[3], " got ", s)