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#include "src/__support/uint128.h"
11
12#include "test/UnitTest/Test.h"
13
14TEST(LlvmLibcHighPrecisionDecimalTest, BasicInit) {
15 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
16 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
17 uint8_t *digits = hpd.get_digits();
18
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);
26}
27
28TEST(LlvmLibcHighPrecisionDecimalTest, BasicShift) {
29 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
30 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
31 uint8_t *digits = hpd.get_digits();
32
33 hpd.shift(shift_amount: 1); // shift left 1, equal to multiplying by 2.
34
35 EXPECT_EQ(digits[0], uint8_t(2));
36 EXPECT_EQ(hpd.get_num_digits(), 1u);
37 EXPECT_EQ(hpd.get_decimal_point(), 1);
38}
39
40TEST(LlvmLibcHighPrecisionDecimalTest, ShouldRoundup) {
41 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
42 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".5");
43 uint8_t *digits = hpd.get_digits();
44
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);
49}
50
51TEST(LlvmLibcHighPrecisionDecimalTest, SmallShift) {
52 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
53 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
54 uint8_t *digits = hpd.get_digits();
55
56 hpd.shift(shift_amount: -1); // shift right one, equal to dividing by 2
57 // result should be 0.61725
58
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);
66
67 hpd.shift(shift_amount: 1); // shift left one, equal to multiplying by 2
68 // result should be 1.2345 again
69
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);
77
78 hpd.shift(shift_amount: 1); // shift left one again
79 // result should be 2.469
80
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);
87
88 hpd.shift(shift_amount: -1); // shift right one again
89 // result should be 1.2345 again
90
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);
98}
99
100TEST(LlvmLibcHighPrecisionDecimalTest, MediumShift) {
101 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
102 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
103 uint8_t *digits = hpd.get_digits();
104
105 hpd.shift(shift_amount: -3); // shift right three, equal to dividing by 8
106 // result should be 0.03747405725
107
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);
120
121 hpd.shift(shift_amount: 3); // shift left three, equal to multiplying by 8
122 // result should be 0.299792458 again
123
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);
135}
136
137TEST(LlvmLibcHighPrecisionDecimalTest, BigShift) {
138 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
139 LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
140 uint8_t *digits = hpd.get_digits();
141
142 hpd.shift(shift_amount: -29); // shift right 29, equal to dividing by 536,870,912
143 // result should be 0.0000000005584069676697254180908203125
144
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);
175
176 hpd.shift(shift_amount: 29); // shift left 29, equal to multiplying by 536,870,912
177 // result should be 0.299792458 again
178
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);
190}
191
192TEST(LlvmLibcHighPrecisionDecimalTest, BigShiftInSteps) {
193 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
194 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
195 uint8_t *digits = hpd.get_digits();
196
197 hpd.shift(shift_amount: 60); // shift left 60, equal to multiplying by
198 // 1152921504606846976.
199
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);
221
222 hpd.shift(shift_amount: 40); // shift left 40, equal to multiplying by
223 // 1099511627776. Result should be 2^100
224
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));
256
257 EXPECT_EQ(hpd.get_num_digits(), 31u);
258 EXPECT_EQ(hpd.get_decimal_point(), 31);
259
260 hpd.shift(shift_amount: -60); // shift right 60, equal to dividing by
261 // 1152921504606846976. Result should be 2^40
262
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));
276
277 EXPECT_EQ(hpd.get_num_digits(), 13u);
278 EXPECT_EQ(hpd.get_decimal_point(), 13);
279
280 hpd.shift(shift_amount: -40); // shift right 40, equal to dividing by
281 // 1099511627776. Result should be 1
282
283 EXPECT_EQ(digits[0], uint8_t(1));
284
285 EXPECT_EQ(hpd.get_num_digits(), 1u);
286 EXPECT_EQ(hpd.get_decimal_point(), 1);
287}
288
289TEST(LlvmLibcHighPrecisionDecimalTest, VeryBigShift) {
290 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
291 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
292 uint8_t *digits = hpd.get_digits();
293
294 hpd.shift(shift_amount: 100); // shift left 100, equal to multiplying by
295 // 1267650600228229401496703205376.
296 // result should be 2^100
297
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));
329
330 EXPECT_EQ(hpd.get_num_digits(), 31u);
331 EXPECT_EQ(hpd.get_decimal_point(), 31);
332
333 hpd.shift(shift_amount: -100); // shift right 100, equal to dividing by
334 // 1267650600228229401496703205376.
335 // result should be 1
336
337 EXPECT_EQ(digits[0], uint8_t(1));
338 EXPECT_EQ(hpd.get_num_digits(), 1u);
339 EXPECT_EQ(hpd.get_decimal_point(), 1);
340}
341
342TEST(LlvmLibcHighPrecisionDecimalTest, RoundingTest) {
343 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
344 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
345
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));
349
350 hpd.shift(shift_amount: 1); // shift left 1 to get 2.469 (rounds to 2)
351
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));
355
356 hpd.shift(shift_amount: 1); // shift left 1 to get 4.938 (rounds to 5)
357
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));
361
362 // 2.5 is right between two integers, so we round to even (2)
363 hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal("2.5");
364
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));
368
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);
372
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));
376
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.)
379
380 // 1099511627776 = 2^40
381 hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal("1099511627776");
382
383 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1099511627776));
384 EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(1099511627776));
385
386 // 1267650600228229401496703205376 = 2^100
387 hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal(
388 "1267650600228229401496703205376");
389
390 UInt128 result = UInt128(1) << 100;
391
392 EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), result);
393}
394
395TEST(LlvmLibcHighPrecisionDecimalTest, BigExpTest) {
396 LIBC_NAMESPACE::internal::HighPrecisionDecimal big_hpd =
397 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789");
398
399 // We need to add one to handle the digit before the decimal point in our
400 // number.
401 EXPECT_EQ(big_hpd.get_decimal_point(), 123456789 + 1);
402
403 LIBC_NAMESPACE::internal::HighPrecisionDecimal big_negative_hpd =
404 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789");
405
406 // Same, but since the number is negative the net result is -123456788
407 EXPECT_EQ(big_negative_hpd.get_decimal_point(), -123456789 + 1);
408}
409
410TEST(LlvmLibcHighPrecisionDecimalTest, NumLenExpTest) {
411 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
412 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789", 5);
413
414 // The length of 5 includes things like the "e" so it only gets 3 digits of
415 // exponent.
416 EXPECT_EQ(hpd.get_decimal_point(), 123 + 1);
417
418 LIBC_NAMESPACE::internal::HighPrecisionDecimal negative_hpd =
419 LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789", 5);
420
421 // The negative sign also counts as a character.
422 EXPECT_EQ(negative_hpd.get_decimal_point(), -12 + 1);
423}
424
425TEST(LlvmLibcHighPrecisionDecimalTest, NumLenDigitsTest) {
426 LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
427 LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 5);
428
429 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(12345));
430
431 LIBC_NAMESPACE::internal::HighPrecisionDecimal longer_hpd =
432 LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 10);
433
434 // With 10 characters it should see the e, but not actually act on it.
435 EXPECT_EQ(longer_hpd.round_to_integer_type<uint64_t>(), uint64_t(123456789));
436}
437

source code of libc/test/src/__support/high_precision_decimal_test.cpp