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 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(1)); 348 349 hpd.shift(1); // shift left 1 to get 2.469 (rounds to 2) 350 351 EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2)); 352 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2)); 353 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(2)); 354 355 hpd.shift(1); // shift left 1 to get 4.938 (rounds to 5) 356 357 EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(5)); 358 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(5)); 359 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(5)); 360 361 // 2.5 is right between two integers, so we round to even (2) 362 hpd = __llvm_libc::internal::HighPrecisionDecimal("2.5"); 363 364 EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2)); 365 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2)); 366 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(2)); 367 368 // unless it's marked as having truncated, which means it's actually slightly 369 // higher, forcing a round up (3) 370 hpd.set_truncated(true); 371 372 EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(3)); 373 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(3)); 374 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), __uint128_t(3)); 375 376 // Check that the larger int types are being handled properly (overflow is not 377 // handled, so int types that are too small are ignored for this test.) 378 379 // 1099511627776 = 2^40 380 hpd = __llvm_libc::internal::HighPrecisionDecimal("1099511627776"); 381 382 EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1099511627776)); 383 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), 384 __uint128_t(1099511627776)); 385 386 // 1267650600228229401496703205376 = 2^100 387 hpd = __llvm_libc::internal::HighPrecisionDecimal( 388 "1267650600228229401496703205376"); 389 390 __uint128_t result = __uint128_t(1) << 100; 391 392 EXPECT_EQ(hpd.round_to_integer_type<__uint128_t>(), result); 393 } 394