Line data Source code
1 : // SPDX-License-Identifier: MIT
2 : /* Unit tests for display/include/fixed31_32.h and dc/basics/fixpt31_32.c
3 : *
4 : * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
5 : */
6 :
7 : #include <kunit/test.h>
8 : #include "os_types.h"
9 : #include "fixed31_32.h"
10 :
11 : static const struct fixed31_32 dc_fixpt_minus_one = { -0x100000000LL };
12 :
13 : /**
14 : * dc_fixpt_from_int_test - KUnit test for dc_fixpt_from_int
15 : * @test: represents a running instance of a test.
16 : */
17 1 : static void dc_fixpt_from_int_test(struct kunit *test)
18 : {
19 : struct fixed31_32 res;
20 :
21 1 : res = dc_fixpt_from_int(0);
22 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_zero.value);
23 :
24 1 : res = dc_fixpt_from_int(1);
25 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
26 :
27 1 : res = dc_fixpt_from_int(-1);
28 1 : KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
29 :
30 1 : res = dc_fixpt_from_int(INT_MAX);
31 1 : KUNIT_EXPECT_EQ(test, res.value, 0x7FFFFFFF00000000LL);
32 :
33 1 : res = dc_fixpt_from_int(INT_MIN);
34 1 : KUNIT_EXPECT_EQ(test, res.value,
35 : 0x8000000000000000LL); /* implicit negative signal */
36 1 : }
37 :
38 : /**
39 : * dc_fixpt_from_fraction_test - KUnit test for dc_fixpt_from_fraction
40 : * @test: represents a running instance of a test.
41 : */
42 1 : static void dc_fixpt_from_fraction_test(struct kunit *test)
43 : {
44 : struct fixed31_32 res;
45 :
46 : /* Assert signal works as expected */
47 1 : res = dc_fixpt_from_fraction(1LL, 1LL);
48 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
49 :
50 1 : res = dc_fixpt_from_fraction(-1LL, 1LL);
51 1 : KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
52 :
53 1 : res = dc_fixpt_from_fraction(1LL, -1LL);
54 1 : KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
55 :
56 1 : res = dc_fixpt_from_fraction(-1LL, -1LL);
57 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
58 :
59 : /* Assert that the greatest parameter values works as expected */
60 1 : res = dc_fixpt_from_fraction(LLONG_MAX, LLONG_MAX);
61 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
62 :
63 1 : res = dc_fixpt_from_fraction(LLONG_MIN, LLONG_MIN);
64 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
65 :
66 : /* Edge case using the smallest fraction possible without LSB rounding */
67 1 : res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART));
68 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
69 :
70 : /* Edge case using the smallest fraction possible with LSB rounding */
71 1 : res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART + 1));
72 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
73 :
74 : /* Assert an nil numerator is a valid input */
75 1 : res = dc_fixpt_from_fraction(0LL, LLONG_MAX);
76 1 : KUNIT_EXPECT_EQ(test, res.value, 0LL);
77 :
78 : /* Edge case using every bit of the decimal part without rounding */
79 1 : res = dc_fixpt_from_fraction(8589934590LL, 8589934592LL);
80 1 : KUNIT_EXPECT_EQ(test, res.value, 0x0FFFFFFFFLL);
81 :
82 1 : res = dc_fixpt_from_fraction(-8589934590LL, 8589934592LL);
83 1 : KUNIT_EXPECT_EQ(test, res.value, -0x0FFFFFFFFLL);
84 :
85 : /* Edge case using every bit of the decimal part then rounding LSB */
86 1 : res = dc_fixpt_from_fraction(8589934591LL, 8589934592LL);
87 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
88 :
89 1 : res = dc_fixpt_from_fraction(-8589934591LL, 8589934592LL);
90 1 : KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
91 : /* A repeating decimal in binary representation that doesn't round up the LSB */
92 1 : res = dc_fixpt_from_fraction(4, 3);
93 1 : KUNIT_EXPECT_EQ(test, res.value, 0x0000000155555555LL);
94 :
95 1 : res = dc_fixpt_from_fraction(-4, 3);
96 1 : KUNIT_EXPECT_EQ(test, res.value, -0x0000000155555555LL);
97 :
98 : /* A repeating decimal in binary representation that rounds up the LSB */
99 1 : res = dc_fixpt_from_fraction(5, 3);
100 1 : KUNIT_EXPECT_EQ(test, res.value, 0x00000001AAAAAAABLL);
101 :
102 1 : res = dc_fixpt_from_fraction(-5, 3);
103 1 : KUNIT_EXPECT_EQ(test, res.value, -0x00000001AAAAAAABLL);
104 1 : }
105 :
106 : /**
107 : * dc_fixpt_mul_test - KUnit test for dc_fixpt_mul
108 : * @test: represents a running instance of a test.
109 : */
110 1 : static void dc_fixpt_mul_test(struct kunit *test)
111 : {
112 : struct fixed31_32 res;
113 : struct fixed31_32 arg;
114 :
115 : /* Assert signal works as expected */
116 1 : res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_one);
117 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
118 :
119 1 : res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_one);
120 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
121 :
122 1 : res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_minus_one);
123 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
124 :
125 1 : res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_minus_one);
126 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
127 :
128 : /* Assert that the greatest parameter values works as expected */
129 1 : arg.value = LONG_MAX;
130 1 : res = dc_fixpt_mul(arg, dc_fixpt_one);
131 1 : KUNIT_EXPECT_EQ(test, res.value, arg.value);
132 :
133 1 : arg.value = LONG_MIN;
134 1 : res = dc_fixpt_mul(arg, dc_fixpt_one);
135 1 : KUNIT_EXPECT_EQ(test, res.value, arg.value);
136 :
137 1 : arg.value = LONG_MAX;
138 1 : res = dc_fixpt_mul(dc_fixpt_one, arg);
139 1 : KUNIT_EXPECT_EQ(test, res.value, arg.value);
140 :
141 1 : arg.value = LONG_MIN;
142 1 : res = dc_fixpt_mul(dc_fixpt_one, arg);
143 1 : KUNIT_EXPECT_EQ(test, res.value, arg.value);
144 :
145 : /* Assert it doesn't round LSB as expected */
146 1 : arg.value = 0x7FFFFFFF7fffffffLL;
147 1 : res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
148 1 : KUNIT_EXPECT_EQ(test, res.value, 0x000000007FFFFFFF);
149 :
150 : /* Assert it rounds LSB as expected */
151 1 : arg.value = 0x7FFFFFFF80000000LL;
152 1 : res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
153 1 : KUNIT_EXPECT_EQ(test, res.value, 0x0000000080000000);
154 1 : }
155 :
156 : /**
157 : * dc_fixpt_sqr_test - KUnit test for dc_fixpt_sqr
158 : * @test: represents a running instance of a test.
159 : */
160 1 : static void dc_fixpt_sqr_test(struct kunit *test)
161 : {
162 : struct fixed31_32 res;
163 : struct fixed31_32 arg;
164 :
165 1 : arg.value = dc_fixpt_one.value;
166 1 : res = dc_fixpt_sqr(arg);
167 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
168 :
169 1 : arg.value = dc_fixpt_minus_one.value;
170 1 : res = dc_fixpt_sqr(arg);
171 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
172 :
173 1 : arg.value = 0;
174 1 : res = dc_fixpt_sqr(arg);
175 1 : KUNIT_EXPECT_EQ(test, res.value, 0);
176 :
177 : /* Test some recognizable values */
178 1 : arg = dc_fixpt_from_int(100);
179 1 : res = dc_fixpt_sqr(arg);
180 2 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_from_int(10000).value);
181 :
182 1 : arg = dc_fixpt_from_fraction(1, 100);
183 1 : res = dc_fixpt_sqr(arg);
184 1 : KUNIT_EXPECT_EQ(test, res.value,
185 : dc_fixpt_from_fraction(1, 10000).value);
186 :
187 : /* LSB rounding */
188 1 : arg = dc_fixpt_from_fraction(3, 2);
189 1 : res = dc_fixpt_sqr(arg);
190 1 : KUNIT_EXPECT_EQ(test, res.value,
191 : dc_fixpt_from_fraction(9, 4).value + 1LL);
192 1 : }
193 :
194 : /**
195 : * dc_fixpt_recip_test - KUnit test for dc_fixpt_recip
196 : * @test: represents a running instance of a test.
197 : */
198 1 : static void dc_fixpt_recip_test(struct kunit *test)
199 : {
200 : struct fixed31_32 res;
201 : struct fixed31_32 arg;
202 :
203 : /* Assert 1/1 works as expected */
204 1 : res = dc_fixpt_recip(dc_fixpt_one);
205 1 : KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
206 :
207 : /* Assert smallest parameters work as expected. */
208 1 : arg.value = 3LL;
209 1 : res = dc_fixpt_recip(arg);
210 1 : KUNIT_EXPECT_EQ(test, res.value, 0x5555555555555555LL);
211 :
212 1 : arg.value = -3LL;
213 1 : res = dc_fixpt_recip(arg);
214 1 : KUNIT_EXPECT_EQ(test, res.value, -0x5555555555555555LL);
215 1 : }
216 :
217 : static struct kunit_case dc_basics_fixpt31_32_test_cases[] = {
218 : KUNIT_CASE(dc_fixpt_from_int_test),
219 : KUNIT_CASE(dc_fixpt_from_fraction_test),
220 : KUNIT_CASE(dc_fixpt_mul_test),
221 : KUNIT_CASE(dc_fixpt_sqr_test),
222 : KUNIT_CASE(dc_fixpt_recip_test),
223 : {}
224 : };
225 :
226 : static struct kunit_suite dc_basics_fixpt31_32_test_suite = {
227 : .name = "dc_basics_fixpt31_32",
228 : .test_cases = dc_basics_fixpt31_32_test_cases,
229 : };
230 :
231 : kunit_test_suites(&dc_basics_fixpt31_32_test_suite);
232 :
|