brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.3 KiB · 7a3c323 Raw
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