1 //===-- Unittests for high_precision_decimal ------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "src/__support/UInt128.h"
10 #include "src/__support/high_precision_decimal.h"
12 #include "test/UnitTest/Test.h"
14 TEST(LlvmLibcHighPrecisionDecimalTest
, BasicInit
) {
15 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
16 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
17 uint8_t *digits
= hpd
.get_digits();
19 EXPECT_EQ(digits
[0], uint8_t(1));
20 EXPECT_EQ(digits
[1], uint8_t(2));
21 EXPECT_EQ(digits
[2], uint8_t(3));
22 EXPECT_EQ(digits
[3], uint8_t(4));
23 EXPECT_EQ(digits
[4], uint8_t(5));
24 EXPECT_EQ(hpd
.get_num_digits(), 5u);
25 EXPECT_EQ(hpd
.get_decimal_point(), 1);
28 TEST(LlvmLibcHighPrecisionDecimalTest
, BasicShift
) {
29 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
30 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
31 uint8_t *digits
= hpd
.get_digits();
33 hpd
.shift(1); // shift left 1, equal to multiplying by 2.
35 EXPECT_EQ(digits
[0], uint8_t(2));
36 EXPECT_EQ(hpd
.get_num_digits(), 1u);
37 EXPECT_EQ(hpd
.get_decimal_point(), 1);
40 TEST(LlvmLibcHighPrecisionDecimalTest
, ShouldRoundup
) {
41 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
42 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".5");
43 uint8_t *digits
= hpd
.get_digits();
45 EXPECT_EQ(digits
[0], uint8_t(5));
46 EXPECT_EQ(hpd
.get_num_digits(), 1u);
47 EXPECT_EQ(hpd
.get_decimal_point(), 0);
48 EXPECT_EQ(hpd
.round_to_integer_type
<int>(), 0);
51 TEST(LlvmLibcHighPrecisionDecimalTest
, SmallShift
) {
52 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
53 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
54 uint8_t *digits
= hpd
.get_digits();
56 hpd
.shift(-1); // shift right one, equal to dividing by 2
57 // result should be 0.61725
59 EXPECT_EQ(digits
[0], uint8_t(6));
60 EXPECT_EQ(digits
[1], uint8_t(1));
61 EXPECT_EQ(digits
[2], uint8_t(7));
62 EXPECT_EQ(digits
[3], uint8_t(2));
63 EXPECT_EQ(digits
[4], uint8_t(5));
64 EXPECT_EQ(hpd
.get_num_digits(), 5u);
65 EXPECT_EQ(hpd
.get_decimal_point(), 0);
67 hpd
.shift(1); // shift left one, equal to multiplying by 2
68 // result should be 1.2345 again
70 EXPECT_EQ(digits
[0], uint8_t(1));
71 EXPECT_EQ(digits
[1], uint8_t(2));
72 EXPECT_EQ(digits
[2], uint8_t(3));
73 EXPECT_EQ(digits
[3], uint8_t(4));
74 EXPECT_EQ(digits
[4], uint8_t(5));
75 EXPECT_EQ(hpd
.get_num_digits(), 5u);
76 EXPECT_EQ(hpd
.get_decimal_point(), 1);
78 hpd
.shift(1); // shift left one again
79 // result should be 2.469
81 EXPECT_EQ(digits
[0], uint8_t(2));
82 EXPECT_EQ(digits
[1], uint8_t(4));
83 EXPECT_EQ(digits
[2], uint8_t(6));
84 EXPECT_EQ(digits
[3], uint8_t(9));
85 EXPECT_EQ(hpd
.get_num_digits(), 4u);
86 EXPECT_EQ(hpd
.get_decimal_point(), 1);
88 hpd
.shift(-1); // shift right one again
89 // result should be 1.2345 again
91 EXPECT_EQ(digits
[0], uint8_t(1));
92 EXPECT_EQ(digits
[1], uint8_t(2));
93 EXPECT_EQ(digits
[2], uint8_t(3));
94 EXPECT_EQ(digits
[3], uint8_t(4));
95 EXPECT_EQ(digits
[4], uint8_t(5));
96 EXPECT_EQ(hpd
.get_num_digits(), 5u);
97 EXPECT_EQ(hpd
.get_decimal_point(), 1);
100 TEST(LlvmLibcHighPrecisionDecimalTest
, MediumShift
) {
101 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
102 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
103 uint8_t *digits
= hpd
.get_digits();
105 hpd
.shift(-3); // shift right three, equal to dividing by 8
106 // result should be 0.03747405725
108 EXPECT_EQ(digits
[0], uint8_t(3));
109 EXPECT_EQ(digits
[1], uint8_t(7));
110 EXPECT_EQ(digits
[2], uint8_t(4));
111 EXPECT_EQ(digits
[3], uint8_t(7));
112 EXPECT_EQ(digits
[4], uint8_t(4));
113 EXPECT_EQ(digits
[5], uint8_t(0));
114 EXPECT_EQ(digits
[6], uint8_t(5));
115 EXPECT_EQ(digits
[7], uint8_t(7));
116 EXPECT_EQ(digits
[8], uint8_t(2));
117 EXPECT_EQ(digits
[9], uint8_t(5));
118 EXPECT_EQ(hpd
.get_num_digits(), 10u);
119 EXPECT_EQ(hpd
.get_decimal_point(), -1);
121 hpd
.shift(3); // shift left three, equal to multiplying by 8
122 // result should be 0.299792458 again
124 EXPECT_EQ(digits
[0], uint8_t(2));
125 EXPECT_EQ(digits
[1], uint8_t(9));
126 EXPECT_EQ(digits
[2], uint8_t(9));
127 EXPECT_EQ(digits
[3], uint8_t(7));
128 EXPECT_EQ(digits
[4], uint8_t(9));
129 EXPECT_EQ(digits
[5], uint8_t(2));
130 EXPECT_EQ(digits
[6], uint8_t(4));
131 EXPECT_EQ(digits
[7], uint8_t(5));
132 EXPECT_EQ(digits
[8], uint8_t(8));
133 EXPECT_EQ(hpd
.get_num_digits(), 9u);
134 EXPECT_EQ(hpd
.get_decimal_point(), 0);
137 TEST(LlvmLibcHighPrecisionDecimalTest
, BigShift
) {
138 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
139 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
140 uint8_t *digits
= hpd
.get_digits();
142 hpd
.shift(-29); // shift right 29, equal to dividing by 536,870,912
143 // result should be 0.0000000005584069676697254180908203125
145 EXPECT_EQ(digits
[0], uint8_t(5));
146 EXPECT_EQ(digits
[1], uint8_t(5));
147 EXPECT_EQ(digits
[2], uint8_t(8));
148 EXPECT_EQ(digits
[3], uint8_t(4));
149 EXPECT_EQ(digits
[4], uint8_t(0));
150 EXPECT_EQ(digits
[5], uint8_t(6));
151 EXPECT_EQ(digits
[6], uint8_t(9));
152 EXPECT_EQ(digits
[7], uint8_t(6));
153 EXPECT_EQ(digits
[8], uint8_t(7));
154 EXPECT_EQ(digits
[9], uint8_t(6));
155 EXPECT_EQ(digits
[10], uint8_t(6));
156 EXPECT_EQ(digits
[11], uint8_t(9));
157 EXPECT_EQ(digits
[12], uint8_t(7));
158 EXPECT_EQ(digits
[13], uint8_t(2));
159 EXPECT_EQ(digits
[14], uint8_t(5));
160 EXPECT_EQ(digits
[15], uint8_t(4));
161 EXPECT_EQ(digits
[16], uint8_t(1));
162 EXPECT_EQ(digits
[17], uint8_t(8));
163 EXPECT_EQ(digits
[18], uint8_t(0));
164 EXPECT_EQ(digits
[19], uint8_t(9));
165 EXPECT_EQ(digits
[20], uint8_t(0));
166 EXPECT_EQ(digits
[21], uint8_t(8));
167 EXPECT_EQ(digits
[22], uint8_t(2));
168 EXPECT_EQ(digits
[23], uint8_t(0));
169 EXPECT_EQ(digits
[24], uint8_t(3));
170 EXPECT_EQ(digits
[25], uint8_t(1));
171 EXPECT_EQ(digits
[26], uint8_t(2));
172 EXPECT_EQ(digits
[27], uint8_t(5));
173 EXPECT_EQ(hpd
.get_num_digits(), 28u);
174 EXPECT_EQ(hpd
.get_decimal_point(), -9);
176 hpd
.shift(29); // shift left 29, equal to multiplying by 536,870,912
177 // result should be 0.299792458 again
179 EXPECT_EQ(digits
[0], uint8_t(2));
180 EXPECT_EQ(digits
[1], uint8_t(9));
181 EXPECT_EQ(digits
[2], uint8_t(9));
182 EXPECT_EQ(digits
[3], uint8_t(7));
183 EXPECT_EQ(digits
[4], uint8_t(9));
184 EXPECT_EQ(digits
[5], uint8_t(2));
185 EXPECT_EQ(digits
[6], uint8_t(4));
186 EXPECT_EQ(digits
[7], uint8_t(5));
187 EXPECT_EQ(digits
[8], uint8_t(8));
188 EXPECT_EQ(hpd
.get_num_digits(), 9u);
189 EXPECT_EQ(hpd
.get_decimal_point(), 0);
192 TEST(LlvmLibcHighPrecisionDecimalTest
, BigShiftInSteps
) {
193 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
194 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
195 uint8_t *digits
= hpd
.get_digits();
197 hpd
.shift(60); // shift left 60, equal to multiplying by
198 // 1152921504606846976.
200 EXPECT_EQ(digits
[0], uint8_t(1));
201 EXPECT_EQ(digits
[1], uint8_t(1));
202 EXPECT_EQ(digits
[2], uint8_t(5));
203 EXPECT_EQ(digits
[3], uint8_t(2));
204 EXPECT_EQ(digits
[4], uint8_t(9));
205 EXPECT_EQ(digits
[5], uint8_t(2));
206 EXPECT_EQ(digits
[6], uint8_t(1));
207 EXPECT_EQ(digits
[7], uint8_t(5));
208 EXPECT_EQ(digits
[8], uint8_t(0));
209 EXPECT_EQ(digits
[9], uint8_t(4));
210 EXPECT_EQ(digits
[10], uint8_t(6));
211 EXPECT_EQ(digits
[11], uint8_t(0));
212 EXPECT_EQ(digits
[12], uint8_t(6));
213 EXPECT_EQ(digits
[13], uint8_t(8));
214 EXPECT_EQ(digits
[14], uint8_t(4));
215 EXPECT_EQ(digits
[15], uint8_t(6));
216 EXPECT_EQ(digits
[16], uint8_t(9));
217 EXPECT_EQ(digits
[17], uint8_t(7));
218 EXPECT_EQ(digits
[18], uint8_t(6));
219 EXPECT_EQ(hpd
.get_num_digits(), 19u);
220 EXPECT_EQ(hpd
.get_decimal_point(), 19);
222 hpd
.shift(40); // shift left 40, equal to multiplying by
223 // 1099511627776. Result should be 2^100
225 EXPECT_EQ(digits
[0], uint8_t(1));
226 EXPECT_EQ(digits
[1], uint8_t(2));
227 EXPECT_EQ(digits
[2], uint8_t(6));
228 EXPECT_EQ(digits
[3], uint8_t(7));
229 EXPECT_EQ(digits
[4], uint8_t(6));
230 EXPECT_EQ(digits
[5], uint8_t(5));
231 EXPECT_EQ(digits
[6], uint8_t(0));
232 EXPECT_EQ(digits
[7], uint8_t(6));
233 EXPECT_EQ(digits
[8], uint8_t(0));
234 EXPECT_EQ(digits
[9], uint8_t(0));
235 EXPECT_EQ(digits
[10], uint8_t(2));
236 EXPECT_EQ(digits
[11], uint8_t(2));
237 EXPECT_EQ(digits
[12], uint8_t(8));
238 EXPECT_EQ(digits
[13], uint8_t(2));
239 EXPECT_EQ(digits
[14], uint8_t(2));
240 EXPECT_EQ(digits
[15], uint8_t(9));
241 EXPECT_EQ(digits
[16], uint8_t(4));
242 EXPECT_EQ(digits
[17], uint8_t(0));
243 EXPECT_EQ(digits
[18], uint8_t(1));
244 EXPECT_EQ(digits
[19], uint8_t(4));
245 EXPECT_EQ(digits
[20], uint8_t(9));
246 EXPECT_EQ(digits
[21], uint8_t(6));
247 EXPECT_EQ(digits
[22], uint8_t(7));
248 EXPECT_EQ(digits
[23], uint8_t(0));
249 EXPECT_EQ(digits
[24], uint8_t(3));
250 EXPECT_EQ(digits
[25], uint8_t(2));
251 EXPECT_EQ(digits
[26], uint8_t(0));
252 EXPECT_EQ(digits
[27], uint8_t(5));
253 EXPECT_EQ(digits
[28], uint8_t(3));
254 EXPECT_EQ(digits
[29], uint8_t(7));
255 EXPECT_EQ(digits
[30], uint8_t(6));
257 EXPECT_EQ(hpd
.get_num_digits(), 31u);
258 EXPECT_EQ(hpd
.get_decimal_point(), 31);
260 hpd
.shift(-60); // shift right 60, equal to dividing by
261 // 1152921504606846976. Result should be 2^40
263 EXPECT_EQ(digits
[0], uint8_t(1));
264 EXPECT_EQ(digits
[1], uint8_t(0));
265 EXPECT_EQ(digits
[2], uint8_t(9));
266 EXPECT_EQ(digits
[3], uint8_t(9));
267 EXPECT_EQ(digits
[4], uint8_t(5));
268 EXPECT_EQ(digits
[5], uint8_t(1));
269 EXPECT_EQ(digits
[6], uint8_t(1));
270 EXPECT_EQ(digits
[7], uint8_t(6));
271 EXPECT_EQ(digits
[8], uint8_t(2));
272 EXPECT_EQ(digits
[9], uint8_t(7));
273 EXPECT_EQ(digits
[10], uint8_t(7));
274 EXPECT_EQ(digits
[11], uint8_t(7));
275 EXPECT_EQ(digits
[12], uint8_t(6));
277 EXPECT_EQ(hpd
.get_num_digits(), 13u);
278 EXPECT_EQ(hpd
.get_decimal_point(), 13);
280 hpd
.shift(-40); // shift right 40, equal to dividing by
281 // 1099511627776. Result should be 1
283 EXPECT_EQ(digits
[0], uint8_t(1));
285 EXPECT_EQ(hpd
.get_num_digits(), 1u);
286 EXPECT_EQ(hpd
.get_decimal_point(), 1);
289 TEST(LlvmLibcHighPrecisionDecimalTest
, VeryBigShift
) {
290 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
291 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
292 uint8_t *digits
= hpd
.get_digits();
294 hpd
.shift(100); // shift left 100, equal to multiplying by
295 // 1267650600228229401496703205376.
296 // result should be 2^100
298 EXPECT_EQ(digits
[0], uint8_t(1));
299 EXPECT_EQ(digits
[1], uint8_t(2));
300 EXPECT_EQ(digits
[2], uint8_t(6));
301 EXPECT_EQ(digits
[3], uint8_t(7));
302 EXPECT_EQ(digits
[4], uint8_t(6));
303 EXPECT_EQ(digits
[5], uint8_t(5));
304 EXPECT_EQ(digits
[6], uint8_t(0));
305 EXPECT_EQ(digits
[7], uint8_t(6));
306 EXPECT_EQ(digits
[8], uint8_t(0));
307 EXPECT_EQ(digits
[9], uint8_t(0));
308 EXPECT_EQ(digits
[10], uint8_t(2));
309 EXPECT_EQ(digits
[11], uint8_t(2));
310 EXPECT_EQ(digits
[12], uint8_t(8));
311 EXPECT_EQ(digits
[13], uint8_t(2));
312 EXPECT_EQ(digits
[14], uint8_t(2));
313 EXPECT_EQ(digits
[15], uint8_t(9));
314 EXPECT_EQ(digits
[16], uint8_t(4));
315 EXPECT_EQ(digits
[17], uint8_t(0));
316 EXPECT_EQ(digits
[18], uint8_t(1));
317 EXPECT_EQ(digits
[19], uint8_t(4));
318 EXPECT_EQ(digits
[20], uint8_t(9));
319 EXPECT_EQ(digits
[21], uint8_t(6));
320 EXPECT_EQ(digits
[22], uint8_t(7));
321 EXPECT_EQ(digits
[23], uint8_t(0));
322 EXPECT_EQ(digits
[24], uint8_t(3));
323 EXPECT_EQ(digits
[25], uint8_t(2));
324 EXPECT_EQ(digits
[26], uint8_t(0));
325 EXPECT_EQ(digits
[27], uint8_t(5));
326 EXPECT_EQ(digits
[28], uint8_t(3));
327 EXPECT_EQ(digits
[29], uint8_t(7));
328 EXPECT_EQ(digits
[30], uint8_t(6));
330 EXPECT_EQ(hpd
.get_num_digits(), 31u);
331 EXPECT_EQ(hpd
.get_decimal_point(), 31);
333 hpd
.shift(-100); // shift right 100, equal to dividing by
334 // 1267650600228229401496703205376.
335 // result should be 1
337 EXPECT_EQ(digits
[0], uint8_t(1));
338 EXPECT_EQ(hpd
.get_num_digits(), 1u);
339 EXPECT_EQ(hpd
.get_decimal_point(), 1);
342 TEST(LlvmLibcHighPrecisionDecimalTest
, RoundingTest
) {
343 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd
=
344 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
346 EXPECT_EQ(hpd
.round_to_integer_type
<uint32_t>(), uint32_t(1));
347 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(1));
348 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(1));
350 hpd
.shift(1); // shift left 1 to get 2.469 (rounds to 2)
352 EXPECT_EQ(hpd
.round_to_integer_type
<uint32_t>(), uint32_t(2));
353 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(2));
354 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(2));
356 hpd
.shift(1); // shift left 1 to get 4.938 (rounds to 5)
358 EXPECT_EQ(hpd
.round_to_integer_type
<uint32_t>(), uint32_t(5));
359 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(5));
360 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(5));
362 // 2.5 is right between two integers, so we round to even (2)
363 hpd
= LIBC_NAMESPACE::internal::HighPrecisionDecimal("2.5");
365 EXPECT_EQ(hpd
.round_to_integer_type
<uint32_t>(), uint32_t(2));
366 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(2));
367 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(2));
369 // unless it's marked as having truncated, which means it's actually slightly
370 // higher, forcing a round up (3)
371 hpd
.set_truncated(true);
373 EXPECT_EQ(hpd
.round_to_integer_type
<uint32_t>(), uint32_t(3));
374 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(3));
375 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(3));
377 // Check that the larger int types are being handled properly (overflow is not
378 // handled, so int types that are too small are ignored for this test.)
380 // 1099511627776 = 2^40
381 hpd
= LIBC_NAMESPACE::internal::HighPrecisionDecimal("1099511627776");
383 EXPECT_EQ(hpd
.round_to_integer_type
<uint64_t>(), uint64_t(1099511627776));
384 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), UInt128(1099511627776));
386 // 1267650600228229401496703205376 = 2^100
387 hpd
= LIBC_NAMESPACE::internal::HighPrecisionDecimal(
388 "1267650600228229401496703205376");
390 UInt128 result
= UInt128(1) << 100;
392 EXPECT_EQ(hpd
.round_to_integer_type
<UInt128
>(), result
);
395 TEST(LlvmLibcHighPrecisionDecimalTest
, BigExpTest
) {
396 LIBC_NAMESPACE::internal::HighPrecisionDecimal big_hpd
=
397 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789");
399 // We need to add one to handle the digit before the decimal point in our
401 EXPECT_EQ(big_hpd
.get_decimal_point(), 123456789 + 1);
403 LIBC_NAMESPACE::internal::HighPrecisionDecimal big_negative_hpd
=
404 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789");
406 // Same, but since the number is negative the net result is -123456788
407 EXPECT_EQ(big_negative_hpd
.get_decimal_point(), -123456789 + 1);