Rebase.
[official-gcc.git] / libgo / go / runtime / softfloat64_test.go
blobdf63010fbd5e9b0b55cedee8b9af302c10f0b424
1 // Copyright 2010 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 runtime_test
7 import (
8 "math"
9 "math/rand"
10 . "runtime"
11 "testing"
14 // turn uint64 op into float64 op
15 func fop(f func(x, y uint64) uint64) func(x, y float64) float64 {
16 return func(x, y float64) float64 {
17 bx := math.Float64bits(x)
18 by := math.Float64bits(y)
19 return math.Float64frombits(f(bx, by))
23 func add(x, y float64) float64 { return x + y }
24 func sub(x, y float64) float64 { return x - y }
25 func mul(x, y float64) float64 { return x * y }
26 func div(x, y float64) float64 { return x / y }
28 func TestFloat64(t *testing.T) {
29 base := []float64{
31 math.Copysign(0, -1),
32 -1,
34 math.NaN(),
35 math.Inf(+1),
36 math.Inf(-1),
37 0.1,
38 1.5,
39 1.9999999999999998, // all 1s mantissa
40 1.3333333333333333, // 1.010101010101...
41 1.1428571428571428, // 1.001001001001...
42 1.112536929253601e-308, // first normal
46 16,
47 32,
48 64,
49 128,
50 256,
52 12,
53 1234,
54 123456,
55 -0.1,
56 -1.5,
57 -1.9999999999999998,
58 -1.3333333333333333,
59 -1.1428571428571428,
60 -2,
61 -3,
62 1e-200,
63 1e-300,
64 1e-310,
65 5e-324,
66 1e-105,
67 1e-305,
68 1e+200,
69 1e+306,
70 1e+307,
71 1e+308,
73 all := make([]float64, 200)
74 copy(all, base)
75 for i := len(base); i < len(all); i++ {
76 all[i] = rand.NormFloat64()
79 test(t, "+", add, fop(Fadd64), all)
80 test(t, "-", sub, fop(Fsub64), all)
81 if GOARCH != "386" { // 386 is not precise!
82 test(t, "*", mul, fop(Fmul64), all)
83 test(t, "/", div, fop(Fdiv64), all)
87 // 64 -hw-> 32 -hw-> 64
88 func trunc32(f float64) float64 {
89 return float64(float32(f))
92 // 64 -sw->32 -hw-> 64
93 func to32sw(f float64) float64 {
94 return float64(math.Float32frombits(F64to32(math.Float64bits(f))))
97 // 64 -hw->32 -sw-> 64
98 func to64sw(f float64) float64 {
99 return math.Float64frombits(F32to64(math.Float32bits(float32(f))))
102 // float64 -hw-> int64 -hw-> float64
103 func hwint64(f float64) float64 {
104 return float64(int64(f))
107 // float64 -hw-> int32 -hw-> float64
108 func hwint32(f float64) float64 {
109 return float64(int32(f))
112 // float64 -sw-> int64 -hw-> float64
113 func toint64sw(f float64) float64 {
114 i, ok := F64toint(math.Float64bits(f))
115 if !ok {
116 // There's no right answer for out of range.
117 // Match the hardware to pass the test.
118 i = int64(f)
120 return float64(i)
123 // float64 -hw-> int64 -sw-> float64
124 func fromint64sw(f float64) float64 {
125 return math.Float64frombits(Fintto64(int64(f)))
128 var nerr int
130 func err(t *testing.T, format string, args ...interface{}) {
131 t.Errorf(format, args...)
133 // cut errors off after a while.
134 // otherwise we spend all our time
135 // allocating memory to hold the
136 // formatted output.
137 if nerr++; nerr >= 10 {
138 t.Fatal("too many errors")
142 func test(t *testing.T, op string, hw, sw func(float64, float64) float64, all []float64) {
143 for _, f := range all {
144 for _, g := range all {
145 h := hw(f, g)
146 s := sw(f, g)
147 if !same(h, s) {
148 err(t, "%g %s %g = sw %g, hw %g\n", f, op, g, s, h)
150 testu(t, "to32", trunc32, to32sw, h)
151 testu(t, "to64", trunc32, to64sw, h)
152 testu(t, "toint64", hwint64, toint64sw, h)
153 testu(t, "fromint64", hwint64, fromint64sw, h)
154 testcmp(t, f, h)
155 testcmp(t, h, f)
156 testcmp(t, g, h)
157 testcmp(t, h, g)
162 func testu(t *testing.T, op string, hw, sw func(float64) float64, v float64) {
163 h := hw(v)
164 s := sw(v)
165 if !same(h, s) {
166 err(t, "%s %g = sw %g, hw %g\n", op, v, s, h)
170 func hwcmp(f, g float64) (cmp int, isnan bool) {
171 switch {
172 case f < g:
173 return -1, false
174 case f > g:
175 return +1, false
176 case f == g:
177 return 0, false
179 return 0, true // must be NaN
182 func testcmp(t *testing.T, f, g float64) {
183 hcmp, hisnan := hwcmp(f, g)
184 scmp, sisnan := Fcmp64(math.Float64bits(f), math.Float64bits(g))
185 if hcmp != scmp || hisnan != sisnan {
186 err(t, "cmp(%g, %g) = sw %v, %v, hw %v, %v\n", f, g, scmp, sisnan, hcmp, hisnan)
190 func same(f, g float64) bool {
191 if math.IsNaN(f) && math.IsNaN(g) {
192 return true
194 if math.Copysign(1, f) != math.Copysign(1, g) {
195 return false
197 return f == g