Mixed Type Operations

Conversions

The ability to convert between the two types via static_cast is available as documented in the above class descriptions.

Operator Overloads Across Types

All comparison, arithmetic, bitwise, and shift operators are provided across:

  • int128_t and uint128_t (cross-type),

  • int128_t / uint128_t and any built-in integer type (signed or unsigned, including the compiler’s 128-bit __int128 / unsigned __int128 where supported).

The behavior and return type of every mixed-sign overload follow the C++ usual arithmetic conversions, identical to what the equivalent built-in __int128 / unsigned __int128 operation would produce, including two’s-complement wrap-around semantics.

Result Type Rules

Operands Common type Result of arithmetic / bitwise

int128_t and uint128_t (same rank, mixed sign)

uint128_t

uint128_t

int128_t and unsigned __int128 (same rank, mixed sign)

uint128_t

uint128_t

uint128_t and __int128 (same rank, mixed sign)

uint128_t

uint128_t

int128_t and a small unsigned built-in (uint8_t to uint64_t)

int128_t

int128_t

uint128_t and a small signed built-in (int8_t to int64_t)

uint128_t

uint128_t

For shift operators (<<, >>), the result type follows the LHS type regardless of the RHS, matching the built-in shift rules.

For comparison operators (==, !=, <, <=, >, >=), the return type is always bool and the comparison is performed on the operands after they have been converted to the common type above.

Cross-type Operator Signatures

namespace boost {
namespace int128 {

//=====================================
// Comparison Operators
//=====================================

BOOST_INT128_HOST_DEVICE constexpr bool operator==(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator==(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator!=(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator!=(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator<(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator<(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator<=(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator<=(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator>(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator>(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator>=(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr bool operator>=(int128_t lhs, uint128_t rhs);

//=====================================
// Arithmetic Operators
//=====================================

BOOST_INT128_HOST_DEVICE constexpr uint128_t operator+(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator+(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator-(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator-(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator*(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator*(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator/(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator/(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator%(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator%(int128_t lhs, uint128_t rhs);

//=====================================
// Bitwise Operators
//=====================================

BOOST_INT128_HOST_DEVICE constexpr uint128_t operator|(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator|(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator&(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator&(int128_t lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator^(uint128_t lhs, int128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator^(int128_t lhs, uint128_t rhs);

//=====================================
// Shift Operators
//=====================================
// Result type follows the LHS.

BOOST_INT128_HOST_DEVICE constexpr int128_t  operator<<(int128_t  lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator<<(uint128_t lhs, int128_t  rhs);
BOOST_INT128_HOST_DEVICE constexpr int128_t  operator>>(int128_t  lhs, uint128_t rhs);
BOOST_INT128_HOST_DEVICE constexpr uint128_t operator>>(uint128_t lhs, int128_t  rhs);

} // namespace int128
} // namespace boost

The cross-type arithmetic and bitwise operators return the same value as static_cast<uint128_t>(lhs) op static_cast<uint128_t>(rhs). The comparison operators return the same value as that expression compared with the matching unsigned operator.

Operations with built-in __int128 / unsigned __int128

When the compiler provides 128-bit built-in integer types, all of the operators above are also available between a library type and the built-in type of opposite signedness (e.g. uint128_t op __int128, unsigned __int128 op int128_t). The result type follows the same rules as the table above (uint128_t for arithmetic and bitwise; the LHS type for shifts; bool for comparisons), and the produced value is identical to what an all-built-in computation would yield.