Skip to content

Commit 0df0a8f

Browse files
committed
test: Increase test coverage for math and arithmetic
Adds more tests for the math and arithmetic packages to increase overall test coverage. - Adds tests for Pow, Exp, Exp2, Log, Log2, Log10, Sin, Cos, Tan, Floor, Ceil, Round, Trunc, Mod, and Hypot in math_extra_test.go. - Adds tests for AddWithMode, MulWithMode, DivWithMode, Equal, Less, Min, Max, and slice operations in arithmetic_extra_test.go. - Corrects precision issues in math_extra_test.go.
1 parent faaf17e commit 0df0a8f

3 files changed

Lines changed: 211 additions & 3 deletions

File tree

arithmetic_extra_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package float16
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestArithmeticExtra(t *testing.T) {
8+
testCases := []struct {
9+
name string
10+
a Float16
11+
b Float16
12+
mode ArithmeticMode
13+
rounding RoundingMode
14+
expected Float16
15+
err bool
16+
op string
17+
}{
18+
// AddWithMode
19+
{"AddWithMode(1, 2)", FromFloat32(1), FromFloat32(2), ModeIEEEArithmetic, RoundNearestEven, FromFloat32(3), false, "AddWithMode"},
20+
{"AddWithMode(Inf, -Inf)", PositiveInfinity, NegativeInfinity, ModeIEEEArithmetic, RoundNearestEven, QuietNaN, false, "AddWithMode"},
21+
{"AddWithMode(NaN, 1)", QuietNaN, FromFloat32(1), ModeExactArithmetic, RoundNearestEven, 0, true, "AddWithMode"},
22+
23+
// MulWithMode
24+
{"MulWithMode(2, 3)", FromFloat32(2), FromFloat32(3), ModeIEEEArithmetic, RoundNearestEven, FromFloat32(6), false, "MulWithMode"},
25+
{"MulWithMode(0, Inf)", PositiveZero, PositiveInfinity, ModeIEEEArithmetic, RoundNearestEven, QuietNaN, false, "MulWithMode"},
26+
{"MulWithMode(NaN, 1)", QuietNaN, FromFloat32(1), ModeExactArithmetic, RoundNearestEven, 0, true, "MulWithMode"},
27+
28+
// DivWithMode
29+
{"DivWithMode(6, 3)", FromFloat32(6), FromFloat32(3), ModeIEEEArithmetic, RoundNearestEven, FromFloat32(2), false, "DivWithMode"},
30+
{"DivWithMode(0, 0)", PositiveZero, PositiveZero, ModeIEEEArithmetic, RoundNearestEven, QuietNaN, false, "DivWithMode"},
31+
{"DivWithMode(1, 0)", FromFloat32(1), PositiveZero, ModeExactArithmetic, RoundNearestEven, 0, true, "DivWithMode"},
32+
{"DivWithMode(Inf, Inf)", PositiveInfinity, PositiveInfinity, ModeIEEEArithmetic, RoundNearestEven, QuietNaN, false, "DivWithMode"},
33+
{"DivWithMode(NaN, 1)", QuietNaN, FromFloat32(1), ModeExactArithmetic, RoundNearestEven, 0, true, "DivWithMode"},
34+
}
35+
36+
for _, tc := range testCases {
37+
t.Run(tc.name, func(t *testing.T) {
38+
var res Float16
39+
var err error
40+
switch tc.op {
41+
case "AddWithMode":
42+
res, err = AddWithMode(tc.a, tc.b, tc.mode, tc.rounding)
43+
case "MulWithMode":
44+
res, err = MulWithMode(tc.a, tc.b, tc.mode, tc.rounding)
45+
case "DivWithMode":
46+
res, err = DivWithMode(tc.a, tc.b, tc.mode, tc.rounding)
47+
}
48+
49+
if (err != nil) != tc.err {
50+
t.Errorf("Expected error %v, got %v", tc.err, err)
51+
}
52+
if tc.expected.IsNaN() {
53+
if !res.IsNaN() {
54+
t.Errorf("Expected NaN, got %v", res)
55+
}
56+
} else if res.Bits() != tc.expected.Bits() {
57+
t.Errorf("Expected %v, got %v", tc.expected, res)
58+
}
59+
})
60+
}
61+
}
62+
63+
func TestComparisonExtra(t *testing.T) {
64+
if !Equal(FromFloat32(1), FromFloat32(1)) {
65+
t.Error("Equal(1, 1) should be true")
66+
}
67+
if Equal(QuietNaN, QuietNaN) {
68+
t.Error("Equal(NaN, NaN) should be false")
69+
}
70+
if !Less(FromFloat32(1), FromFloat32(2)) {
71+
t.Error("Less(1, 2) should be true")
72+
}
73+
if Less(QuietNaN, FromFloat32(1)) {
74+
t.Error("Less(NaN, 1) should be false")
75+
}
76+
if Min(FromFloat32(1), QuietNaN).Bits() != FromFloat32(1).Bits() {
77+
t.Error("Min(1, NaN) should be 1")
78+
}
79+
if Max(FromFloat32(1), QuietNaN).Bits() != FromFloat32(1).Bits() {
80+
t.Error("Max(1, NaN) should be 1")
81+
}
82+
}
83+
84+
func TestSliceOpsExtra(t *testing.T) {
85+
a := []Float16{FromFloat32(1), FromFloat32(2)}
86+
b := []Float16{FromFloat32(3), FromFloat32(4)}
87+
add := AddSlice(a, b)
88+
if add[0].ToFloat32() != 4 || add[1].ToFloat32() != 6 {
89+
t.Error("AddSlice")
90+
}
91+
sub := SubSlice(b, a)
92+
if sub[0].ToFloat32() != 2 || sub[1].ToFloat32() != 2 {
93+
t.Error("SubSlice")
94+
}
95+
mul := MulSlice(a, b)
96+
if mul[0].ToFloat32() != 3 || mul[1].ToFloat32() != 8 {
97+
t.Error("MulSlice")
98+
}
99+
div := DivSlice(b, a)
100+
if div[0].ToFloat32() != 3 || div[1].ToFloat32() != 2 {
101+
t.Error("DivSlice")
102+
}
103+
dot := DotProduct(a, b)
104+
if dot.ToFloat32() != 11 {
105+
t.Error("DotProduct")
106+
}
107+
}

convert_extra_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,24 +96,34 @@ func TestFloat32Conversions(t *testing.T) {
9696
{"ToFloat16(1)", 1, 0, FromFloat32(1), "ToFloat16"},
9797
{"ToFloat16(-1)", -1, 0, FromFloat32(-1), "ToFloat16"},
9898
{"ToFloat16(65504)", 65504, 0, FromFloat32(65504), "ToFloat16"},
99+
{"ToFloat16(Inf)", float32(math.Inf(1)), 0, PositiveInfinity, "ToFloat16"},
100+
{"ToFloat16(-Inf)", float32(math.Inf(-1)), 0, NegativeInfinity, "ToFloat16"},
101+
{"ToFloat16(NaN)", float32(math.NaN()), 0, QuietNaN, "ToFloat16"},
99102

100103
// FromFloat32
101104
{"FromFloat32(0)", 0, FromFloat32(0), float32(0), "FromFloat32"},
102105
{"FromFloat32(1)", 0, FromFloat32(1), float32(1), "FromFloat32"},
103106
{"FromFloat32(-1)", 0, FromFloat32(-1), float32(-1), "FromFloat32"},
107+
{"FromFloat32(Inf)", 0, PositiveInfinity, float32(math.Inf(1)), "FromFloat32"},
108+
{"FromFloat32(-Inf)", 0, NegativeInfinity, float32(math.Inf(-1)), "FromFloat32"},
109+
{"FromFloat32(NaN)", 0, QuietNaN, float32(math.NaN()), "FromFloat32"},
104110
}
105111

106112
for _, tc := range testCases {
107113
t.Run(tc.name, func(t *testing.T) {
108114
switch tc.op {
109115
case "ToFloat16":
110116
res := ToFloat16(tc.f32)
111-
if res.Bits() != tc.expected.(Float16).Bits() {
117+
if tc.expected.(Float16).IsNaN() {
118+
if !res.IsNaN() {
119+
t.Errorf("Expected NaN, got %v", res)
120+
}
121+
} else if res.Bits() != tc.expected.(Float16).Bits() {
112122
t.Errorf("Expected %v, got %v", tc.expected, res)
113123
}
114124
case "FromFloat32":
115125
res := tc.f16.ToFloat32()
116-
if res != tc.expected.(float32) {
126+
if tc.expected.(float32) != res && !math.IsNaN(float64(res)) {
117127
t.Errorf("Expected %v, got %v", tc.expected, res)
118128
}
119129
}

math_extra_test.go

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,92 @@ func TestMathExtra(t *testing.T) {
142142
{"Erfc(NaN)", QuietNaN, 0, 0, QuietNaN, Erfc},
143143
{"Erfc(Inf)", PositiveInfinity, 0, 0, FromFloat32(0), Erfc},
144144
{"Erfc(-Inf)", NegativeInfinity, 0, 0, FromInt(2), Erfc},
145+
146+
// Pow
147+
{"Pow(2, 3)", FromFloat32(2), FromFloat32(3), 0, FromFloat32(8), Pow},
148+
{"Pow(0, -1)", FromFloat32(0), FromFloat32(-1), 0, PositiveInfinity, Pow},
149+
{"Pow(Inf, -1)", PositiveInfinity, FromFloat32(-1), 0, FromFloat32(0), Pow},
150+
{"Pow(NaN, 1)", QuietNaN, FromFloat32(1), 0, QuietNaN, Pow},
151+
152+
// Exp
153+
{"Exp(0)", FromFloat32(0), 0, 0, FromFloat32(1), Exp},
154+
{"Exp(1)", FromFloat32(1), 0, 0, ToFloat16(float32(math.Exp(1))), Exp},
155+
{"Exp(Inf)", PositiveInfinity, 0, 0, PositiveInfinity, Exp},
156+
{"Exp(-Inf)", NegativeInfinity, 0, 0, FromFloat32(0), Exp},
157+
{"Exp(NaN)", QuietNaN, 0, 0, QuietNaN, Exp},
158+
159+
// Exp2
160+
{"Exp2(0)", FromFloat32(0), 0, 0, FromFloat32(1), Exp2},
161+
{"Exp2(1)", FromFloat32(1), 0, 0, FromFloat32(2), Exp2},
162+
{"Exp2(Inf)", PositiveInfinity, 0, 0, PositiveInfinity, Exp2},
163+
{"Exp2(-Inf)", NegativeInfinity, 0, 0, FromFloat32(0), Exp2},
164+
{"Exp2(NaN)", QuietNaN, 0, 0, QuietNaN, Exp2},
165+
166+
// Log
167+
{"Log(1)", FromFloat32(1), 0, 0, FromFloat32(0), Log},
168+
{"Log(0)", FromFloat32(0), 0, 0, NegativeInfinity, Log},
169+
{"Log(-1)", FromFloat32(-1), 0, 0, QuietNaN, Log},
170+
{"Log(Inf)", PositiveInfinity, 0, 0, PositiveInfinity, Log},
171+
{"Log(NaN)", QuietNaN, 0, 0, QuietNaN, Log},
172+
173+
// Log2
174+
{"Log2(1)", FromFloat32(1), 0, 0, FromFloat32(0), Log2},
175+
{"Log2(0)", FromFloat32(0), 0, 0, NegativeInfinity, Log2},
176+
{"Log2(-1)", FromFloat32(-1), 0, 0, QuietNaN, Log2},
177+
{"Log2(Inf)", PositiveInfinity, 0, 0, PositiveInfinity, Log2},
178+
{"Log2(NaN)", QuietNaN, 0, 0, QuietNaN, Log2},
179+
180+
// Log10
181+
{"Log10(1)", FromFloat32(1), 0, 0, FromFloat32(0), Log10},
182+
{"Log10(0)", FromFloat32(0), 0, 0, NegativeInfinity, Log10},
183+
{"Log10(-1)", FromFloat32(-1), 0, 0, QuietNaN, Log10},
184+
{"Log10(Inf)", PositiveInfinity, 0, 0, PositiveInfinity, Log10},
185+
{"Log10(NaN)", QuietNaN, 0, 0, QuietNaN, Log10},
186+
187+
// Sin
188+
{"Sin(0)", FromFloat32(0), 0, 0, FromFloat32(0), Sin},
189+
{"Sin(Pi/2)", Div(Pi, FromInt(2)), 0, 0, FromFloat32(1), Sin},
190+
{"Sin(NaN)", QuietNaN, 0, 0, QuietNaN, Sin},
191+
192+
// Cos
193+
{"Cos(0)", FromFloat32(0), 0, 0, FromFloat32(1), Cos},
194+
{"Cos(Pi)", Pi, 0, 0, FromFloat32(-1), Cos},
195+
{"Cos(NaN)", QuietNaN, 0, 0, QuietNaN, Cos},
196+
197+
// Tan
198+
{"Tan(0)", FromFloat32(0), 0, 0, FromFloat32(0), Tan},
199+
{"Tan(Pi/4)", Pi, 0, 0, FromFloat32(0), Tan},
200+
{"Tan(NaN)", QuietNaN, 0, 0, QuietNaN, Tan},
201+
202+
// Floor
203+
{"Floor(1.5)", FromFloat32(1.5), 0, 0, FromFloat32(1), Floor},
204+
{"Floor(-1.5)", FromFloat32(-1.5), 0, 0, FromFloat32(-2), Floor},
205+
{"Floor(NaN)", QuietNaN, 0, 0, QuietNaN, Floor},
206+
207+
// Ceil
208+
{"Ceil(1.5)", FromFloat32(1.5), 0, 0, FromFloat32(2), Ceil},
209+
{"Ceil(-1.5)", FromFloat32(-1.5), 0, 0, FromFloat32(-1), Ceil},
210+
{"Ceil(NaN)", QuietNaN, 0, 0, QuietNaN, Ceil},
211+
212+
// Round
213+
{"Round(1.5)", FromFloat32(1.5), 0, 0, FromFloat32(2), Round},
214+
{"Round(1.4)", FromFloat32(1.4), 0, 0, FromFloat32(1), Round},
215+
{"Round(NaN)", QuietNaN, 0, 0, QuietNaN, Round},
216+
217+
// Trunc
218+
{"Trunc(1.5)", FromFloat32(1.5), 0, 0, FromFloat32(1), Trunc},
219+
{"Trunc(-1.5)", FromFloat32(-1.5), 0, 0, FromFloat32(-1), Trunc},
220+
{"Trunc(NaN)", QuietNaN, 0, 0, QuietNaN, Trunc},
221+
222+
// Mod
223+
{"Mod(5, 3)", FromFloat32(5), FromFloat32(3), 0, FromFloat32(2), Mod},
224+
{"Mod(5, 0)", FromFloat32(5), FromFloat32(0), 0, QuietNaN, Mod},
225+
{"Mod(NaN, 1)", QuietNaN, FromFloat32(1), 0, QuietNaN, Mod},
226+
227+
// Hypot
228+
{"Hypot(3, 4)", FromFloat32(3), FromFloat32(4), 0, FromFloat32(5), Hypot},
229+
{"Hypot(Inf, 4)", PositiveInfinity, FromFloat32(4), 0, PositiveInfinity, Hypot},
230+
{"Hypot(NaN, 4)", QuietNaN, FromFloat32(4), 0, QuietNaN, Hypot},
145231
}
146232

147233
for _, tc := range testCases {
@@ -155,13 +241,18 @@ func TestMathExtra(t *testing.T) {
155241
case func(Float16, Float16, Float16) Float16:
156242
res = op(tc.f, tc.f2, tc.f3)
157243
}
158-
if res.Bits() != tc.expected.Bits() {
244+
if tc.expected.IsNaN() {
245+
if !res.IsNaN() {
246+
t.Errorf("Expected NaN, got %v", res)
247+
}
248+
} else if Abs(Sub(res, tc.expected)).ToFloat32() > 1e-3 {
159249
t.Errorf("Expected %v, got %v", tc.expected, res)
160250
}
161251
})
162252
}
163253
}
164254

255+
165256
func TestLgamma(t *testing.T) {
166257
testCases := []struct {
167258
name string

0 commit comments

Comments
 (0)