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.
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) {
39 1.9999999999999998, // all 1s mantissa
40 1.3333333333333333, // 1.010101010101...
41 1.1428571428571428, // 1.001001001001...
42 1.112536929253601e-308, // first normal
73 all := make([]float64, 200)
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))
116 // There's no right answer for out of range.
117 // Match the hardware to pass the test.
123 // float64 -hw-> int64 -sw-> float64
124 func fromint64sw(f float64) float64 {
125 return math.Float64frombits(Fintto64(int64(f)))
130 func err(t *testing.T, format string, args ...any) {
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
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 {
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)
162 func testu(t *testing.T, op string, hw, sw func(float64) float64, v float64) {
166 err(t, "%s %g = sw %g, hw %g\n", op, v, s, h)
170 func hwcmp(f, g float64) (cmp int, isnan bool) {
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 int32(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) {
194 if math.Copysign(1, f) != math.Copysign(1, g) {