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