1 //===-- Unittests for the UInt integer class ------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/__support/CPP/optional.h"
10 #include "src/__support/big_int.h"
11 #include "src/__support/integer_literals.h" // parse_unsigned_bigint
12 #include "src/__support/macros/config.h"
13 #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
15 #include "hdr/math_macros.h" // HUGE_VALF, HUGE_VALF
16 #include "test/UnitTest/Test.h"
18 namespace LIBC_NAMESPACE_DECL
{
20 enum Value
{ ZERO
, ONE
, TWO
, MIN
, MAX
};
22 template <typename T
> auto create(Value value
) {
35 __builtin_unreachable();
38 using Types
= testing::TypeList
< //
39 #ifdef LIBC_TYPES_HAS_INT64
40 BigInt
<64, false, uint64_t>, // 64-bits unsigned (1 x uint64_t)
41 BigInt
<64, true, uint64_t>, // 64-bits signed (1 x uint64_t)
43 #ifdef LIBC_TYPES_HAS_INT128
44 BigInt
<128, false, __uint128_t
>, // 128-bits unsigned (1 x __uint128_t)
45 BigInt
<128, true, __uint128_t
>, // 128-bits signed (1 x __uint128_t)
47 BigInt
<16, false, uint16_t>, // 16-bits unsigned (1 x uint16_t)
48 BigInt
<16, true, uint16_t>, // 16-bits signed (1 x uint16_t)
49 BigInt
<64, false, uint16_t>, // 64-bits unsigned (4 x uint16_t)
50 BigInt
<64, true, uint16_t> // 64-bits signed (4 x uint16_t)
53 #define ASSERT_SAME(A, B) ASSERT_TRUE((A) == (B))
55 TYPED_TEST(LlvmLibcUIntClassTest
, Additions
, Types
) {
56 ASSERT_SAME(create
<T
>(ZERO
) + create
<T
>(ZERO
), create
<T
>(ZERO
));
57 ASSERT_SAME(create
<T
>(ONE
) + create
<T
>(ZERO
), create
<T
>(ONE
));
58 ASSERT_SAME(create
<T
>(ZERO
) + create
<T
>(ONE
), create
<T
>(ONE
));
59 ASSERT_SAME(create
<T
>(ONE
) + create
<T
>(ONE
), create
<T
>(TWO
));
60 // 2's complement addition works for signed and unsigned types.
61 // - unsigned : 0xff + 0x01 = 0x00 (255 + 1 = 0)
62 // - signed : 0xef + 0x01 = 0xf0 (127 + 1 = -128)
63 ASSERT_SAME(create
<T
>(MAX
) + create
<T
>(ONE
), create
<T
>(MIN
));
66 TYPED_TEST(LlvmLibcUIntClassTest
, Subtraction
, Types
) {
67 ASSERT_SAME(create
<T
>(ZERO
) - create
<T
>(ZERO
), create
<T
>(ZERO
));
68 ASSERT_SAME(create
<T
>(ONE
) - create
<T
>(ONE
), create
<T
>(ZERO
));
69 ASSERT_SAME(create
<T
>(ONE
) - create
<T
>(ZERO
), create
<T
>(ONE
));
70 // 2's complement subtraction works for signed and unsigned types.
71 // - unsigned : 0x00 - 0x01 = 0xff ( 0 - 1 = 255)
72 // - signed : 0xf0 - 0x01 = 0xef (-128 - 1 = 127)
73 ASSERT_SAME(create
<T
>(MIN
) - create
<T
>(ONE
), create
<T
>(MAX
));
76 TYPED_TEST(LlvmLibcUIntClassTest
, Multiplication
, Types
) {
77 ASSERT_SAME(create
<T
>(ZERO
) * create
<T
>(ZERO
), create
<T
>(ZERO
));
78 ASSERT_SAME(create
<T
>(ZERO
) * create
<T
>(ONE
), create
<T
>(ZERO
));
79 ASSERT_SAME(create
<T
>(ONE
) * create
<T
>(ZERO
), create
<T
>(ZERO
));
80 ASSERT_SAME(create
<T
>(ONE
) * create
<T
>(ONE
), create
<T
>(ONE
));
81 ASSERT_SAME(create
<T
>(ONE
) * create
<T
>(TWO
), create
<T
>(TWO
));
82 ASSERT_SAME(create
<T
>(TWO
) * create
<T
>(ONE
), create
<T
>(TWO
));
83 // - unsigned : 0xff x 0xff = 0x01 (mod 0xff)
84 // - signed : 0xef x 0xef = 0x01 (mod 0xff)
85 ASSERT_SAME(create
<T
>(MAX
) * create
<T
>(MAX
), create
<T
>(ONE
));
88 template <typename T
> void print(const char *msg
, T value
) {
90 IntegerToString
<T
, radix::Hex
> buffer(value
);
91 testing::tlog
<< buffer
.view() << "\n";
94 TEST(LlvmLibcUIntClassTest
, SignedAddSub
) {
95 // Computations performed by https://www.wolframalpha.com/
96 using T
= BigInt
<128, true, uint32_t>;
97 const T a
= parse_bigint
<T
>("1927508279017230597");
98 const T b
= parse_bigint
<T
>("278789278723478925");
99 const T s
= parse_bigint
<T
>("2206297557740709522");
101 ASSERT_SAME(a
+ b
, s
);
102 ASSERT_SAME(b
+ a
, s
); // commutative
104 ASSERT_SAME(a
- s
, -b
);
105 ASSERT_SAME(s
- a
, b
);
108 TEST(LlvmLibcUIntClassTest
, SignedMulDiv
) {
109 // Computations performed by https://www.wolframalpha.com/
110 using T
= BigInt
<128, true, uint16_t>;
115 } const test_cases
[] = {{"-4", "3", "-12"},
117 {"1927508279017230597", "278789278723478925",
118 "537368642840747885329125014794668225"}};
119 for (auto tc
: test_cases
) {
120 const T a
= parse_bigint
<T
>(tc
.a
);
121 const T b
= parse_bigint
<T
>(tc
.b
);
122 const T mul
= parse_bigint
<T
>(tc
.mul
);
124 ASSERT_SAME(a
* b
, mul
);
125 ASSERT_SAME(b
* a
, mul
); // commutative
126 ASSERT_SAME(a
* -b
, -mul
); // sign
127 ASSERT_SAME(-a
* b
, -mul
); // sign
128 ASSERT_SAME(-a
* -b
, mul
); // sign
130 ASSERT_SAME(mul
/ a
, b
);
131 ASSERT_SAME(mul
/ b
, a
);
132 ASSERT_SAME(-mul
/ a
, -b
); // sign
133 ASSERT_SAME(mul
/ -a
, -b
); // sign
134 ASSERT_SAME(-mul
/ -a
, b
); // sign
138 TYPED_TEST(LlvmLibcUIntClassTest
, Division
, Types
) {
139 ASSERT_SAME(create
<T
>(ZERO
) / create
<T
>(ONE
), create
<T
>(ZERO
));
140 ASSERT_SAME(create
<T
>(MAX
) / create
<T
>(ONE
), create
<T
>(MAX
));
141 ASSERT_SAME(create
<T
>(MAX
) / create
<T
>(MAX
), create
<T
>(ONE
));
142 ASSERT_SAME(create
<T
>(ONE
) / create
<T
>(ONE
), create
<T
>(ONE
));
143 if constexpr (T::SIGNED
) {
144 // Special case found by fuzzing.
145 ASSERT_SAME(create
<T
>(MIN
) / create
<T
>(MIN
), create
<T
>(ONE
));
147 // - unsigned : 0xff / 0x02 = 0x7f
148 // - signed : 0xef / 0x02 = 0x77
149 ASSERT_SAME(create
<T
>(MAX
) / create
<T
>(TWO
), (create
<T
>(MAX
) >> 1));
151 using word_type
= typename
T::word_type
;
152 const T zero_one_repeated
= T::all_ones() / T(0xff);
153 const word_type pattern
= word_type(~0) / word_type(0xff);
154 for (const word_type part
: zero_one_repeated
.val
) {
155 if constexpr (T::SIGNED
== false) {
156 EXPECT_EQ(part
, pattern
);
161 TYPED_TEST(LlvmLibcUIntClassTest
, is_neg
, Types
) {
162 EXPECT_FALSE(create
<T
>(ZERO
).is_neg());
163 EXPECT_FALSE(create
<T
>(ONE
).is_neg());
164 EXPECT_FALSE(create
<T
>(TWO
).is_neg());
165 EXPECT_EQ(create
<T
>(MIN
).is_neg(), T::SIGNED
);
166 EXPECT_FALSE(create
<T
>(MAX
).is_neg());
169 TYPED_TEST(LlvmLibcUIntClassTest
, Masks
, Types
) {
170 if constexpr (!T::SIGNED
) {
171 constexpr size_t BITS
= T::BITS
;
172 // mask_trailing_ones
173 ASSERT_SAME((mask_trailing_ones
<T
, 0>()), T::zero());
174 ASSERT_SAME((mask_trailing_ones
<T
, 1>()), T::one());
175 ASSERT_SAME((mask_trailing_ones
<T
, BITS
- 1>()), T::all_ones() >> 1);
176 ASSERT_SAME((mask_trailing_ones
<T
, BITS
>()), T::all_ones());
178 ASSERT_SAME((mask_leading_ones
<T
, 0>()), T::zero());
179 ASSERT_SAME((mask_leading_ones
<T
, 1>()), T::one() << (BITS
- 1));
180 ASSERT_SAME((mask_leading_ones
<T
, BITS
- 1>()), T::all_ones() - T::one());
181 ASSERT_SAME((mask_leading_ones
<T
, BITS
>()), T::all_ones());
182 // mask_trailing_zeros
183 ASSERT_SAME((mask_trailing_zeros
<T
, 0>()), T::all_ones());
184 ASSERT_SAME((mask_trailing_zeros
<T
, 1>()), T::all_ones() - T::one());
185 ASSERT_SAME((mask_trailing_zeros
<T
, BITS
- 1>()), T::one() << (BITS
- 1));
186 ASSERT_SAME((mask_trailing_zeros
<T
, BITS
>()), T::zero());
187 // mask_trailing_zeros
188 ASSERT_SAME((mask_leading_zeros
<T
, 0>()), T::all_ones());
189 ASSERT_SAME((mask_leading_zeros
<T
, 1>()), T::all_ones() >> 1);
190 ASSERT_SAME((mask_leading_zeros
<T
, BITS
- 1>()), T::one());
191 ASSERT_SAME((mask_leading_zeros
<T
, BITS
>()), T::zero());
195 TYPED_TEST(LlvmLibcUIntClassTest
, CountBits
, Types
) {
196 if constexpr (!T::SIGNED
) {
197 for (size_t i
= 0; i
< T::BITS
; ++i
) {
198 const auto l_one
= T::all_ones() << i
; // 0b111...000
199 const auto r_one
= T::all_ones() >> i
; // 0b000...111
201 const int ones
= T::BITS
- zeros
;
202 ASSERT_EQ(cpp::countr_one(r_one
), ones
);
203 ASSERT_EQ(cpp::countl_one(l_one
), ones
);
204 ASSERT_EQ(cpp::countr_zero(l_one
), zeros
);
205 ASSERT_EQ(cpp::countl_zero(r_one
), zeros
);
210 using LL_UInt16
= UInt
<16>;
211 using LL_UInt32
= UInt
<32>;
212 using LL_UInt64
= UInt
<64>;
213 // We want to test UInt<128> explicitly. So, for
214 // convenience, we use a sugar which does not conflict with the UInt128 type
215 // which can resolve to __uint128_t if the platform has it.
216 using LL_UInt128
= UInt
<128>;
217 using LL_UInt192
= UInt
<192>;
218 using LL_UInt256
= UInt
<256>;
219 using LL_UInt320
= UInt
<320>;
220 using LL_UInt512
= UInt
<512>;
221 using LL_UInt1024
= UInt
<1024>;
223 using LL_Int128
= Int
<128>;
224 using LL_Int192
= Int
<192>;
226 TEST(LlvmLibcUIntClassTest
, BitCastToFromDouble
) {
227 static_assert(cpp::is_trivially_copyable
<LL_UInt64
>::value
);
228 static_assert(sizeof(LL_UInt64
) == sizeof(double));
229 const double inf
= HUGE_VAL
;
230 const double max
= DBL_MAX
;
231 const double array
[] = {0.0, 0.1, 1.0, max
, inf
};
232 for (double value
: array
) {
233 LL_UInt64 back
= cpp::bit_cast
<LL_UInt64
>(value
);
234 double forth
= cpp::bit_cast
<double>(back
);
235 EXPECT_TRUE(value
== forth
);
239 #ifdef LIBC_TYPES_HAS_INT128
240 TEST(LlvmLibcUIntClassTest
, BitCastToFromNativeUint128
) {
241 static_assert(cpp::is_trivially_copyable
<LL_UInt128
>::value
);
242 static_assert(sizeof(LL_UInt128
) == sizeof(__uint128_t
));
243 const __uint128_t array
[] = {0, 1, ~__uint128_t(0)};
244 for (__uint128_t value
: array
) {
245 LL_UInt128 back
= cpp::bit_cast
<LL_UInt128
>(value
);
246 __uint128_t forth
= cpp::bit_cast
<__uint128_t
>(back
);
247 EXPECT_TRUE(value
== forth
);
250 #endif // LIBC_TYPES_HAS_INT128
252 #ifdef LIBC_TYPES_HAS_FLOAT128
253 TEST(LlvmLibcUIntClassTest
, BitCastToFromNativeFloat128
) {
254 static_assert(cpp::is_trivially_copyable
<LL_UInt128
>::value
);
255 static_assert(sizeof(LL_UInt128
) == sizeof(float128
));
256 const float128 array
[] = {0, 0.1, 1};
257 for (float128 value
: array
) {
258 LL_UInt128 back
= cpp::bit_cast
<LL_UInt128
>(value
);
259 float128 forth
= cpp::bit_cast
<float128
>(back
);
260 EXPECT_TRUE(value
== forth
);
263 #endif // LIBC_TYPES_HAS_FLOAT128
265 #ifdef LIBC_TYPES_HAS_FLOAT16
266 TEST(LlvmLibcUIntClassTest
, BitCastToFromNativeFloat16
) {
267 static_assert(cpp::is_trivially_copyable
<LL_UInt16
>::value
);
268 static_assert(sizeof(LL_UInt16
) == sizeof(float16
));
269 const float16 array
[] = {
270 static_cast<float16
>(0.0),
271 static_cast<float16
>(0.1),
272 static_cast<float16
>(1.0),
274 for (float16 value
: array
) {
275 LL_UInt16 back
= cpp::bit_cast
<LL_UInt16
>(value
);
276 float16 forth
= cpp::bit_cast
<float16
>(back
);
277 EXPECT_TRUE(value
== forth
);
280 #endif // LIBC_TYPES_HAS_FLOAT16
282 TEST(LlvmLibcUIntClassTest
, BasicInit
) {
283 LL_UInt128
half_val(12345);
284 LL_UInt128
full_val({12345, 67890});
285 ASSERT_TRUE(half_val
!= full_val
);
288 TEST(LlvmLibcUIntClassTest
, AdditionTests
) {
289 LL_UInt128
val1(12345);
290 LL_UInt128
val2(54321);
291 LL_UInt128
result1(66666);
292 EXPECT_EQ(val1
+ val2
, result1
);
293 EXPECT_EQ((val1
+ val2
), (val2
+ val1
)); // addition is commutative
296 LL_UInt128
val3({0xf000000000000001, 0});
297 LL_UInt128
val4({0x100000000000000f, 0});
298 LL_UInt128
result2({0x10, 0x1});
299 EXPECT_EQ(val3
+ val4
, result2
);
300 EXPECT_EQ(val3
+ val4
, val4
+ val3
);
303 LL_UInt128
val5({0x0123456789abcdef, 0xfedcba9876543210});
304 LL_UInt128
val6({0x1111222233334444, 0xaaaabbbbccccdddd});
305 LL_UInt128
result3({0x12346789bcdf1233, 0xa987765443210fed});
306 EXPECT_EQ(val5
+ val6
, result3
);
307 EXPECT_EQ(val5
+ val6
, val6
+ val5
);
309 // Test 192-bit addition
310 LL_UInt192
val7({0x0123456789abcdef, 0xfedcba9876543210, 0xfedcba9889abcdef});
311 LL_UInt192
val8({0x1111222233334444, 0xaaaabbbbccccdddd, 0xeeeeffffeeeeffff});
313 {0x12346789bcdf1233, 0xa987765443210fed, 0xedcbba98789acdef});
314 EXPECT_EQ(val7
+ val8
, result4
);
315 EXPECT_EQ(val7
+ val8
, val8
+ val7
);
317 // Test 256-bit addition
318 LL_UInt256
val9({0x1f1e1d1c1b1a1918, 0xf1f2f3f4f5f6f7f8, 0x0123456789abcdef,
319 0xfedcba9876543210});
320 LL_UInt256
val10({0x1111222233334444, 0xaaaabbbbccccdddd, 0x1111222233334444,
321 0xaaaabbbbccccdddd});
322 LL_UInt256
result5({0x302f3f3e4e4d5d5c, 0x9c9dafb0c2c3d5d5,
323 0x12346789bcdf1234, 0xa987765443210fed});
324 EXPECT_EQ(val9
+ val10
, result5
);
325 EXPECT_EQ(val9
+ val10
, val10
+ val9
);
328 TEST(LlvmLibcUIntClassTest
, SubtractionTests
) {
329 LL_UInt128
val1(12345);
330 LL_UInt128
val2(54321);
331 LL_UInt128
result1({0xffffffffffff5c08, 0xffffffffffffffff});
332 LL_UInt128
result2(0xa3f8);
333 EXPECT_EQ(val1
- val2
, result1
);
334 EXPECT_EQ(val1
, val2
+ result1
);
335 EXPECT_EQ(val2
- val1
, result2
);
336 EXPECT_EQ(val2
, val1
+ result2
);
338 LL_UInt128
val3({0xf000000000000001, 0});
339 LL_UInt128
val4({0x100000000000000f, 0});
340 LL_UInt128
result3(0xdffffffffffffff2);
341 LL_UInt128
result4({0x200000000000000e, 0xffffffffffffffff});
342 EXPECT_EQ(val3
- val4
, result3
);
343 EXPECT_EQ(val3
, val4
+ result3
);
344 EXPECT_EQ(val4
- val3
, result4
);
345 EXPECT_EQ(val4
, val3
+ result4
);
347 LL_UInt128
val5({0x0123456789abcdef, 0xfedcba9876543210});
348 LL_UInt128
val6({0x1111222233334444, 0xaaaabbbbccccdddd});
349 LL_UInt128
result5({0xf0122345567889ab, 0x5431fedca9875432});
350 LL_UInt128
result6({0x0feddcbaa9877655, 0xabce01235678abcd});
351 EXPECT_EQ(val5
- val6
, result5
);
352 EXPECT_EQ(val5
, val6
+ result5
);
353 EXPECT_EQ(val6
- val5
, result6
);
354 EXPECT_EQ(val6
, val5
+ result6
);
357 TEST(LlvmLibcUIntClassTest
, MultiplicationTests
) {
358 LL_UInt128
val1({5, 0});
359 LL_UInt128
val2({10, 0});
360 LL_UInt128
result1({50, 0});
361 EXPECT_EQ((val1
* val2
), result1
);
362 EXPECT_EQ((val1
* val2
), (val2
* val1
)); // multiplication is commutative
364 // Check that the multiplication works accross the whole number
365 LL_UInt128
val3({0xf, 0});
366 LL_UInt128
val4({0x1111111111111111, 0x1111111111111111});
367 LL_UInt128
result2({0xffffffffffffffff, 0xffffffffffffffff});
368 EXPECT_EQ((val3
* val4
), result2
);
369 EXPECT_EQ((val3
* val4
), (val4
* val3
));
371 // Check that multiplication doesn't reorder the bits.
372 LL_UInt128
val5({2, 0});
373 LL_UInt128
val6({0x1357024675316420, 0x0123456776543210});
374 LL_UInt128
result3({0x26ae048cea62c840, 0x02468aceeca86420});
376 EXPECT_EQ((val5
* val6
), result3
);
377 EXPECT_EQ((val5
* val6
), (val6
* val5
));
379 // Make sure that multiplication handles overflow correctly.
381 LL_UInt128
val8({0x8000800080008000, 0x8000800080008000});
382 LL_UInt128
result4({0x0001000100010000, 0x0001000100010001});
383 EXPECT_EQ((val7
* val8
), result4
);
384 EXPECT_EQ((val7
* val8
), (val8
* val7
));
386 // val9 is the 128 bit mantissa of 1e60 as a float, val10 is the mantissa for
387 // 1e-60. They almost cancel on the high bits, but the result we're looking
388 // for is just the low bits. The full result would be
389 // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50
390 LL_UInt128
val9({0x01D762422C946590, 0x9F4F2726179A2245});
391 LL_UInt128
val10({0x3792F412CB06794D, 0xCDB02555653131B6});
392 LL_UInt128
result5({0x917cf11d1e039c50, 0x3a4f32d17f40d08f});
393 EXPECT_EQ((val9
* val10
), result5
);
394 EXPECT_EQ((val9
* val10
), (val10
* val9
));
396 // Test 192-bit multiplication
398 {0xffffffffffffffff, 0x01D762422C946590, 0x9F4F2726179A2245});
400 {0xffffffffffffffff, 0x3792F412CB06794D, 0xCDB02555653131B6});
403 {0x0000000000000001, 0xc695a9ab08652121, 0x5de7faf698d32732});
404 EXPECT_EQ((val11
* val12
), result6
);
405 EXPECT_EQ((val11
* val12
), (val12
* val11
));
407 LL_UInt256
val13({0xffffffffffffffff, 0x01D762422C946590, 0x9F4F2726179A2245,
408 0xffffffffffffffff});
409 LL_UInt256
val14({0xffffffffffffffff, 0xffffffffffffffff, 0x3792F412CB06794D,
410 0xCDB02555653131B6});
411 LL_UInt256
result7({0x0000000000000001, 0xfe289dbdd36b9a6f,
412 0x291de4c71d5f646c, 0xfd37221cb06d4978});
413 EXPECT_EQ((val13
* val14
), result7
);
414 EXPECT_EQ((val13
* val14
), (val14
* val13
));
417 TEST(LlvmLibcUIntClassTest
, DivisionTests
) {
418 LL_UInt128
val1({10, 0});
419 LL_UInt128
val2({5, 0});
420 LL_UInt128
result1({2, 0});
421 EXPECT_EQ((val1
/ val2
), result1
);
422 EXPECT_EQ((val1
/ result1
), val2
);
424 // Check that the division works accross the whole number
425 LL_UInt128
val3({0xffffffffffffffff, 0xffffffffffffffff});
426 LL_UInt128
val4({0xf, 0});
427 LL_UInt128
result2({0x1111111111111111, 0x1111111111111111});
428 EXPECT_EQ((val3
/ val4
), result2
);
429 EXPECT_EQ((val3
/ result2
), val4
);
431 // Check that division doesn't reorder the bits.
432 LL_UInt128
val5({0x26ae048cea62c840, 0x02468aceeca86420});
433 LL_UInt128
val6({2, 0});
434 LL_UInt128
result3({0x1357024675316420, 0x0123456776543210});
435 EXPECT_EQ((val5
/ val6
), result3
);
436 EXPECT_EQ((val5
/ result3
), val6
);
438 // Make sure that division handles inexact results correctly.
439 LL_UInt128
val7({1001, 0});
440 LL_UInt128
val8({10, 0});
441 LL_UInt128
result4({100, 0});
442 EXPECT_EQ((val7
/ val8
), result4
);
443 EXPECT_EQ((val7
/ result4
), val8
);
445 // Make sure that division handles divisors of one correctly.
446 LL_UInt128
val9({0x1234567812345678, 0x9abcdef09abcdef0});
447 LL_UInt128
val10({1, 0});
448 LL_UInt128
result5({0x1234567812345678, 0x9abcdef09abcdef0});
449 EXPECT_EQ((val9
/ val10
), result5
);
450 EXPECT_EQ((val9
/ result5
), val10
);
452 // Make sure that division handles results of slightly more than 1 correctly.
453 LL_UInt128
val11({1050, 0});
454 LL_UInt128
val12({1030, 0});
455 LL_UInt128
result6({1, 0});
456 EXPECT_EQ((val11
/ val12
), result6
);
458 // Make sure that division handles dividing by zero correctly.
459 LL_UInt128
val13({1234, 0});
460 LL_UInt128
val14({0, 0});
461 EXPECT_FALSE(val13
.div(val14
).has_value());
464 TEST(LlvmLibcUIntClassTest
, ModuloTests
) {
465 LL_UInt128
val1({10, 0});
466 LL_UInt128
val2({5, 0});
467 LL_UInt128
result1({0, 0});
468 EXPECT_EQ((val1
% val2
), result1
);
470 LL_UInt128
val3({101, 0});
471 LL_UInt128
val4({10, 0});
472 LL_UInt128
result2({1, 0});
473 EXPECT_EQ((val3
% val4
), result2
);
475 LL_UInt128
val5({10000001, 0});
476 LL_UInt128
val6({10, 0});
477 LL_UInt128
result3({1, 0});
478 EXPECT_EQ((val5
% val6
), result3
);
480 LL_UInt128
val7({12345, 10});
481 LL_UInt128
val8({0, 1});
482 LL_UInt128
result4({12345, 0});
483 EXPECT_EQ((val7
% val8
), result4
);
485 LL_UInt128
val9({12345, 10});
486 LL_UInt128
val10({0, 11});
487 LL_UInt128
result5({12345, 10});
488 EXPECT_EQ((val9
% val10
), result5
);
490 LL_UInt128
val11({10, 10});
491 LL_UInt128
val12({10, 10});
492 LL_UInt128
result6({0, 0});
493 EXPECT_EQ((val11
% val12
), result6
);
495 LL_UInt128
val13({12345, 0});
496 LL_UInt128
val14({1, 0});
497 LL_UInt128
result7({0, 0});
498 EXPECT_EQ((val13
% val14
), result7
);
500 LL_UInt128
val15({0xffffffffffffffff, 0xffffffffffffffff});
501 LL_UInt128
val16({0x1111111111111111, 0x111111111111111});
502 LL_UInt128
result8({0xf, 0});
503 EXPECT_EQ((val15
% val16
), result8
);
505 LL_UInt128
val17({5076944270305263619, 54210108624}); // (10 ^ 30) + 3
506 LL_UInt128
val18({10, 0});
507 LL_UInt128
result9({3, 0});
508 EXPECT_EQ((val17
% val18
), result9
);
511 TEST(LlvmLibcUIntClassTest
, PowerTests
) {
512 LL_UInt128
val1({10, 0});
514 LL_UInt128
result1({5076944270305263616, 54210108624}); // (10 ^ 30)
515 EXPECT_EQ(val1
, result1
);
517 LL_UInt128
val2({1, 0});
519 LL_UInt128
result2({1, 0});
520 EXPECT_EQ(val2
, result2
);
522 LL_UInt128
val3({0, 0});
524 LL_UInt128
result3({0, 0});
525 EXPECT_EQ(val3
, result3
);
527 LL_UInt128
val4({10, 0});
529 LL_UInt128
result4({1, 0});
530 EXPECT_EQ(val4
, result4
);
532 // Test zero to the zero. Currently it returns 1, since that's the easiest
534 LL_UInt128
val5({0, 0});
536 LL_UInt128
result5({1, 0});
537 EXPECT_EQ(val5
, result5
);
539 // Test a number that overflows. 100 ^ 20 is larger than 2 ^ 128.
540 LL_UInt128
val6({100, 0});
542 LL_UInt128
result6({0xb9f5610000000000, 0x6329f1c35ca4bfab});
543 EXPECT_EQ(val6
, result6
);
545 // Test that both halves of the number are being used.
546 LL_UInt128
val7({1, 1});
548 LL_UInt128
result7({1, 2});
549 EXPECT_EQ(val7
, result7
);
551 LL_UInt128 val_pow_two
;
552 LL_UInt128 result_pow_two
;
553 for (size_t i
= 0; i
< 128; ++i
) {
555 val_pow_two
.pow_n(i
);
557 result_pow_two
= result_pow_two
<< i
;
558 EXPECT_EQ(val_pow_two
, result_pow_two
);
562 TEST(LlvmLibcUIntClassTest
, ShiftLeftTests
) {
563 LL_UInt128
val1(0x0123456789abcdef);
564 LL_UInt128
result1(0x123456789abcdef0);
565 EXPECT_EQ((val1
<< 4), result1
);
567 LL_UInt128
val2({0x13579bdf02468ace, 0x123456789abcdef0});
568 LL_UInt128
result2({0x02468ace00000000, 0x9abcdef013579bdf});
569 EXPECT_EQ((val2
<< 32), result2
);
570 LL_UInt128 val22
= val2
;
572 EXPECT_EQ(val22
, result2
);
574 LL_UInt128
result3({0, 0x13579bdf02468ace});
575 EXPECT_EQ((val2
<< 64), result3
);
577 LL_UInt128
result4({0, 0x02468ace00000000});
578 EXPECT_EQ((val2
<< 96), result4
);
580 LL_UInt128
result5({0, 0x2468ace000000000});
581 EXPECT_EQ((val2
<< 100), result5
);
583 LL_UInt192
val3({1, 0, 0});
584 LL_UInt192
result7({0, 1, 0});
585 EXPECT_EQ((val3
<< 64), result7
);
588 TEST(LlvmLibcUIntClassTest
, ShiftRightTests
) {
589 LL_UInt128
val1(0x0123456789abcdef);
590 LL_UInt128
result1(0x00123456789abcde);
591 EXPECT_EQ((val1
>> 4), result1
);
593 LL_UInt128
val2({0x13579bdf02468ace, 0x123456789abcdef0});
594 LL_UInt128
result2({0x9abcdef013579bdf, 0x0000000012345678});
595 EXPECT_EQ((val2
>> 32), result2
);
596 LL_UInt128 val22
= val2
;
598 EXPECT_EQ(val22
, result2
);
600 LL_UInt128
result3({0x123456789abcdef0, 0});
601 EXPECT_EQ((val2
>> 64), result3
);
603 LL_UInt128
result4({0x0000000012345678, 0});
604 EXPECT_EQ((val2
>> 96), result4
);
606 LL_UInt128
result5({0x0000000001234567, 0});
607 EXPECT_EQ((val2
>> 100), result5
);
609 LL_UInt128
v1({0x1111222233334444, 0xaaaabbbbccccdddd});
610 LL_UInt128
r1({0xaaaabbbbccccdddd, 0});
611 EXPECT_EQ((v1
>> 64), r1
);
613 LL_UInt192
v2({0x1111222233334444, 0x5555666677778888, 0xaaaabbbbccccdddd});
614 LL_UInt192
r2({0x5555666677778888, 0xaaaabbbbccccdddd, 0});
615 LL_UInt192
r3({0xaaaabbbbccccdddd, 0, 0});
616 EXPECT_EQ((v2
>> 64), r2
);
617 EXPECT_EQ((v2
>> 128), r3
);
618 EXPECT_EQ((r2
>> 64), r3
);
620 LL_UInt192
val3({0, 0, 1});
621 LL_UInt192
result7({0, 1, 0});
622 EXPECT_EQ((val3
>> 64), result7
);
625 TEST(LlvmLibcUIntClassTest
, AndTests
) {
626 LL_UInt128
base({0xffff00000000ffff, 0xffffffff00000000});
627 LL_UInt128
val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
628 uint64_t val64
= 0xf0f0f0f00f0f0f0f;
629 int val32
= 0x0f0f0f0f;
630 LL_UInt128
result128({0xf0f0000000000f0f, 0xff00ff0000000000});
631 LL_UInt128
result64(0xf0f0000000000f0f);
632 LL_UInt128
result32(0x00000f0f);
633 EXPECT_EQ((base
& val128
), result128
);
634 EXPECT_EQ((base
& val64
), result64
);
635 EXPECT_EQ((base
& val32
), result32
);
638 TEST(LlvmLibcUIntClassTest
, OrTests
) {
639 LL_UInt128
base({0xffff00000000ffff, 0xffffffff00000000});
640 LL_UInt128
val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
641 uint64_t val64
= 0xf0f0f0f00f0f0f0f;
642 int val32
= 0x0f0f0f0f;
643 LL_UInt128
result128({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
644 LL_UInt128
result64({0xfffff0f00f0fffff, 0xffffffff00000000});
645 LL_UInt128
result32({0xffff00000f0fffff, 0xffffffff00000000});
646 EXPECT_EQ((base
| val128
), result128
);
647 EXPECT_EQ((base
| val64
), result64
);
648 EXPECT_EQ((base
| val32
), result32
);
651 TEST(LlvmLibcUIntClassTest
, CompoundAssignments
) {
652 LL_UInt128
x({0xffff00000000ffff, 0xffffffff00000000});
653 LL_UInt128
b({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
657 LL_UInt128
or_result({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
658 EXPECT_EQ(a
, or_result
);
662 LL_UInt128
and_result({0xf0f0000000000f0f, 0xff00ff0000000000});
663 EXPECT_EQ(a
, and_result
);
667 LL_UInt128
xor_result({0x0f0ff0f00f0ff0f0, 0x00ff00ff00ff00ff});
668 EXPECT_EQ(a
, xor_result
);
670 a
= LL_UInt128(uint64_t(0x0123456789abcdef));
671 LL_UInt128
shift_left_result(uint64_t(0x123456789abcdef0));
673 EXPECT_EQ(a
, shift_left_result
);
675 a
= LL_UInt128(uint64_t(0x123456789abcdef1));
676 LL_UInt128
shift_right_result(uint64_t(0x0123456789abcdef));
678 EXPECT_EQ(a
, shift_right_result
);
680 a
= LL_UInt128({0xf000000000000001, 0});
681 b
= LL_UInt128({0x100000000000000f, 0});
682 LL_UInt128
add_result({0x10, 0x1});
684 EXPECT_EQ(a
, add_result
);
686 a
= LL_UInt128({0xf, 0});
687 b
= LL_UInt128({0x1111111111111111, 0x1111111111111111});
688 LL_UInt128
mul_result({0xffffffffffffffff, 0xffffffffffffffff});
690 EXPECT_EQ(a
, mul_result
);
693 TEST(LlvmLibcUIntClassTest
, UnaryPredecrement
) {
694 LL_UInt128 a
= LL_UInt128({0x1111111111111111, 0x1111111111111111});
696 EXPECT_EQ(a
, LL_UInt128({0x1111111111111112, 0x1111111111111111}));
698 a
= LL_UInt128({0xffffffffffffffff, 0x0});
700 EXPECT_EQ(a
, LL_UInt128({0x0, 0x1}));
702 a
= LL_UInt128({0xffffffffffffffff, 0xffffffffffffffff});
704 EXPECT_EQ(a
, LL_UInt128({0x0, 0x0}));
707 TEST(LlvmLibcUIntClassTest
, EqualsTests
) {
708 LL_UInt128
a1({0xffffffff00000000, 0xffff00000000ffff});
709 LL_UInt128
a2({0xffffffff00000000, 0xffff00000000ffff});
710 LL_UInt128
b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
711 LL_UInt128
a_reversed({0xffff00000000ffff, 0xffffffff00000000});
712 LL_UInt128
a_upper(0xffff00000000ffff);
713 LL_UInt128
a_lower(0xffffffff00000000);
714 ASSERT_TRUE(a1
== a1
);
715 ASSERT_TRUE(a1
== a2
);
716 ASSERT_FALSE(a1
== b
);
717 ASSERT_FALSE(a1
== a_reversed
);
718 ASSERT_FALSE(a1
== a_lower
);
719 ASSERT_FALSE(a1
== a_upper
);
720 ASSERT_TRUE(a_lower
!= a_upper
);
723 TEST(LlvmLibcUIntClassTest
, ComparisonTests
) {
724 LL_UInt128
a({0xffffffff00000000, 0xffff00000000ffff});
725 LL_UInt128
b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
731 LL_UInt128
x(0xffffffff00000000);
732 LL_UInt128
y(0x00000000ffffffff);
742 TEST(LlvmLibcUIntClassTest
, FullMulTests
) {
743 LL_UInt128
a({0xffffffffffffffffULL
, 0xffffffffffffffffULL
});
744 LL_UInt128
b({0xfedcba9876543210ULL
, 0xfefdfcfbfaf9f8f7ULL
});
745 LL_UInt256
r({0x0123456789abcdf0ULL
, 0x0102030405060708ULL
,
746 0xfedcba987654320fULL
, 0xfefdfcfbfaf9f8f7ULL
});
747 LL_UInt128
r_hi({0xfedcba987654320eULL
, 0xfefdfcfbfaf9f8f7ULL
});
749 EXPECT_EQ(a
.ful_mul(b
), r
);
750 EXPECT_EQ(a
.quick_mul_hi(b
), r_hi
);
753 {0x7766554433221101ULL
, 0xffeeddccbbaa9988ULL
, 0x1f2f3f4f5f6f7f8fULL
});
754 LL_UInt320
rr({0x8899aabbccddeeffULL
, 0x0011223344556677ULL
,
755 0x583715f4d3b29171ULL
, 0xffeeddccbbaa9988ULL
,
756 0x1f2f3f4f5f6f7f8fULL
});
758 EXPECT_EQ(a
.ful_mul(c
), rr
);
759 EXPECT_EQ(a
.ful_mul(c
), c
.ful_mul(a
));
762 #define TEST_QUICK_MUL_HI(Bits, Error) \
764 LL_UInt##Bits a = ~LL_UInt##Bits(0); \
765 LL_UInt##Bits hi = a.quick_mul_hi(a); \
766 LL_UInt##Bits trunc = static_cast<LL_UInt##Bits>(a.ful_mul(a) >> Bits); \
767 uint64_t overflow = trunc.sub_overflow(hi); \
768 EXPECT_EQ(overflow, uint64_t(0)); \
769 EXPECT_LE(uint64_t(trunc), uint64_t(Error)); \
772 TEST(LlvmLibcUIntClassTest
, QuickMulHiTests
) {
773 TEST_QUICK_MUL_HI(128, 1);
774 TEST_QUICK_MUL_HI(192, 2);
775 TEST_QUICK_MUL_HI(256, 3);
776 TEST_QUICK_MUL_HI(512, 7);
779 TEST(LlvmLibcUIntClassTest
, ConstexprInitTests
) {
780 constexpr LL_UInt128 add
= LL_UInt128(1) + LL_UInt128(2);
781 ASSERT_EQ(add
, LL_UInt128(3));
782 constexpr LL_UInt128 sub
= LL_UInt128(5) - LL_UInt128(4);
783 ASSERT_EQ(sub
, LL_UInt128(1));
786 #define TEST_QUICK_DIV_UINT32_POW2(x, e) \
788 LL_UInt320 y({0x8899aabbccddeeffULL, 0x0011223344556677ULL, \
789 0x583715f4d3b29171ULL, 0xffeeddccbbaa9988ULL, \
790 0x1f2f3f4f5f6f7f8fULL}); \
791 LL_UInt320 d = LL_UInt320(x); \
793 LL_UInt320 q1 = y / d; \
794 LL_UInt320 r1 = y % d; \
795 LL_UInt320 r2 = *y.div_uint_half_times_pow_2(x, e); \
800 TEST(LlvmLibcUIntClassTest
, DivUInt32TimesPow2Tests
) {
801 for (size_t i
= 0; i
< 320; i
+= 32) {
802 TEST_QUICK_DIV_UINT32_POW2(1, i
);
803 TEST_QUICK_DIV_UINT32_POW2(13151719, i
);
806 TEST_QUICK_DIV_UINT32_POW2(1, 75);
807 TEST_QUICK_DIV_UINT32_POW2(1, 101);
809 TEST_QUICK_DIV_UINT32_POW2(1000000000, 75);
810 TEST_QUICK_DIV_UINT32_POW2(1000000000, 101);
813 TEST(LlvmLibcUIntClassTest
, ComparisonInt128Tests
) {
844 TEST(LlvmLibcUIntClassTest
, BasicArithmeticInt128Tests
) {
849 ASSERT_EQ(a
* a
, LL_Int128(123 * 123));
850 ASSERT_EQ(a
* c
, LL_Int128(-369));
851 ASSERT_EQ(c
* a
, LL_Int128(-369));
852 ASSERT_EQ(c
* c
, LL_Int128(9));
859 #ifdef LIBC_TYPES_HAS_INT128
861 TEST(LlvmLibcUIntClassTest
, ConstructorFromUInt128Tests
) {
862 __uint128_t a
= (__uint128_t(123) << 64) + 1;
863 __int128_t b
= -static_cast<__int128_t
>(a
);
870 ASSERT_EQ(static_cast<int>(c
), 1);
871 ASSERT_EQ(static_cast<int>(c
>> 64), 123);
872 ASSERT_EQ(static_cast<uint64_t>(d
), static_cast<uint64_t>(b
));
873 ASSERT_EQ(static_cast<uint64_t>(d
>> 64), static_cast<uint64_t>(b
>> 64));
874 ASSERT_EQ(c
+ d
, LL_Int128(a
+ b
));
876 ASSERT_EQ(static_cast<int>(e
), 1);
877 ASSERT_EQ(static_cast<int>(e
>> 64), 123);
878 ASSERT_EQ(static_cast<uint64_t>(f
), static_cast<uint64_t>(b
));
879 ASSERT_EQ(static_cast<uint64_t>(f
>> 64), static_cast<uint64_t>(b
>> 64));
880 ASSERT_EQ(LL_UInt192(e
+ f
), LL_UInt192(a
+ b
));
883 TEST(LlvmLibcUIntClassTest
, WordTypeUInt128Tests
) {
884 using LL_UInt256_128
= BigInt
<256, false, __uint128_t
>;
885 using LL_UInt128_128
= BigInt
<128, false, __uint128_t
>;
889 ASSERT_EQ(static_cast<int>(a
), 1);
891 ASSERT_EQ(static_cast<int>(a
), 2);
892 ASSERT_EQ(static_cast<uint64_t>(a
), uint64_t(2));
894 ASSERT_EQ(static_cast<int>(a
), 3);
895 ASSERT_EQ(static_cast<uint64_t>(a
), uint64_t(0x2'0000'0003));
896 ASSERT_EQ(static_cast<int>(a
>> 32), 2);
897 ASSERT_EQ(static_cast<int>(a
>> (128 + 32)), 1);
899 LL_UInt128_128
b(__uint128_t(1) << 127);
903 ASSERT_EQ(static_cast<int>(a
>> 254), 1);
905 LL_UInt256_128 d
= LL_UInt256_128(123) << 4;
906 ASSERT_EQ(static_cast<int>(d
), 123 << 4);
907 LL_UInt256_128 e
= a
/ d
;
908 LL_UInt256_128 f
= a
% d
;
909 LL_UInt256_128 r
= *a
.div_uint_half_times_pow_2(123, 4);
914 #endif // LIBC_TYPES_HAS_INT128
916 TEST(LlvmLibcUIntClassTest
, OtherWordTypeTests
) {
917 using LL_UInt96
= BigInt
<96, false, uint32_t>;
921 ASSERT_EQ(static_cast<int>(a
), 1);
923 ASSERT_EQ(static_cast<int>(a
), 2);
924 ASSERT_EQ(static_cast<uint64_t>(a
), uint64_t(0x1'0000'0002));
926 ASSERT_EQ(static_cast<int>(a
), 3);
927 ASSERT_EQ(static_cast<int>(a
>> 32), 2);
928 ASSERT_EQ(static_cast<int>(a
>> 64), 1);
931 TEST(LlvmLibcUIntClassTest
, OtherWordTypeCastTests
) {
932 using LL_UInt96
= BigInt
<96, false, uint32_t>;
934 LL_UInt96
a({123, 456, 789});
936 ASSERT_EQ(static_cast<int>(a
), 123);
937 ASSERT_EQ(static_cast<int>(a
>> 32), 456);
938 ASSERT_EQ(static_cast<int>(a
>> 64), 789);
940 // Bigger word with more bits to smaller word with less bits.
943 ASSERT_EQ(static_cast<int>(b
), 123);
944 ASSERT_EQ(static_cast<int>(b
>> 32), 456);
945 ASSERT_EQ(static_cast<int>(b
>> 64), 789);
946 ASSERT_EQ(static_cast<int>(b
>> 96), 0);
950 ASSERT_EQ(static_cast<int>(b
), 987);
951 ASSERT_EQ(static_cast<int>(b
>> 32), 123);
952 ASSERT_EQ(static_cast<int>(b
>> 64), 456);
953 ASSERT_EQ(static_cast<int>(b
>> 96), 789);
955 // Smaller word with less bits to bigger word with more bits.
958 ASSERT_EQ(static_cast<int>(c
), 987);
959 ASSERT_EQ(static_cast<int>(c
>> 32), 123);
960 ASSERT_EQ(static_cast<int>(c
>> 64), 456);
962 // Smaller word with more bits to bigger word with less bits
965 ASSERT_EQ(static_cast<int>(d
), 987);
966 ASSERT_EQ(static_cast<int>(d
>> 32), 123);
968 // Bigger word with less bits to smaller word with more bits
972 ASSERT_EQ(static_cast<int>(e
), 987);
973 ASSERT_EQ(static_cast<int>(e
>> 32), 123);
977 ASSERT_EQ(static_cast<int>(e
), 654);
978 ASSERT_EQ(static_cast<int>(e
>> 32), 987);
979 ASSERT_EQ(static_cast<int>(e
>> 64), 123);
982 TEST(LlvmLibcUIntClassTest
, SignedOtherWordTypeCastTests
) {
983 using LL_Int64
= BigInt
<64, true, uint64_t>;
984 using LL_Int96
= BigInt
<96, true, uint32_t>;
988 LL_Int192
zero_192(0);
990 LL_Int96
plus_a({0x1234, 0x5678, 0x9ABC});
992 ASSERT_EQ(static_cast<int>(plus_a
), 0x1234);
993 ASSERT_EQ(static_cast<int>(plus_a
>> 32), 0x5678);
994 ASSERT_EQ(static_cast<int>(plus_a
>> 64), 0x9ABC);
996 LL_Int96
minus_a(-plus_a
);
998 // The reason that the numbers are inverted and not negated is that we're
999 // using two's complement. To negate a two's complement number you flip the
1000 // bits and add 1, so minus_a is {~0x1234, ~0x5678, ~0x9ABC} + {1,0,0}.
1001 ASSERT_EQ(static_cast<int>(minus_a
), (~0x1234) + 1);
1002 ASSERT_EQ(static_cast<int>(minus_a
>> 32), ~0x5678);
1003 ASSERT_EQ(static_cast<int>(minus_a
>> 64), ~0x9ABC);
1005 ASSERT_TRUE(plus_a
+ minus_a
== zero_96
);
1007 // 192 so there's an extra block to get sign extended to
1008 LL_Int192
bigger_plus_a(plus_a
);
1010 ASSERT_EQ(static_cast<int>(bigger_plus_a
), 0x1234);
1011 ASSERT_EQ(static_cast<int>(bigger_plus_a
>> 32), 0x5678);
1012 ASSERT_EQ(static_cast<int>(bigger_plus_a
>> 64), 0x9ABC);
1013 ASSERT_EQ(static_cast<int>(bigger_plus_a
>> 96), 0);
1014 ASSERT_EQ(static_cast<int>(bigger_plus_a
>> 128), 0);
1015 ASSERT_EQ(static_cast<int>(bigger_plus_a
>> 160), 0);
1017 LL_Int192
bigger_minus_a(minus_a
);
1019 ASSERT_EQ(static_cast<int>(bigger_minus_a
), (~0x1234) + 1);
1020 ASSERT_EQ(static_cast<int>(bigger_minus_a
>> 32), ~0x5678);
1021 ASSERT_EQ(static_cast<int>(bigger_minus_a
>> 64), ~0x9ABC);
1022 ASSERT_EQ(static_cast<int>(bigger_minus_a
>> 96), ~0);
1023 ASSERT_EQ(static_cast<int>(bigger_minus_a
>> 128), ~0);
1024 ASSERT_EQ(static_cast<int>(bigger_minus_a
>> 160), ~0);
1026 ASSERT_TRUE(bigger_plus_a
+ bigger_minus_a
== zero_192
);
1028 LL_Int64
smaller_plus_a(plus_a
);
1030 ASSERT_EQ(static_cast<int>(smaller_plus_a
), 0x1234);
1031 ASSERT_EQ(static_cast<int>(smaller_plus_a
>> 32), 0x5678);
1033 LL_Int64
smaller_minus_a(minus_a
);
1035 ASSERT_EQ(static_cast<int>(smaller_minus_a
), (~0x1234) + 1);
1036 ASSERT_EQ(static_cast<int>(smaller_minus_a
>> 32), ~0x5678);
1038 ASSERT_TRUE(smaller_plus_a
+ smaller_minus_a
== zero_64
);
1040 // Also try going from bigger word size to smaller word size
1041 LL_Int96
smaller_back_plus_a(smaller_plus_a
);
1043 ASSERT_EQ(static_cast<int>(smaller_back_plus_a
), 0x1234);
1044 ASSERT_EQ(static_cast<int>(smaller_back_plus_a
>> 32), 0x5678);
1045 ASSERT_EQ(static_cast<int>(smaller_back_plus_a
>> 64), 0);
1047 LL_Int96
smaller_back_minus_a(smaller_minus_a
);
1049 ASSERT_EQ(static_cast<int>(smaller_back_minus_a
), (~0x1234) + 1);
1050 ASSERT_EQ(static_cast<int>(smaller_back_minus_a
>> 32), ~0x5678);
1051 ASSERT_EQ(static_cast<int>(smaller_back_minus_a
>> 64), ~0);
1053 ASSERT_TRUE(smaller_back_plus_a
+ smaller_back_minus_a
== zero_96
);
1055 LL_Int96
bigger_back_plus_a(bigger_plus_a
);
1057 ASSERT_EQ(static_cast<int>(bigger_back_plus_a
), 0x1234);
1058 ASSERT_EQ(static_cast<int>(bigger_back_plus_a
>> 32), 0x5678);
1059 ASSERT_EQ(static_cast<int>(bigger_back_plus_a
>> 64), 0x9ABC);
1061 LL_Int96
bigger_back_minus_a(bigger_minus_a
);
1063 ASSERT_EQ(static_cast<int>(bigger_back_minus_a
), (~0x1234) + 1);
1064 ASSERT_EQ(static_cast<int>(bigger_back_minus_a
>> 32), ~0x5678);
1065 ASSERT_EQ(static_cast<int>(bigger_back_minus_a
>> 64), ~0x9ABC);
1067 ASSERT_TRUE(bigger_back_plus_a
+ bigger_back_minus_a
== zero_96
);
1070 TEST(LlvmLibcUIntClassTest
, MixedSignednessOtherWordTypeCastTests
) {
1071 using LL_UInt96
= BigInt
<96, false, uint32_t>;
1073 // ensure that -123 gets extended, even though the input type is signed while
1074 // the BigInt is unsigned.
1075 ASSERT_EQ(int64_t(x
), int64_t(-123));
1078 } // namespace LIBC_NAMESPACE_DECL