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
...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
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 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
) {