# How to Use absl::int128 and absl::uint128 in Abseil-C++

> Learn to use absl::int128 and absl::uint128 for portable 128-bit integer arithmetic in Abseil-C++. Maximize performance with compiler intrinsics.

- Repository: [Abseil/abseil-cpp](https://github.com/abseil/abseil-cpp)
- Tags: how-to-guide
- Published: 2026-07-17

---

**`absl::int128` and `absl::uint128` are portable 128-bit integer types that provide full arithmetic support, implicit construction from integrals, and utility functions for splitting values into 64-bit halves, backed by native compiler intrinsics when available.**

The Abseil-C++ library delivers robust 128-bit integer arithmetic through `absl::int128` and `absl::uint128`, defined in [`absl/numeric/int128.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/numeric/int128.h). These types ensure consistent behavior across compilers, automatically utilizing native `__int128` support when present or falling back to a software implementation using dual 64-bit halves.

## What Are absl::int128 and absl::uint128?

### Design Overview and Portability

Both types are declared in **[[`absl/numeric/int128.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/numeric/int128.h)](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h)**. `absl::uint128` provides a full-featured unsigned 128-bit integer interface, while `absl::int128` serves as its signed counterpart. The forward declaration for the signed variant appears at line [60](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L60).

When the compiler defines `ABSL_HAVE_INTRINSIC_INT128`—indicating native `__int128` support—Abseil implements these types as `alignas` wrappers around the built-in compiler type. This guarantees binary-compatible layout with zero abstraction overhead. On platforms without native support, the implementation uses a composite structure storing separate `high` and `low` 64-bit values.

## Core API and Usage Patterns

### Construction and Initialization

The types support **implicit construction** from any integral type. As implemented at lines [15-21](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L15-L21), you can initialize values directly:

```cpp
absl::uint128 u = 42;                    // implicit from int
absl::int128 i = -42;                    // signed construction
absl::uint128 v = absl::MakeUint128(1, 0); // high=1, low=0

```

The `absl::MakeUint128(high, low)` function constructs a `uint128` from two 64-bit parts, declared just after line [100](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L100).

### Explicit Conversion Operators

When narrowing to smaller types, use `static_cast` or the explicit conversion operators defined at lines [44-66](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L44-L66):

```cpp
uint64_t lower = static_cast<uint64_t>(u);  // truncates to low 64 bits
int64_t  signed_part = static_cast<int64_t>(i);

```

### Arithmetic and Bitwise Operations

All standard operators are provided starting around line [74](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L74). This includes assignment operators (`+=`, `-=`, `*=`, etc.) and their non-assignment forms (`+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `&`, `|`, `^`).

```cpp
absl::uint128 sum = u + v;
absl::uint128 prod = u * 2;
absl::int128 diff = i - absl::int128(u);
absl::uint128 shifted = u << 64;

```

### Accessing 64-bit Halves

Extract the high and low 64-bit components using the friend functions declared at lines [92-99](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L92-L99):

```cpp
uint64_t low = absl::Uint128Low64(u);    // extracts bits 0-63
uint64_t high = absl::Uint128High64(u);  // extracts bits 64-127

```

## Integration with Abseil Components

The 128-bit types integrate throughout the Abseil codebase:

- **String parsing**: Used in **[[`absl/strings/numbers.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/strings/numbers.h)](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/numbers.h)** for high-precision integer conversion (see `FastIntToBuffer` at line [206](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/numbers.h#L206)).
- **Random number generation**: Wide multiplication in **[[`absl/random/internal/wide_multiply.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/random/internal/wide_multiply.h)](https://github.com/abseil/abseil-cpp/blob/master/absl/random/internal/wide_multiply.h)** utilizes `MultiplyU128ToU256` at line [58](https://github.com/abseil/abseil-cpp/blob/master/absl/random/internal/wide_multiply.h#L58) to produce 256-bit results from 128-bit inputs.
- **String formatting**: Formatting support resides in **[[`absl/strings/internal/str_format/arg.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/strings/internal/str_format/arg.h)](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/internal/str_format/arg.h)** via `FormatConvertImpl` overloads at lines [334-336](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/internal/str_format/arg.h#L334-L336).

## Complete Working Example

The following example demonstrates construction, arithmetic, component extraction, and basic output:

```cpp
#include "absl/numeric/int128.h"
#include <iostream>

int main() {
  // Construction
  absl::uint128 u1 = 1;                         // implicit from int
  absl::uint128 u2 = absl::MakeUint128(0, 5);   // high=0, low=5
  absl::int128 i1 = -42;                        // signed construction

  // Arithmetic
  absl::uint128 sum = u1 + u2;                  // 6
  absl::uint128 prod = u1 * u2;                 // 5
  absl::int128 diff = i1 - absl::int128(u1);    // -43

  // Access halves
  uint64_t low = absl::Uint128Low64(u2);        // 5
  uint64_t high = absl::Uint128High64(u2);      // 0

  // Output (cast to 64-bit for demonstration; use absl::StrCat for full precision)
  std::cout << "sum = " << static_cast<unsigned long long>(sum) << '\n';
  std::cout << "high=" << high << " low=" << low << '\n';
}

```

## Summary

- **`absl::int128` and `absl::uint128`** provide portable 128-bit arithmetic in [`absl/numeric/int128.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/numeric/int128.h), wrapping native `__int128` when available via `ABSL_HAVE_INTRINSIC_INT128`.
- **Construction** supports implicit integral conversion and explicit 64-bit pair assembly via `absl::MakeUint128()`.
- **Operations** include all standard arithmetic, bitwise, and shift operators with full assignment support.
- **Component access** uses `absl::Uint128Low64()` and `absl::Uint128High64()` to extract 64-bit halves.
- **Integration** extends to string parsing, random number generation, and formatting throughout the Abseil library.

## Frequently Asked Questions

### How do I convert absl::int128 to a string?

While direct `std::cout` support requires casting to a smaller type, the recommended approach uses Abseil's string formatting utilities. According to the implementation in [`absl/strings/internal/str_format/arg.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/strings/internal/str_format/arg.h), you can use `absl::StrCat()` or `absl::Format()` which provide overloads for `int128` and `uint128` types at lines [334-336](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/internal/str_format/arg.h#L334-L336).

### What is the difference between absl::int128 and compiler-native __int128?

When `ABSL_HAVE_INTRINSIC_INT128` is defined, `absl::int128` is merely an `alignas` wrapper around the compiler's native `__int128`, ensuring zero overhead and binary compatibility. On compilers without native support, Abseil provides a complete software implementation using two 64-bit integers, ensuring portability at the cost of software emulation.

### How do I construct an absl::uint128 from two 64-bit values?

Use the `absl::MakeUint128(high, low)` function declared in [`absl/numeric/int128.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/numeric/int128.h) just after line [100](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L100). The first parameter becomes the high 64 bits, and the second becomes the low 64 bits: `auto val = absl::MakeUint128(0x1234, 0x5678);`.

### Does absl::int128 support constexpr construction?

Yes, the constructors and many operations are `constexpr` compatible where supported by the compiler, allowing compile-time computation with 128-bit values. The implicit constructors at lines [15-21](https://github.com/abseil/abseil-cpp/blob/master/absl/numeric/int128.h#L15-L21) and conversion operators enable constant expression usage in appropriate contexts.