437 lines · cpp
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-exception6//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(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(-1); // shift right one, equal to dividing by 257 // result should be 0.6172558 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(1); // shift left one, equal to multiplying by 268 // result should be 1.2345 again69 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(1); // shift left one again79 // result should be 2.46980 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(-1); // shift right one again89 // result should be 1.2345 again90 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(-3); // shift right three, equal to dividing by 8106 // result should be 0.03747405725107 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(3); // shift left three, equal to multiplying by 8122 // result should be 0.299792458 again123 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(-29); // shift right 29, equal to dividing by 536,870,912143 // result should be 0.0000000005584069676697254180908203125144 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(29); // shift left 29, equal to multiplying by 536,870,912177 // result should be 0.299792458 again178 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(60); // shift left 60, equal to multiplying by198 // 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(40); // shift left 40, equal to multiplying by223 // 1099511627776. Result should be 2^100224 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(-60); // shift right 60, equal to dividing by261 // 1152921504606846976. Result should be 2^40262 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(-40); // shift right 40, equal to dividing by281 // 1099511627776. Result should be 1282 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(100); // shift left 100, equal to multiplying by295 // 1267650600228229401496703205376.296 // result should be 2^100297 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(-100); // shift right 100, equal to dividing by334 // 1267650600228229401496703205376.335 // result should be 1336 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(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(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 slightly370 // 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 not378 // handled, so int types that are too small are ignored for this test.)379 380 // 1099511627776 = 2^40381 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^100387 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 our400 // 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 -123456788407 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 of415 // 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