-
Notifications
You must be signed in to change notification settings - Fork 0
/
fma_test.go
93 lines (81 loc) · 3.97 KB
/
fma_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package fma
import (
. "math"
"testing"
)
// Test cases were generated with Berkeley TestFloat-3e/testfloat_gen.
// http://www.jhauser.us/arithmetic/TestFloat.html.
// The default rounding mode is selected (nearest/even), and exception flags are ignored.
var fmaC = []struct{ x, y, z, want float64 }{
// Large exponent spread
{-3.999999999999087, -1.1123914289620494e-16, -7.999877929687506, -7.999877929687505},
{-262112.0000004768, -0.06251525855623184, 1.1102230248837136e-16, 16385.99945072085},
{-6.462348523533467e-27, -2.3763644720331857e-211, 4.000000000931324, 4.000000000931324},
// Effective addition
{-2.0000000037252907, 6.7904383376e-313, -3.3951933161e-313, -1.697607001654e-312},
{-0.12499999999999999, 512.007568359375, -1.4193627164960366e-16, -64.00094604492188},
{-2.7550648847397148e-39, -3.4028301595800694e+38, 0.9960937495343386, 1.9335955376735676},
{5.723369164769208e+24, 3.8149300927159385e-06, 1.84489958778182e+19, 4.028324913621874e+19},
{-0.4843749999990904, -3.6893487872543293e+19, 9.223653786709391e+18, 2.7093936974938993e+19},
{-3.8146972665201165e-06, 4.2949672959999385e+09, -2.2204460489938386e-16, -16384.000003844263},
{6.98156394130982e-309, -1.1072962560000002e+09, -4.4414561548793455e-308, -7.73065965765153e-300},
// Effective subtraction
{5e-324, 4.5, -2e-323, 0},
{5e-324, 7, -3.5e-323, 0},
{5e-324, 0.5000000000000001, -5e-324, Copysign(0, -1)},
{-2.1240680525e-314, -1.233647078189316e+308, -0.25781249999954525, -0.25780987964919844},
{8.579992955364441e-308, 0.6037391876780558, -4.4501307410480706e-308, 7.29947236107098e-309},
{-4.450143471986689e-308, -0.9960937499927239, -4.450419332475649e-308, -1.7659233458788e-310},
{1.4932076393918112, -2.2248022430460833e-308, 4.449875571054211e-308, 1.127783865601762e-308},
// Overflow
{-2.288020632214759e+38, -8.98846570988901e+307, 1.7696041796300924e+308, Inf(0)},
{1.4888652783208255e+308, -9.007199254742012e+15, -6.807282911929205e+38, Inf(-1)},
{9.142703268902826e+192, -1.3504889569802838e+296, -1.9082200803806996e-89, Inf(-1)},
// Finite x and y, but non-finite z.
{31.99218749627471, -1.7976930544991702e+308, Inf(0), Inf(0)},
{-1.7976931281784667e+308, -2.0009765625002265, Inf(-1), Inf(-1)},
// Special
{0, 0, 0, 0},
{-1.1754226043408471e-38, NaN(), Inf(0), NaN()},
{0, 0, 2.22507385643494e-308, 2.22507385643494e-308},
{-8.65697792e+09, NaN(), -7.516192799999999e+09, NaN()},
{-0.00012207403779029757, 3.221225471996093e+09, NaN(), NaN()},
{Inf(-1), 0.1252441407414153, -1.387184532981584e-76, Inf(-1)},
{Inf(0), 1.525878907671432e-05, -9.214364835452549e+18, Inf(0)},
// Random
{0.1777916152213626, -32.000015266239636, -2.2204459148334633e-16, -5.689334401293007},
{-2.0816681711722314e-16, -0.4997558592585846, -0.9465627129124969, -0.9465627129124968},
{-1.9999997615814211, 1.8518819259933516e+19, 16.874999999999996, -3.703763410463646e+19},
{-0.12499994039717421, 32767.99999976135, -2.0752587082923246e+19, -2.075258708292325e+19},
{7.705600568510257e-34, -1.801432979000528e+16, -0.17224197722973714, -0.17224197722973716},
{3.8988133103758913e-308, -0.9848632812499999, 3.893879244098556e-308, 5.40811742605814e-310},
{-0.012651981190687427, 6.911985574912436e+38, 6.669240527007144e+18, -8.745031148409496e+36},
{4.612811918325842e+18, 1.4901161193847641e-08, 2.6077032311277997e-08, 6.873625395187494e+10},
{-9.094947033611148e-13, 4.450691014249257e-308, 2.086006742350485e-308, 2.086006742346437e-308},
{-7.751454006381804e-05, 5.588653777189071e-308, -2.2207280111272877e-308, -2.2211612130544025e-308},
}
func alike(a, b float64) bool {
switch {
case IsNaN(a) && IsNaN(b):
return true
case a == b:
return Signbit(a) == Signbit(b)
}
return false
}
func TestFma(t *testing.T) {
for _, c := range fmaC {
got := Fma(c.x, c.y, c.z)
if !alike(got, c.want) {
t.Errorf("Fma(%g,%g,%g) == %g; want %g", c.x, c.y, c.z, got, c.want)
}
}
}
var GlobalF float64
func BenchmarkFma(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ {
x = Fma(E, Pi, x)
}
GlobalF = x
}