23 #include <type_traits> 28 std::numeric_limits<uint64_t>::max());
38 #define STEP(T, n, pos, sh) \ 40 if ((n) >= (static_cast<T>(1) << (sh))) { \ 45 static inline int Fls64(uint64_t
n) {
48 STEP(uint64_t, n, pos, 0x20);
49 uint32_t n32 =
static_cast<uint32_t
>(
n);
50 STEP(uint32_t, n32, pos, 0x10);
51 STEP(uint32_t, n32, pos, 0x08);
52 STEP(uint32_t, n32, pos, 0x04);
53 return pos + ((uint64_t{0x3333333322221100} >> (n32 << 2)) & 0x3);
59 static inline int Fls128(
uint128 n) {
61 return Fls64(hi) + 64;
73 if (divisor > dividend) {
75 *remainder_ret = dividend;
79 if (divisor == dividend) {
89 const int shift = Fls128(dividend) - Fls128(denominator);
90 denominator <<= shift;
94 for (
int i = 0;
i <= shift; ++
i) {
96 if (dividend >= denominator) {
97 dividend -= denominator;
103 *quotient_ret = quotient;
104 *remainder_ret = dividend;
107 template <
typename T>
114 assert(std::isfinite(v) && v > -1 &&
115 (std::numeric_limits<T>::max_exponent <= 128 ||
116 v < std::ldexp(static_cast<T>(1), 128)));
118 if (v >= std::ldexp(static_cast<T>(1), 64)) {
119 uint64_t hi =
static_cast<uint64_t
>(std::ldexp(v, -64));
120 uint64_t lo =
static_cast<uint64_t
>(v - std::ldexp(static_cast<T>(hi), 64));
127 #if defined(__clang__) && !defined(__SSE3__) 131 uint128 MakeUint128FromFloat(
long double v) {
133 static_assert(std::numeric_limits<double>::digits >= 50,
"");
134 static_assert(std::numeric_limits<long double>::digits <= 150,
"");
136 assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
138 v = std::ldexp(v, -100);
139 uint64_t w0 =
static_cast<uint64_t
>(
static_cast<double>(std::trunc(v)));
140 v = std::ldexp(v - static_cast<double>(w0), 50);
141 uint64_t w1 =
static_cast<uint64_t
>(
static_cast<double>(std::trunc(v)));
142 v = std::ldexp(v - static_cast<double>(w1), 50);
143 uint64_t w2 =
static_cast<uint64_t
>(
static_cast<double>(std::trunc(v)));
144 return (static_cast<uint128>(w0) << 100) | (static_cast<uint128>(w1) << 50) |
145 static_cast<uint128>(w2);
147 #endif // __clang__ && !__SSE3__ 155 #if defined(ABSL_HAVE_INTRINSIC_INT128) 156 return static_cast<unsigned __int128
>(lhs) /
157 static_cast<unsigned __int128>(rhs);
158 #else // ABSL_HAVE_INTRINSIC_INT128 161 DivModImpl(lhs, rhs, "ient, &remainder);
163 #endif // ABSL_HAVE_INTRINSIC_INT128 166 #if defined(ABSL_HAVE_INTRINSIC_INT128) 167 return static_cast<unsigned __int128
>(lhs) %
168 static_cast<unsigned __int128>(rhs);
169 #else // ABSL_HAVE_INTRINSIC_INT128 172 DivModImpl(lhs, rhs, "ient, &remainder);
174 #endif // ABSL_HAVE_INTRINSIC_INT128 179 std::string Uint128ToFormattedString(
uint128 v, std::ios_base::fmtflags
flags) {
183 switch (flags & std::ios::basefield) {
185 div = 0x1000000000000000;
189 div = 01000000000000000000000;
193 div = 10000000000000000000u;
201 std::ostringstream os;
202 std::ios_base::fmtflags copy_mask =
203 std::ios::basefield | std::ios::showbase | std::ios::uppercase;
204 os.setf(flags & copy_mask, copy_mask);
207 DivModImpl(high, div, &high, &low);
209 DivModImpl(high, div, &high, &mid);
212 os << std::noshowbase << std::setfill(
'0') << std::setw(div_base_log);
214 os << std::setw(div_base_log);
217 os << std::noshowbase << std::setfill(
'0') << std::setw(div_base_log);
226 std::ios_base::fmtflags
flags = os.flags();
227 std::string rep = Uint128ToFormattedString(v, flags);
230 std::streamsize width = os.width(0);
231 if (static_cast<size_t>(width) > rep.size()) {
232 std::ios::fmtflags adjustfield = flags & std::ios::adjustfield;
233 if (adjustfield == std::ios::left) {
234 rep.append(width - rep.size(), os.fill());
235 }
else if (adjustfield == std::ios::internal &&
236 (flags & std::ios::showbase) &&
237 (flags & std::ios::basefield) == std::ios::hex && v != 0) {
238 rep.insert(2, width - rep.size(), os.fill());
240 rep.insert(0, width - rep.size(), os.fill());
250 constexpr
bool numeric_limits<absl::uint128>::is_specialized;
251 constexpr
bool numeric_limits<absl::uint128>::is_signed;
252 constexpr
bool numeric_limits<absl::uint128>::is_integer;
253 constexpr
bool numeric_limits<absl::uint128>::is_exact;
254 constexpr
bool numeric_limits<absl::uint128>::has_infinity;
255 constexpr
bool numeric_limits<absl::uint128>::has_quiet_NaN;
256 constexpr
bool numeric_limits<absl::uint128>::has_signaling_NaN;
257 constexpr float_denorm_style numeric_limits<absl::uint128>::has_denorm;
258 constexpr
bool numeric_limits<absl::uint128>::has_denorm_loss;
259 constexpr float_round_style numeric_limits<absl::uint128>::round_style;
260 constexpr
bool numeric_limits<absl::uint128>::is_iec559;
261 constexpr
bool numeric_limits<absl::uint128>::is_bounded;
262 constexpr
bool numeric_limits<absl::uint128>::is_modulo;
263 constexpr
int numeric_limits<absl::uint128>::digits;
264 constexpr
int numeric_limits<absl::uint128>::digits10;
265 constexpr
int numeric_limits<absl::uint128>::max_digits10;
267 constexpr
int numeric_limits<absl::uint128>::min_exponent;
268 constexpr
int numeric_limits<absl::uint128>::min_exponent10;
269 constexpr
int numeric_limits<absl::uint128>::max_exponent;
270 constexpr
int numeric_limits<absl::uint128>::max_exponent10;
271 constexpr
bool numeric_limits<absl::uint128>::traps;
272 constexpr
bool numeric_limits<absl::uint128>::tinyness_before;
constexpr uint64_t Uint128High64(uint128 v)
friend constexpr uint64_t Uint128Low64(uint128 v)
std::ostream & operator<<(std::ostream &os, absl::LogSeverity s)
uint128 operator%(uint128 lhs, uint128 rhs)
constexpr uint64_t Uint128Low64(uint128 v)
std::pair< uint64_t, uint64_t > uint128
#define STEP(T, n, pos, sh)
const uint128 kuint128max
constexpr uint128 MakeUint128(uint64_t high, uint64_t low)
uint128 operator/(uint128 lhs, uint128 rhs)