absl::int128·uint128 분석
#왜 128비트가 필요한가
64비트 정수의 한계는 두 곳에서 자주 부딪힌다.
- 광범위 timestamp — 나노초 epoch는 64비트로 ~292년. 마이크로초로는 ~58만 년. 곱·누적이 들어가면 부족해진다.
- 누적 통계 —
count × value²같은 분산 계산. - 암호·해시 합성 — SipHash, BLAKE 같은 알고리즘이 128비트 중간 결과를 요구.
Clang/GCC는 __int128을 비표준 확장으로 제공하지만 MSVC는 없다. Abseil은 모든 플랫폼에 동일 인터페이스를 보장한다.
비트 레이아웃과 carry 처리는 다음과 같다.
#include "absl/numeric/int128.h"
absl::uint128 u = absl::MakeUint128(0x12345678, 0xabcdef0123456789);absl::int128 s = absl::MakeInt128(-1, 0);
absl::uint128 sum = u + absl::Uint128Max();#생성
문법이 약간 다른 두 가지 생성 방식이 있다.
// 1. 64-bit half-pair (high, low)absl::uint128 a = absl::MakeUint128(0xdead'beef, 0xcafe'0000'0000);
// 2. 정수 리터럴 변환absl::uint128 b = 42;absl::int128 c = -100;
// 3. 상수absl::uint128 max_u = absl::Uint128Max();absl::int128 min_s = absl::Int128Min();absl::int128 max_s = absl::Int128Max();리터럴은 64비트까지만 직접 들어간다. 큰 값은 두 64비트 조각으로 합성하거나 곱·shift로 만든다.
absl::uint128 trillion_squared = absl::uint128{1'000'000'000'000ULL} * absl::uint128{1'000'000'000'000ULL};#산술
C++ 산술 연산자가 모두 오버로드된다. 컴파일러가 __int128을 지원하면 그것을 사용하고, 아니면 long-arithmetic emulation으로 fallback.
absl::uint128 a = absl::MakeUint128(1, 0); // 2^64absl::uint128 b = a + 1; // 2^64 + 1
absl::uint128 m = a * a; // 2^128 — overflow // m == 0 (low 128 bits)
absl::uint128 d = m / a; // 0 / a == 0
absl::uint128 sh = absl::uint128{1} << 100; // 2^100부호 있는 경우 overflow는 implementation-defined (대부분 wrap)이다.
#64-bit 분해
Uint128High64/Uint128Low64로 두 절반을 꺼낼 수 있다.
absl::uint128 v = ...;uint64_t hi = absl::Uint128High64(v);uint64_t lo = absl::Uint128Low64(v);직렬화 시 두 64비트로 나누어 저장하는 패턴이 흔하다.
void Encode(absl::uint128 v, char* buf) { uint64_t hi = absl::Uint128High64(v); uint64_t lo = absl::Uint128Low64(v); std::memcpy(buf, &hi, 8); std::memcpy(buf + 8, &lo, 8);}#문자열 변환
absl::uint128 v = absl::MakeUint128(0x1234, 0x5678);std::string s = absl::StrCat(v);// "340282366920938463463374607431768211456" 같은 십진수
std::ostringstream os;os << std::hex << v; // 16진수 출력StrCat/StreamFormatter가 자동 지원한다. 파싱은 absl::SimpleAtoi로.
absl::uint128 parsed;if (!absl::SimpleAtoi("123456789012345678901234567890", &parsed)) { return absl::InvalidArgumentError("bad number");}#std::numeric_limits 호환
static_assert(std::numeric_limits<absl::uint128>::is_integer);static_assert(std::numeric_limits<absl::uint128>::digits == 128);
absl::uint128 max = std::numeric_limits<absl::uint128>::max();C++20부터는 std::uint128_t가 제안되었지만 표준 진입이 아직 미정. Abseil은 그 사이의 명확한 안정 답이다.
#작은 예시 — 큰 카운터
class GlobalRequestCounter {public: void Increment(uint64_t bytes) { absl::MutexLock lock(&mu_); count_ += 1; bytes_total_ += absl::uint128{bytes}; }
absl::uint128 BytesTotal() const { absl::MutexLock lock(&mu_); return bytes_total_; }
private: mutable absl::Mutex mu_; uint64_t count_ ABSL_GUARDED_BY(mu_) = 0; absl::uint128 bytes_total_ ABSL_GUARDED_BY(mu_) = 0;};petabyte 누적이 우습게 들어간다. 64비트면 16EB(2^64 바이트)에서 wrap.
#코드 리뷰 체크리스트
// 회피 — __int128 비표준 직접 사용__int128 v = ...; // ❌ MSVC 안 됨
// Good — absl::int128absl::int128 v = ...;// 회피 — high/low 합성 시 부호 혼동absl::int128 v = (static_cast<absl::int128>(hi) << 64) | lo; // ⚠️ 부호 확장
// Good — 명시 helperabsl::int128 v = absl::MakeInt128(hi, lo);// 회피 — JSON 직렬화에 그대로std::string s = absl::StrCat(v); // 10진수 문자열 → JSON number는 53비트 제한// → 문자열로 wrap 또는 hi/lo 두 필드로 분해#정리
absl::int128/uint128은 모든 플랫폼 통합 128비트 정수.- 컴파일러 builtin(
__int128) 가능 시 그것을 사용, 아니면 emulation. MakeUint128(hi, lo)/MakeInt128(hi, lo)로 생성,Uint128High64/Uint128Low64로 분해.- 산술·shift·비교 연산자 전부 오버로드. overflow는 wrap.
StrCat·SimpleAtoi로 문자열 변환.numeric_limits호환.
#다음 장 예고
Part 9-02: bits — popcount, countl_zero 등 비트 연산.
#관련 항목
Abseil Code Review · 49 of 79
- 1 Abseil Code Review — Google production-grade C++ 라이브러리 분석
- 2 Abseil 개요 — Google이 std를 보완한 이유
- 3 Abseil 설계 철학 — std 호환과 추가 기능의 균형
- 4 Abseil 빌드와 의존성 — Bazel vs CMake
- 5 Abseil LTS vs HEAD 릴리스 모델 분석
- 6 Abseil Versioning과 ABI 호환성 정책
- 7 Abseil 매크로 — ABSL_HAVE_*·ABSL_ATTRIBUTE_*
- 8 Abseil ABSL_PREDICT_TRUE/FALSE — branch hint
- 9 absl::LogSeverity — 로그 레벨 타입
- 10 Abseil type_traits — negation·conjunction·void_t
- 11 Abseil Conformance·Policy 분석
- 12 Abseil Memory utilities 분석
- 13 Abseil raw_logging — heap-free 로깅
- 14 Abseil thread_annotations — clang TSA 통합
- 15 absl::Status — exception-free error handling
- 16 absl::StatusOr<T> — 값 또는 에러
- 17 absl status_macros — ASSIGN_OR_RETURN·RETURN_IF_ERROR
- 18 absl::Status payload — 구조화된 에러 컨텍스트
- 19 absl::Status ↔ exception 변환 패턴
- 20 absl::string_view — non-owning 문자열 참조
- 21 absl::string_view 함정 — dangling·c_str·임시 객체
- 22 absl::StrCat — 가변 인자 문자열 연결과 AlphaNum
- 23 absl::StrSplit — Delimiter·Predicate·컨테이너 변환
- 24 absl::StrJoin — 컨테이너 결합과 Formatter
- 25 absl::StrFormat — type-safe printf·FormatSpec
- 26 Abseil ASCII 함수 — locale-free 분류·대소문자 변환
- 27 Abseil Escape — CEscape·HexEscape·Base64
- 28 absl::flat_hash_map — Swiss Table 기반 hash map
- 29 absl::flat_hash_set — set 버전 Swiss Table
- 30 absl::node_hash_map — stable pointer가 필요할 때
- 31 absl::btree_map — sorted·cache-friendly B-tree
- 32 absl::FixedArray — 런타임 크기 stack 배열
- 33 absl::InlinedVector — small buffer optimization
- 34 Abseil Swiss Table internals — control byte·SIMD probing
- 35 absl::Mutex — reader-writer·fairness·deadlock 검출
- 36 absl::Mutex Conditional Critical Section — Await로 cv 없애기
- 37 absl::Notification — once-only signal
- 38 absl::BlockingCounter·Barrier — 다중 thread 조율
- 39 absl::Mutex annotations — clang thread-safety로 race를 컴파일 타임에
- 40 absl::Time·Duration 분석 — 단단한 type
- 41 absl::Time Format·Parse
- 42 absl::CivilTime 분석
- 43 absl::time_zone 분석
- 44 absl::Time mocking — 테스트 친화 시간
- 45 absl::BitGen — 모던 난수 생성기
- 46 Abseil Random Distributions — Uniform·Exponential
- 47 Abseil Mocking Random — 테스트 결정성
- 48 Abseil Random Seeding·Entropy
- 49 absl::int128·uint128 분석
- 50 absl::bits — popcount·countl_zero
- 51 absl::optional vs std::optional
- 52 absl::variant 분석
- 53 absl::span 분석
- 54 absl::any 분석
- 55 absl::compare — three-way 비교
- 56 Abseil utility — apply·in_place
- 57 Abseil AbslHashValue 분석
- 58 Abseil HashState chaining
- 59 Abseil Custom hashable 구현
- 60 Abseil LOG·VLOG·CHECK 분석
- 61 Abseil LogSink 분석
- 62 Abseil LogEntry·structured logging
- 63 Abseil Stack trace·failure_signal_handler
- 64 ABSL_FLAG 정의 분석
- 65 Abseil ParseCommandLine 동작
- 66 Abseil Flag introspection·validation
- 67 Google 스타일의 Abseil 사용 패턴
- 68 Abseil 자주 보는 anti-pattern
- 69 std → absl 마이그레이션 전략
- 70 absl::Cleanup — 함수 종료 시 실행 보장
- 71 Abseil algorithm container 확장 — c_sort·c_find_if·c_count_if
- 72 absl::function_ref와 any_invocable — 함수 객체 전달의 두 축
- 73 absl::bind_front와 Overload — 함수 객체 보조 도구
- 74 absl::Cord — 분산 시스템용 대용량 문자열
- 75 absl::from_chars·SimpleAtoi — 빠른 숫자 변환
- 76 absl::Cord vs std::string — 선택 기준과 메모리 프로파일
- 77 absl::GetStackTrace와 Symbolize — crash 시 readable stack
- 78 absl::ComputeCrc32c — 하드웨어 가속 체크섬
- 79 absl::PeriodicSampler — 적응형 샘플링·jitter 회피
관련 글
absl::bits — popcount·countl_zero
absl::popcount, countl_zero, countr_zero — C++20 <bit>의 polyfill. SwissTable·해시·정수 압축의 핵심 primitive.
같은 시리즈에서 이어 읽기
absl::PeriodicSampler — 적응형 샘플링·jitter 회피
absl::profiling_internal::PeriodicSampler — sampling rate를 동적으로 조정, geometric distribution으로 jitter 회피. 메모리 할당 추적·profiling 인프라의 기반.
같은 시리즈에서 이어 읽기
absl::ComputeCrc32c — 하드웨어 가속 체크섬
absl::ComputeCrc32c — SSE4.2 CRC32, ARM CRC 명령어로 가속된 CRC32C 구현. iSCSI·Btrfs·protobuf에서 표준화된 무결성 검사.
같은 시리즈에서 이어 읽기