summaryrefslogtreecommitdiff
path: root/absl/numeric/int128.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/numeric/int128.cc')
-rw-r--r--absl/numeric/int128.cc28
1 files changed, 20 insertions, 8 deletions
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index e5526c6f..daa32b51 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -111,7 +111,7 @@ uint128 MakeUint128FromFloat(T v) {
return MakeUint128(0, static_cast<uint64_t>(v));
}
-#if defined(__clang__) && !defined(__SSE3__)
+#if defined(__clang__) && (__clang_major__ < 9) && !defined(__SSE3__)
// Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
// Casting from long double to uint64_t is miscompiled and drops bits.
// It is more work, so only use when we need the workaround.
@@ -131,7 +131,7 @@ uint128 MakeUint128FromFloat(long double v) {
return (static_cast<uint128>(w0) << 100) | (static_cast<uint128>(w1) << 50) |
static_cast<uint128>(w2);
}
-#endif // __clang__ && !__SSE3__
+#endif // __clang__ && (__clang_major__ < 9) && !__SSE3__
} // namespace
uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {}
@@ -202,6 +202,10 @@ std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) {
} // namespace
+std::string uint128::ToString() const {
+ return Uint128ToFormattedString(*this, std::ios_base::dec);
+}
+
std::ostream& operator<<(std::ostream& os, uint128 v) {
std::ios_base::fmtflags flags = os.flags();
std::string rep = Uint128ToFormattedString(v, flags);
@@ -216,9 +220,9 @@ std::ostream& operator<<(std::ostream& os, uint128 v) {
} else if (adjustfield == std::ios::internal &&
(flags & std::ios::showbase) &&
(flags & std::ios::basefield) == std::ios::hex && v != 0) {
- rep.insert(2, count, os.fill());
+ rep.insert(size_t{2}, count, os.fill());
} else {
- rep.insert(0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
}
}
@@ -285,6 +289,14 @@ int128 operator%(int128 lhs, int128 rhs) {
}
#endif // ABSL_HAVE_INTRINSIC_INT128
+std::string int128::ToString() const {
+ std::string rep;
+ if (Int128High64(*this) < 0) rep = "-";
+ rep.append(Uint128ToFormattedString(UnsignedAbsoluteValue(*this),
+ std::ios_base::dec));
+ return rep;
+}
+
std::ostream& operator<<(std::ostream& os, int128 v) {
std::ios_base::fmtflags flags = os.flags();
std::string rep;
@@ -314,16 +326,16 @@ std::ostream& operator<<(std::ostream& os, int128 v) {
break;
case std::ios::internal:
if (print_as_decimal && (rep[0] == '+' || rep[0] == '-')) {
- rep.insert(1, count, os.fill());
+ rep.insert(size_t{1}, count, os.fill());
} else if ((flags & std::ios::basefield) == std::ios::hex &&
(flags & std::ios::showbase) && v != 0) {
- rep.insert(2, count, os.fill());
+ rep.insert(size_t{2}, count, os.fill());
} else {
- rep.insert(0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
}
break;
default: // std::ios::right
- rep.insert(0, count, os.fill());
+ rep.insert(size_t{0}, count, os.fill());
break;
}
}