1 //===-- Unittests for high_precision_decimal ------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/high_precision_decimal.h"
10 
11 #include "utils/UnitTest/Test.h"
12 
13 TEST(LlvmLibcHighPrecisionDecimalTest, BasicInit) {
14   __llvm_libc::internal::HighPrecisionDecimal hpd =
15       __llvm_libc::internal::HighPrecisionDecimal("1.2345");
16   uint8_t *digits = hpd.get_digits();
17 
18   EXPECT_EQ(digits[0], uint8_t(1));
19   EXPECT_EQ(digits[1], uint8_t(2));
20   EXPECT_EQ(digits[2], uint8_t(3));
21   EXPECT_EQ(digits[3], uint8_t(4));
22   EXPECT_EQ(digits[4], uint8_t(5));
23   EXPECT_EQ(hpd.get_num_digits(), 5u);
24   EXPECT_EQ(hpd.get_decimal_point(), 1);
25 }
26 
27 TEST(LlvmLibcHighPrecisionDecimalTest, BasicShift) {
28   __llvm_libc::internal::HighPrecisionDecimal hpd =
29       __llvm_libc::internal::HighPrecisionDecimal("1");
30   uint8_t *digits = hpd.get_digits();
31 
32   hpd.shift(1); // shift left 1, equal to multiplying by 2.
33 
34   EXPECT_EQ(digits[0], uint8_t(2));
35   EXPECT_EQ(hpd.get_num_digits(), 1u);
36   EXPECT_EQ(hpd.get_decimal_point(), 1);
37 }
38 
39 TEST(LlvmLibcHighPrecisionDecimalTest, ShouldRoundup) {
40   __llvm_libc::internal::HighPrecisionDecimal hpd =
41       __llvm_libc::internal::HighPrecisionDecimal(".5");
42   uint8_t *digits = hpd.get_digits();
43 
44   EXPECT_EQ(digits[0], uint8_t(5));
45   EXPECT_EQ(hpd.get_num_digits(), 1u);
46   EXPECT_EQ(hpd.get_decimal_point(), 0);
47   EXPECT_EQ(hpd.round_to_integer_type<int>(), 0);
48 }
49 
50 TEST(LlvmLibcHighPrecisionDecimalTest, SmallShift) {
51   __llvm_libc::internal::HighPrecisionDecimal hpd =
52       __llvm_libc::internal::HighPrecisionDecimal("1.2345");
53   uint8_t *digits = hpd.get_digits();
54 
55   hpd.shift(-1); // shift right one, equal to dividing by 2
56   // result should be 0.61725
57 
58   EXPECT_EQ(digits[0], uint8_t(6));
59   EXPECT_EQ(digits[1], uint8_t(1));
60   EXPECT_EQ(digits[2], uint8_t(7));
61   EXPECT_EQ(digits[3], uint8_t(2));
62   EXPECT_EQ(digits[4], uint8_t(5));
63   EXPECT_EQ(hpd.get_num_digits(), 5u);
64   EXPECT_EQ(hpd.get_decimal_point(), 0);
65 
66   hpd.shift(1); // shift left one, equal to multiplying by 2
67   // result should be 1.2345 again
68 
69   EXPECT_EQ(digits[0], uint8_t(1));
70   EXPECT_EQ(digits[1], uint8_t(2));
71   EXPECT_EQ(digits[2], uint8_t(3));
72   EXPECT_EQ(digits[3], uint8_t(4));
73   EXPECT_EQ(digits[4], uint8_t(5));
74   EXPECT_EQ(hpd.get_num_digits(), 5u);
75   EXPECT_EQ(hpd.get_decimal_point(), 1);
76 
77   hpd.shift(1); // shift left one again
78   // result should be 2.469
79 
80   EXPECT_EQ(digits[0], uint8_t(2));
81   EXPECT_EQ(digits[1], uint8_t(4));
82   EXPECT_EQ(digits[2], uint8_t(6));
83   EXPECT_EQ(digits[3], uint8_t(9));
84   EXPECT_EQ(hpd.get_num_digits(), 4u);
85   EXPECT_EQ(hpd.get_decimal_point(), 1);
86 
87   hpd.shift(-1); // shift right one again
88   // result should be 1.2345 again
89 
90   EXPECT_EQ(digits[0], uint8_t(1));
91   EXPECT_EQ(digits[1], uint8_t(2));
92   EXPECT_EQ(digits[2], uint8_t(3));
93   EXPECT_EQ(digits[3], uint8_t(4));
94   EXPECT_EQ(digits[4], uint8_t(5));
95   EXPECT_EQ(hpd.get_num_digits(), 5u);
96   EXPECT_EQ(hpd.get_decimal_point(), 1);
97 }
98 
99 TEST(LlvmLibcHighPrecisionDecimalTest, MediumShift) {
100   __llvm_libc::internal::HighPrecisionDecimal hpd =
101       __llvm_libc::internal::HighPrecisionDecimal(".299792458");
102   uint8_t *digits = hpd.get_digits();
103 
104   hpd.shift(-3); // shift right three, equal to dividing by 8
105   // result should be 0.03747405725
106 
107   EXPECT_EQ(digits[0], uint8_t(3));
108   EXPECT_EQ(digits[1], uint8_t(7));
109   EXPECT_EQ(digits[2], uint8_t(4));
110   EXPECT_EQ(digits[3], uint8_t(7));
111   EXPECT_EQ(digits[4], uint8_t(4));
112   EXPECT_EQ(digits[5], uint8_t(0));
113   EXPECT_EQ(digits[6], uint8_t(5));
114   EXPECT_EQ(digits[7], uint8_t(7));
115   EXPECT_EQ(digits[8], uint8_t(2));
116   EXPECT_EQ(digits[9], uint8_t(5));
117   EXPECT_EQ(hpd.get_num_digits(), 10u);
118   EXPECT_EQ(hpd.get_decimal_point(), -1);
119 
120   hpd.shift(3); // shift left three, equal to multiplying by 8
121   // result should be 0.299792458 again
122 
123   EXPECT_EQ(digits[0], uint8_t(2));
124   EXPECT_EQ(digits[1], uint8_t(9));
125   EXPECT_EQ(digits[2], uint8_t(9));
126   EXPECT_EQ(digits[3], uint8_t(7));
127   EXPECT_EQ(digits[4], uint8_t(9));
128   EXPECT_EQ(digits[5], uint8_t(2));
129   EXPECT_EQ(digits[6], uint8_t(4));
130   EXPECT_EQ(digits[7], uint8_t(5));
131   EXPECT_EQ(digits[8], uint8_t(8));
132   EXPECT_EQ(hpd.get_num_digits(), 9u);
133   EXPECT_EQ(hpd.get_decimal_point(), 0);
134 }
135 
136 TEST(LlvmLibcHighPrecisionDecimalTest, BigShift) {
137   __llvm_libc::internal::HighPrecisionDecimal hpd =
138       __llvm_libc::internal::HighPrecisionDecimal(".299792458");
139   uint8_t *digits = hpd.get_digits();
140 
141   hpd.shift(-29); // shift right 29, equal to dividing by 536,870,912
142   // result should be 0.0000000005584069676697254180908203125
143 
144   EXPECT_EQ(digits[0], uint8_t(5));
145   EXPECT_EQ(digits[1], uint8_t(5));
146   EXPECT_EQ(digits[2], uint8_t(8));
147   EXPECT_EQ(digits[3], uint8_t(4));
148   EXPECT_EQ(digits[4], uint8_t(0));
149   EXPECT_EQ(digits[5], uint8_t(6));
150   EXPECT_EQ(digits[6], uint8_t(9));
151   EXPECT_EQ(digits[7], uint8_t(6));
152   EXPECT_EQ(digits[8], uint8_t(7));
153   EXPECT_EQ(digits[9], uint8_t(6));
154   EXPECT_EQ(digits[10], uint8_t(6));
155   EXPECT_EQ(digits[11], uint8_t(9));
156   EXPECT_EQ(digits[12], uint8_t(7));
157   EXPECT_EQ(digits[13], uint8_t(2));
158   EXPECT_EQ(digits[14], uint8_t(5));
159   EXPECT_EQ(digits[15], uint8_t(4));
160   EXPECT_EQ(digits[16], uint8_t(1));
161   EXPECT_EQ(digits[17], uint8_t(8));
162   EXPECT_EQ(digits[18], uint8_t(0));
163   EXPECT_EQ(digits[19], uint8_t(9));
164   EXPECT_EQ(digits[20], uint8_t(0));
165   EXPECT_EQ(digits[21], uint8_t(8));
166   EXPECT_EQ(digits[22], uint8_t(2));
167   EXPECT_EQ(digits[23], uint8_t(0));
168   EXPECT_EQ(digits[24], uint8_t(3));
169   EXPECT_EQ(digits[25], uint8_t(1));
170   EXPECT_EQ(digits[26], uint8_t(2));
171   EXPECT_EQ(digits[27], uint8_t(5));
172   EXPECT_EQ(hpd.get_num_digits(), 28u);
173   EXPECT_EQ(hpd.get_decimal_point(), -9);
174 
175   hpd.shift(29); // shift left 29, equal to multiplying by 536,870,912
176   // result should be 0.299792458 again
177 
178   EXPECT_EQ(digits[0], uint8_t(2));
179   EXPECT_EQ(digits[1], uint8_t(9));
180   EXPECT_EQ(digits[2], uint8_t(9));
181   EXPECT_EQ(digits[3], uint8_t(7));
182   EXPECT_EQ(digits[4], uint8_t(9));
183   EXPECT_EQ(digits[5], uint8_t(2));
184   EXPECT_EQ(digits[6], uint8_t(4));
185   EXPECT_EQ(digits[7], uint8_t(5));
186   EXPECT_EQ(digits[8], uint8_t(8));
187   EXPECT_EQ(hpd.get_num_digits(), 9u);
188   EXPECT_EQ(hpd.get_decimal_point(), 0);
189 }
190 
191 TEST(LlvmLibcHighPrecisionDecimalTest, BigShiftInSteps) {
192   __llvm_libc::internal::HighPrecisionDecimal hpd =
193       __llvm_libc::internal::HighPrecisionDecimal("1");
194   uint8_t *digits = hpd.get_digits();
195 
196   hpd.shift(60); // shift left 60, equal to multiplying by
197                  // 1152921504606846976.
198 
199   EXPECT_EQ(digits[0], uint8_t(1));
200   EXPECT_EQ(digits[1], uint8_t(1));
201   EXPECT_EQ(digits[2], uint8_t(5));
202   EXPECT_EQ(digits[3], uint8_t(2));
203   EXPECT_EQ(digits[4], uint8_t(9));
204   EXPECT_EQ(digits[5], uint8_t(2));
205   EXPECT_EQ(digits[6], uint8_t(1));
206   EXPECT_EQ(digits[7], uint8_t(5));
207   EXPECT_EQ(digits[8], uint8_t(0));
208   EXPECT_EQ(digits[9], uint8_t(4));
209   EXPECT_EQ(digits[10], uint8_t(6));
210   EXPECT_EQ(digits[11], uint8_t(0));
211   EXPECT_EQ(digits[12], uint8_t(6));
212   EXPECT_EQ(digits[13], uint8_t(8));
213   EXPECT_EQ(digits[14], uint8_t(4));
214   EXPECT_EQ(digits[15], uint8_t(6));
215   EXPECT_EQ(digits[16], uint8_t(9));
216   EXPECT_EQ(digits[17], uint8_t(7));
217   EXPECT_EQ(digits[18], uint8_t(6));
218   EXPECT_EQ(hpd.get_num_digits(), 19u);
219   EXPECT_EQ(hpd.get_decimal_point(), 19);
220 
221   hpd.shift(40); // shift left 40, equal to multiplying by
222                  // 1099511627776. Result should be 2^100
223 
224   EXPECT_EQ(digits[0], uint8_t(1));
225   EXPECT_EQ(digits[1], uint8_t(2));
226   EXPECT_EQ(digits[2], uint8_t(6));
227   EXPECT_EQ(digits[3], uint8_t(7));
228   EXPECT_EQ(digits[4], uint8_t(6));
229   EXPECT_EQ(digits[5], uint8_t(5));
230   EXPECT_EQ(digits[6], uint8_t(0));
231   EXPECT_EQ(digits[7], uint8_t(6));
232   EXPECT_EQ(digits[8], uint8_t(0));
233   EXPECT_EQ(digits[9], uint8_t(0));
234   EXPECT_EQ(digits[10], uint8_t(2));
235   EXPECT_EQ(digits[11], uint8_t(2));
236   EXPECT_EQ(digits[12], uint8_t(8));
237   EXPECT_EQ(digits[13], uint8_t(2));
238   EXPECT_EQ(digits[14], uint8_t(2));
239   EXPECT_EQ(digits[15], uint8_t(9));
240   EXPECT_EQ(digits[16], uint8_t(4));
241   EXPECT_EQ(digits[17], uint8_t(0));
242   EXPECT_EQ(digits[18], uint8_t(1));
243   EXPECT_EQ(digits[19], uint8_t(4));
244   EXPECT_EQ(digits[20], uint8_t(9));
245   EXPECT_EQ(digits[21], uint8_t(6));
246   EXPECT_EQ(digits[22], uint8_t(7));
247   EXPECT_EQ(digits[23], uint8_t(0));
248   EXPECT_EQ(digits[24], uint8_t(3));
249   EXPECT_EQ(digits[25], uint8_t(2));
250   EXPECT_EQ(digits[26], uint8_t(0));
251   EXPECT_EQ(digits[27], uint8_t(5));
252   EXPECT_EQ(digits[28], uint8_t(3));
253   EXPECT_EQ(digits[29], uint8_t(7));
254   EXPECT_EQ(digits[30], uint8_t(6));
255 
256   EXPECT_EQ(hpd.get_num_digits(), 31u);
257   EXPECT_EQ(hpd.get_decimal_point(), 31);
258 
259   hpd.shift(-60); // shift right 60, equal to dividing by
260                   // 1152921504606846976. Result should be 2^40
261 
262   EXPECT_EQ(digits[0], uint8_t(1));
263   EXPECT_EQ(digits[1], uint8_t(0));
264   EXPECT_EQ(digits[2], uint8_t(9));
265   EXPECT_EQ(digits[3], uint8_t(9));
266   EXPECT_EQ(digits[4], uint8_t(5));
267   EXPECT_EQ(digits[5], uint8_t(1));
268   EXPECT_EQ(digits[6], uint8_t(1));
269   EXPECT_EQ(digits[7], uint8_t(6));
270   EXPECT_EQ(digits[8], uint8_t(2));
271   EXPECT_EQ(digits[9], uint8_t(7));
272   EXPECT_EQ(digits[10], uint8_t(7));
273   EXPECT_EQ(digits[11], uint8_t(7));
274   EXPECT_EQ(digits[12], uint8_t(6));
275 
276   EXPECT_EQ(hpd.get_num_digits(), 13u);
277   EXPECT_EQ(hpd.get_decimal_point(), 13);
278 
279   hpd.shift(-40); // shift right 40, equal to dividing by
280                   // 1099511627776. Result should be 1
281 
282   EXPECT_EQ(digits[0], uint8_t(1));
283 
284   EXPECT_EQ(hpd.get_num_digits(), 1u);
285   EXPECT_EQ(hpd.get_decimal_point(), 1);
286 }
287 
288 TEST(LlvmLibcHighPrecisionDecimalTest, VeryBigShift) {
289   __llvm_libc::internal::HighPrecisionDecimal hpd =
290       __llvm_libc::internal::HighPrecisionDecimal("1");
291   uint8_t *digits = hpd.get_digits();
292 
293   hpd.shift(100); // shift left 100, equal to multiplying by
294                   // 1267650600228229401496703205376.
295   // result should be 2^100
296 
297   EXPECT_EQ(digits[0], uint8_t(1));
298   EXPECT_EQ(digits[1], uint8_t(2));
299   EXPECT_EQ(digits[2], uint8_t(6));
300   EXPECT_EQ(digits[3], uint8_t(7));
301   EXPECT_EQ(digits[4], uint8_t(6));
302   EXPECT_EQ(digits[5], uint8_t(5));
303   EXPECT_EQ(digits[6], uint8_t(0));
304   EXPECT_EQ(digits[7], uint8_t(6));
305   EXPECT_EQ(digits[8], uint8_t(0));
306   EXPECT_EQ(digits[9], uint8_t(0));
307   EXPECT_EQ(digits[10], uint8_t(2));
308   EXPECT_EQ(digits[11], uint8_t(2));
309   EXPECT_EQ(digits[12], uint8_t(8));
310   EXPECT_EQ(digits[13], uint8_t(2));
311   EXPECT_EQ(digits[14], uint8_t(2));
312   EXPECT_EQ(digits[15], uint8_t(9));
313   EXPECT_EQ(digits[16], uint8_t(4));
314   EXPECT_EQ(digits[17], uint8_t(0));
315   EXPECT_EQ(digits[18], uint8_t(1));
316   EXPECT_EQ(digits[19], uint8_t(4));
317   EXPECT_EQ(digits[20], uint8_t(9));
318   EXPECT_EQ(digits[21], uint8_t(6));
319   EXPECT_EQ(digits[22], uint8_t(7));
320   EXPECT_EQ(digits[23], uint8_t(0));
321   EXPECT_EQ(digits[24], uint8_t(3));
322   EXPECT_EQ(digits[25], uint8_t(2));
323   EXPECT_EQ(digits[26], uint8_t(0));
324   EXPECT_EQ(digits[27], uint8_t(5));
325   EXPECT_EQ(digits[28], uint8_t(3));
326   EXPECT_EQ(digits[29], uint8_t(7));
327   EXPECT_EQ(digits[30], uint8_t(6));
328 
329   EXPECT_EQ(hpd.get_num_digits(), 31u);
330   EXPECT_EQ(hpd.get_decimal_point(), 31);
331 
332   hpd.shift(-100); // shift right 100, equal to dividing by
333                    // 1267650600228229401496703205376.
334   // result should be 1
335 
336   EXPECT_EQ(digits[0], uint8_t(1));
337   EXPECT_EQ(hpd.get_num_digits(), 1u);
338   EXPECT_EQ(hpd.get_decimal_point(), 1);
339 }
340 
341 TEST(LlvmLibcHighPrecisionDecimalTest, RoundingTest) {
342   __llvm_libc::internal::HighPrecisionDecimal hpd =
343       __llvm_libc::internal::HighPrecisionDecimal("1.2345");
344 
345   EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(1));
346   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1));
347 #ifdef __SIZEOF_INT128__
348   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(1));
349 #endif
350 
351   hpd.shift(1); // shift left 1 to get 2.469 (rounds to 2)
352 
353   EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2));
354   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2));
355 #ifdef __SIZEOF_INT128__
356   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(2));
357 #endif
358 
359   hpd.shift(1); // shift left 1 to get 4.938 (rounds to 5)
360 
361   EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(5));
362   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(5));
363 #ifdef __SIZEOF_INT128__
364   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(5));
365 #endif
366 
367   // 2.5 is right between two integers, so we round to even (2)
368   hpd = __llvm_libc::internal::HighPrecisionDecimal("2.5");
369 
370   EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2));
371   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2));
372 #ifdef __SIZEOF_INT128__
373   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(2));
374 #endif
375 
376   // unless it's marked as having truncated, which means it's actually slightly
377   // higher, forcing a round up (3)
378   hpd.set_truncated(true);
379 
380   EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(3));
381   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(3));
382 #ifdef __SIZEOF_INT128__
383   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(3));
384 #endif
385 
386   // Check that the larger int types are being handled properly (overflow is not
387   // handled, so int types that are too small are ignored for this test.)
388 
389   // 1099511627776 = 2^40
390   hpd = __llvm_libc::internal::HighPrecisionDecimal("1099511627776");
391 
392   EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1099511627776));
393 #ifdef __SIZEOF_INT128__
394   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(),
395             __uint128_t(1099511627776));
396 
397   // 1267650600228229401496703205376 = 2^100
398   hpd = __llvm_libc::internal::HighPrecisionDecimal(
399       "1267650600228229401496703205376");
400 
401   __uint128_t result = __uint128_t(1) << 100;
402 
403   EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), result);
404 #endif
405 }
406