diff options
Diffstat (limited to 'abseil-cpp/absl/numeric/int128_test.cc')
-rw-r--r-- | abseil-cpp/absl/numeric/int128_test.cc | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/abseil-cpp/absl/numeric/int128_test.cc b/abseil-cpp/absl/numeric/int128_test.cc index bc86c71..01e3eb5 100644 --- a/abseil-cpp/absl/numeric/int128_test.cc +++ b/abseil-cpp/absl/numeric/int128_test.cc @@ -32,6 +32,8 @@ #pragma warning(disable:4146) #endif +#define MAKE_INT128(HI, LO) absl::MakeInt128(static_cast<int64_t>(HI), LO) + namespace { template <typename T> @@ -226,6 +228,11 @@ TEST(Uint128, AllTests) { EXPECT_EQ(test >>= 1, one); EXPECT_EQ(test <<= 1, two); + EXPECT_EQ(big, +big); + EXPECT_EQ(two, +two); + EXPECT_EQ(absl::Uint128Max(), +absl::Uint128Max()); + EXPECT_EQ(zero, +zero); + EXPECT_EQ(big, -(-big)); EXPECT_EQ(two, -((-one) - 1)); EXPECT_EQ(absl::Uint128Max(), -one); @@ -234,6 +241,24 @@ TEST(Uint128, AllTests) { EXPECT_EQ(absl::Uint128Max(), absl::kuint128max); } +TEST(Int128, RightShiftOfNegativeNumbers) { + absl::int128 minus_six = -6; + absl::int128 minus_three = -3; + absl::int128 minus_two = -2; + absl::int128 minus_one = -1; + if ((-6 >> 1) == -3) { + // Right shift is arithmetic (sign propagates) + EXPECT_EQ(minus_six >> 1, minus_three); + EXPECT_EQ(minus_six >> 2, minus_two); + EXPECT_EQ(minus_six >> 65, minus_one); + } else { + // Right shift is logical (zeros shifted in at MSB) + EXPECT_EQ(minus_six >> 1, absl::int128(absl::uint128(minus_six) >> 1)); + EXPECT_EQ(minus_six >> 2, absl::int128(absl::uint128(minus_six) >> 2)); + EXPECT_EQ(minus_six >> 65, absl::int128(absl::uint128(minus_six) >> 65)); + } +} + TEST(Uint128, ConversionTests) { EXPECT_TRUE(absl::MakeUint128(1, 0)); @@ -260,8 +285,9 @@ TEST(Uint128, ConversionTests) { EXPECT_EQ(from_precise_double, from_precise_ints); EXPECT_DOUBLE_EQ(static_cast<double>(from_precise_ints), precise_double); - double approx_double = 0xffffeeeeddddcccc * std::pow(2.0, 64.0) + - 0xbbbbaaaa99998888; + double approx_double = + static_cast<double>(0xffffeeeeddddcccc) * std::pow(2.0, 64.0) + + static_cast<double>(0xbbbbaaaa99998888); absl::uint128 from_approx_double(approx_double); EXPECT_DOUBLE_EQ(static_cast<double>(from_approx_double), approx_double); @@ -769,6 +795,19 @@ TEST(Int128, ComparisonTest) { } } +TEST(Int128, UnaryPlusTest) { + int64_t values64[] = {0, 1, 12345, 0x4000000000000000, + std::numeric_limits<int64_t>::max()}; + for (int64_t value : values64) { + SCOPED_TRACE(::testing::Message() << "value = " << value); + + EXPECT_EQ(absl::int128(value), +absl::int128(value)); + EXPECT_EQ(absl::int128(-value), +absl::int128(-value)); + EXPECT_EQ(absl::MakeInt128(value, 0), +absl::MakeInt128(value, 0)); + EXPECT_EQ(absl::MakeInt128(-value, 0), +absl::MakeInt128(-value, 0)); + } +} + TEST(Int128, UnaryNegationTest) { int64_t values64[] = {0, 1, 12345, 0x4000000000000000, std::numeric_limits<int64_t>::max()}; @@ -1209,6 +1248,27 @@ TEST(Int128, BitwiseShiftTest) { absl::MakeInt128(uint64_t{1} << j, 0) >>= (j - i)); } } + + // Manually calculated cases with shift count for positive (val1) and negative + // (val2) values + absl::int128 val1 = MAKE_INT128(0x123456789abcdef0, 0x123456789abcdef0); + absl::int128 val2 = MAKE_INT128(0xfedcba0987654321, 0xfedcba0987654321); + + EXPECT_EQ(val1 << 63, MAKE_INT128(0x91a2b3c4d5e6f78, 0x0)); + EXPECT_EQ(val1 << 64, MAKE_INT128(0x123456789abcdef0, 0x0)); + EXPECT_EQ(val2 << 63, MAKE_INT128(0xff6e5d04c3b2a190, 0x8000000000000000)); + EXPECT_EQ(val2 << 64, MAKE_INT128(0xfedcba0987654321, 0x0)); + + EXPECT_EQ(val1 << 126, MAKE_INT128(0x0, 0x0)); + EXPECT_EQ(val2 << 126, MAKE_INT128(0x4000000000000000, 0x0)); + + EXPECT_EQ(val1 >> 63, MAKE_INT128(0x0, 0x2468acf13579bde0)); + EXPECT_EQ(val1 >> 64, MAKE_INT128(0x0, 0x123456789abcdef0)); + EXPECT_EQ(val2 >> 63, MAKE_INT128(0xffffffffffffffff, 0xfdb974130eca8643)); + EXPECT_EQ(val2 >> 64, MAKE_INT128(0xffffffffffffffff, 0xfedcba0987654321)); + + EXPECT_EQ(val1 >> 126, MAKE_INT128(0x0, 0x0)); + EXPECT_EQ(val2 >> 126, MAKE_INT128(0xffffffffffffffff, 0xffffffffffffffff)); } TEST(Int128, NumericLimitsTest) { |