#include "src/__support/high_precision_decimal.h"
#include "src/__support/uint128.h"
#include "test/UnitTest/Test.h"
TEST(LlvmLibcHighPrecisionDecimalTest, BasicInit) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
uint8_t *digits = hpd.get_digits();
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(2));
EXPECT_EQ(digits[2], uint8_t(3));
EXPECT_EQ(digits[3], uint8_t(4));
EXPECT_EQ(digits[4], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 5u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, BasicShift) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
uint8_t *digits = hpd.get_digits();
hpd.shift(1);
EXPECT_EQ(digits[0], uint8_t(2));
EXPECT_EQ(hpd.get_num_digits(), 1u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, ShouldRoundup) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal(".5");
uint8_t *digits = hpd.get_digits();
EXPECT_EQ(digits[0], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 1u);
EXPECT_EQ(hpd.get_decimal_point(), 0);
EXPECT_EQ(hpd.round_to_integer_type<int>(), 0);
}
TEST(LlvmLibcHighPrecisionDecimalTest, SmallShift) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
uint8_t *digits = hpd.get_digits();
hpd.shift(-1);
EXPECT_EQ(digits[0], uint8_t(6));
EXPECT_EQ(digits[1], uint8_t(1));
EXPECT_EQ(digits[2], uint8_t(7));
EXPECT_EQ(digits[3], uint8_t(2));
EXPECT_EQ(digits[4], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 5u);
EXPECT_EQ(hpd.get_decimal_point(), 0);
hpd.shift(1);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(2));
EXPECT_EQ(digits[2], uint8_t(3));
EXPECT_EQ(digits[3], uint8_t(4));
EXPECT_EQ(digits[4], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 5u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
hpd.shift(1);
EXPECT_EQ(digits[0], uint8_t(2));
EXPECT_EQ(digits[1], uint8_t(4));
EXPECT_EQ(digits[2], uint8_t(6));
EXPECT_EQ(digits[3], uint8_t(9));
EXPECT_EQ(hpd.get_num_digits(), 4u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
hpd.shift(-1);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(2));
EXPECT_EQ(digits[2], uint8_t(3));
EXPECT_EQ(digits[3], uint8_t(4));
EXPECT_EQ(digits[4], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 5u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, MediumShift) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
uint8_t *digits = hpd.get_digits();
hpd.shift(-3);
EXPECT_EQ(digits[0], uint8_t(3));
EXPECT_EQ(digits[1], uint8_t(7));
EXPECT_EQ(digits[2], uint8_t(4));
EXPECT_EQ(digits[3], uint8_t(7));
EXPECT_EQ(digits[4], uint8_t(4));
EXPECT_EQ(digits[5], uint8_t(0));
EXPECT_EQ(digits[6], uint8_t(5));
EXPECT_EQ(digits[7], uint8_t(7));
EXPECT_EQ(digits[8], uint8_t(2));
EXPECT_EQ(digits[9], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 10u);
EXPECT_EQ(hpd.get_decimal_point(), -1);
hpd.shift(3);
EXPECT_EQ(digits[0], uint8_t(2));
EXPECT_EQ(digits[1], uint8_t(9));
EXPECT_EQ(digits[2], uint8_t(9));
EXPECT_EQ(digits[3], uint8_t(7));
EXPECT_EQ(digits[4], uint8_t(9));
EXPECT_EQ(digits[5], uint8_t(2));
EXPECT_EQ(digits[6], uint8_t(4));
EXPECT_EQ(digits[7], uint8_t(5));
EXPECT_EQ(digits[8], uint8_t(8));
EXPECT_EQ(hpd.get_num_digits(), 9u);
EXPECT_EQ(hpd.get_decimal_point(), 0);
}
TEST(LlvmLibcHighPrecisionDecimalTest, BigShift) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal(".299792458");
uint8_t *digits = hpd.get_digits();
hpd.shift(-29);
EXPECT_EQ(digits[0], uint8_t(5));
EXPECT_EQ(digits[1], uint8_t(5));
EXPECT_EQ(digits[2], uint8_t(8));
EXPECT_EQ(digits[3], uint8_t(4));
EXPECT_EQ(digits[4], uint8_t(0));
EXPECT_EQ(digits[5], uint8_t(6));
EXPECT_EQ(digits[6], uint8_t(9));
EXPECT_EQ(digits[7], uint8_t(6));
EXPECT_EQ(digits[8], uint8_t(7));
EXPECT_EQ(digits[9], uint8_t(6));
EXPECT_EQ(digits[10], uint8_t(6));
EXPECT_EQ(digits[11], uint8_t(9));
EXPECT_EQ(digits[12], uint8_t(7));
EXPECT_EQ(digits[13], uint8_t(2));
EXPECT_EQ(digits[14], uint8_t(5));
EXPECT_EQ(digits[15], uint8_t(4));
EXPECT_EQ(digits[16], uint8_t(1));
EXPECT_EQ(digits[17], uint8_t(8));
EXPECT_EQ(digits[18], uint8_t(0));
EXPECT_EQ(digits[19], uint8_t(9));
EXPECT_EQ(digits[20], uint8_t(0));
EXPECT_EQ(digits[21], uint8_t(8));
EXPECT_EQ(digits[22], uint8_t(2));
EXPECT_EQ(digits[23], uint8_t(0));
EXPECT_EQ(digits[24], uint8_t(3));
EXPECT_EQ(digits[25], uint8_t(1));
EXPECT_EQ(digits[26], uint8_t(2));
EXPECT_EQ(digits[27], uint8_t(5));
EXPECT_EQ(hpd.get_num_digits(), 28u);
EXPECT_EQ(hpd.get_decimal_point(), -9);
hpd.shift(29);
EXPECT_EQ(digits[0], uint8_t(2));
EXPECT_EQ(digits[1], uint8_t(9));
EXPECT_EQ(digits[2], uint8_t(9));
EXPECT_EQ(digits[3], uint8_t(7));
EXPECT_EQ(digits[4], uint8_t(9));
EXPECT_EQ(digits[5], uint8_t(2));
EXPECT_EQ(digits[6], uint8_t(4));
EXPECT_EQ(digits[7], uint8_t(5));
EXPECT_EQ(digits[8], uint8_t(8));
EXPECT_EQ(hpd.get_num_digits(), 9u);
EXPECT_EQ(hpd.get_decimal_point(), 0);
}
TEST(LlvmLibcHighPrecisionDecimalTest, BigShiftInSteps) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
uint8_t *digits = hpd.get_digits();
hpd.shift(60);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(1));
EXPECT_EQ(digits[2], uint8_t(5));
EXPECT_EQ(digits[3], uint8_t(2));
EXPECT_EQ(digits[4], uint8_t(9));
EXPECT_EQ(digits[5], uint8_t(2));
EXPECT_EQ(digits[6], uint8_t(1));
EXPECT_EQ(digits[7], uint8_t(5));
EXPECT_EQ(digits[8], uint8_t(0));
EXPECT_EQ(digits[9], uint8_t(4));
EXPECT_EQ(digits[10], uint8_t(6));
EXPECT_EQ(digits[11], uint8_t(0));
EXPECT_EQ(digits[12], uint8_t(6));
EXPECT_EQ(digits[13], uint8_t(8));
EXPECT_EQ(digits[14], uint8_t(4));
EXPECT_EQ(digits[15], uint8_t(6));
EXPECT_EQ(digits[16], uint8_t(9));
EXPECT_EQ(digits[17], uint8_t(7));
EXPECT_EQ(digits[18], uint8_t(6));
EXPECT_EQ(hpd.get_num_digits(), 19u);
EXPECT_EQ(hpd.get_decimal_point(), 19);
hpd.shift(40);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(2));
EXPECT_EQ(digits[2], uint8_t(6));
EXPECT_EQ(digits[3], uint8_t(7));
EXPECT_EQ(digits[4], uint8_t(6));
EXPECT_EQ(digits[5], uint8_t(5));
EXPECT_EQ(digits[6], uint8_t(0));
EXPECT_EQ(digits[7], uint8_t(6));
EXPECT_EQ(digits[8], uint8_t(0));
EXPECT_EQ(digits[9], uint8_t(0));
EXPECT_EQ(digits[10], uint8_t(2));
EXPECT_EQ(digits[11], uint8_t(2));
EXPECT_EQ(digits[12], uint8_t(8));
EXPECT_EQ(digits[13], uint8_t(2));
EXPECT_EQ(digits[14], uint8_t(2));
EXPECT_EQ(digits[15], uint8_t(9));
EXPECT_EQ(digits[16], uint8_t(4));
EXPECT_EQ(digits[17], uint8_t(0));
EXPECT_EQ(digits[18], uint8_t(1));
EXPECT_EQ(digits[19], uint8_t(4));
EXPECT_EQ(digits[20], uint8_t(9));
EXPECT_EQ(digits[21], uint8_t(6));
EXPECT_EQ(digits[22], uint8_t(7));
EXPECT_EQ(digits[23], uint8_t(0));
EXPECT_EQ(digits[24], uint8_t(3));
EXPECT_EQ(digits[25], uint8_t(2));
EXPECT_EQ(digits[26], uint8_t(0));
EXPECT_EQ(digits[27], uint8_t(5));
EXPECT_EQ(digits[28], uint8_t(3));
EXPECT_EQ(digits[29], uint8_t(7));
EXPECT_EQ(digits[30], uint8_t(6));
EXPECT_EQ(hpd.get_num_digits(), 31u);
EXPECT_EQ(hpd.get_decimal_point(), 31);
hpd.shift(-60);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(0));
EXPECT_EQ(digits[2], uint8_t(9));
EXPECT_EQ(digits[3], uint8_t(9));
EXPECT_EQ(digits[4], uint8_t(5));
EXPECT_EQ(digits[5], uint8_t(1));
EXPECT_EQ(digits[6], uint8_t(1));
EXPECT_EQ(digits[7], uint8_t(6));
EXPECT_EQ(digits[8], uint8_t(2));
EXPECT_EQ(digits[9], uint8_t(7));
EXPECT_EQ(digits[10], uint8_t(7));
EXPECT_EQ(digits[11], uint8_t(7));
EXPECT_EQ(digits[12], uint8_t(6));
EXPECT_EQ(hpd.get_num_digits(), 13u);
EXPECT_EQ(hpd.get_decimal_point(), 13);
hpd.shift(-40);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(hpd.get_num_digits(), 1u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, VeryBigShift) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1");
uint8_t *digits = hpd.get_digits();
hpd.shift(100);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(digits[1], uint8_t(2));
EXPECT_EQ(digits[2], uint8_t(6));
EXPECT_EQ(digits[3], uint8_t(7));
EXPECT_EQ(digits[4], uint8_t(6));
EXPECT_EQ(digits[5], uint8_t(5));
EXPECT_EQ(digits[6], uint8_t(0));
EXPECT_EQ(digits[7], uint8_t(6));
EXPECT_EQ(digits[8], uint8_t(0));
EXPECT_EQ(digits[9], uint8_t(0));
EXPECT_EQ(digits[10], uint8_t(2));
EXPECT_EQ(digits[11], uint8_t(2));
EXPECT_EQ(digits[12], uint8_t(8));
EXPECT_EQ(digits[13], uint8_t(2));
EXPECT_EQ(digits[14], uint8_t(2));
EXPECT_EQ(digits[15], uint8_t(9));
EXPECT_EQ(digits[16], uint8_t(4));
EXPECT_EQ(digits[17], uint8_t(0));
EXPECT_EQ(digits[18], uint8_t(1));
EXPECT_EQ(digits[19], uint8_t(4));
EXPECT_EQ(digits[20], uint8_t(9));
EXPECT_EQ(digits[21], uint8_t(6));
EXPECT_EQ(digits[22], uint8_t(7));
EXPECT_EQ(digits[23], uint8_t(0));
EXPECT_EQ(digits[24], uint8_t(3));
EXPECT_EQ(digits[25], uint8_t(2));
EXPECT_EQ(digits[26], uint8_t(0));
EXPECT_EQ(digits[27], uint8_t(5));
EXPECT_EQ(digits[28], uint8_t(3));
EXPECT_EQ(digits[29], uint8_t(7));
EXPECT_EQ(digits[30], uint8_t(6));
EXPECT_EQ(hpd.get_num_digits(), 31u);
EXPECT_EQ(hpd.get_decimal_point(), 31);
hpd.shift(-100);
EXPECT_EQ(digits[0], uint8_t(1));
EXPECT_EQ(hpd.get_num_digits(), 1u);
EXPECT_EQ(hpd.get_decimal_point(), 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, RoundingTest) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1.2345");
EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(1));
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(1));
hpd.shift(1);
EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2));
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(2));
hpd.shift(1);
EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(5));
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(5));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(5));
hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal("2.5");
EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(2));
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(2));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(2));
hpd.set_truncated(true);
EXPECT_EQ(hpd.round_to_integer_type<uint32_t>(), uint32_t(3));
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(3));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(3));
hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal("1099511627776");
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(1099511627776));
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), UInt128(1099511627776));
hpd = LIBC_NAMESPACE::internal::HighPrecisionDecimal(
"1267650600228229401496703205376");
UInt128 result = UInt128(1) << 100;
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), result);
}
TEST(LlvmLibcHighPrecisionDecimalTest, BigExpTest) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal big_hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789");
EXPECT_EQ(big_hpd.get_decimal_point(), 123456789 + 1);
LIBC_NAMESPACE::internal::HighPrecisionDecimal big_negative_hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789");
EXPECT_EQ(big_negative_hpd.get_decimal_point(), -123456789 + 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, NumLenExpTest) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e123456789", 5);
EXPECT_EQ(hpd.get_decimal_point(), 123 + 1);
LIBC_NAMESPACE::internal::HighPrecisionDecimal negative_hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("1e-123456789", 5);
EXPECT_EQ(negative_hpd.get_decimal_point(), -12 + 1);
}
TEST(LlvmLibcHighPrecisionDecimalTest, NumLenDigitsTest) {
LIBC_NAMESPACE::internal::HighPrecisionDecimal hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 5);
EXPECT_EQ(hpd.round_to_integer_type<uint64_t>(), uint64_t(12345));
LIBC_NAMESPACE::internal::HighPrecisionDecimal longer_hpd =
LIBC_NAMESPACE::internal::HighPrecisionDecimal("123456789e1", 10);
EXPECT_EQ(longer_hpd.round_to_integer_type<uint64_t>(), uint64_t(123456789));
}