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