PR #1777: Avoid std::ldexp in `operator double(int128)`.

Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/1777

This patch replaces all instances of

  std::ldexp(msb, 64)

with

  msb * (2**64)

as it turns out that this optimization is not done by MSVC. Worse, it emited a function call with error checking, even if the int128 cannot hit the inf limitation.

Sadly even the constant `std::ldexp(1.0, 64)` is not inlined: https://gcc.godbolt.org/z/oGhGz77sx
Merge a21b1c952494944e51e12c62127a71480bc28695 into 878313658ed7cbef40635e2394b28ef0242072d8

Merging this change closes #1777

COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/1777 from degasus:int128_t a21b1c952494944e51e12c62127a71480bc28695
PiperOrigin-RevId: 688968524
Change-Id: Id88cf38e241553f88bf4d97e7b001247dcd5599b
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index 21f65a3..ae736b2 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -789,16 +789,20 @@
 // Conversion operators to floating point types.
 
 inline uint128::operator float() const {
-  return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64);
+  // Note: This method might return Inf.
+  constexpr float pow_2_64 = 18446744073709551616.0f;
+  return static_cast<float>(lo_) + static_cast<float>(hi_) * pow_2_64;
 }
 
 inline uint128::operator double() const {
-  return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64);
+  constexpr double pow_2_64 = 18446744073709551616.0;
+  return static_cast<double>(lo_) + static_cast<double>(hi_) * pow_2_64;
 }
 
 inline uint128::operator long double() const {
+  constexpr long double pow_2_64 = 18446744073709551616.0L;
   return static_cast<long double>(lo_) +
-         std::ldexp(static_cast<long double>(hi_), 64);
+         static_cast<long double>(hi_) * pow_2_64;
 }
 
 // Comparison operators.
diff --git a/absl/numeric/int128_have_intrinsic.inc b/absl/numeric/int128_have_intrinsic.inc
index 51e4b9d..216115a 100644
--- a/absl/numeric/int128_have_intrinsic.inc
+++ b/absl/numeric/int128_have_intrinsic.inc
@@ -170,27 +170,29 @@
   // complement overwhelms the precision of the mantissa.
   //
   // Also check to make sure we don't negate Int128Min()
+  constexpr float pow_2_64 = 18446744073709551616.0f;
   return v_ < 0 && *this != Int128Min()
              ? -static_cast<float>(-*this)
              : static_cast<float>(Int128Low64(*this)) +
-                   std::ldexp(static_cast<float>(Int128High64(*this)), 64);
+                   static_cast<float>(Int128High64(*this)) * pow_2_64;
 }
 
 inline int128::operator double() const {
   // See comment in int128::operator float() above.
+  constexpr double pow_2_64 = 18446744073709551616.0;
   return v_ < 0 && *this != Int128Min()
              ? -static_cast<double>(-*this)
              : static_cast<double>(Int128Low64(*this)) +
-                   std::ldexp(static_cast<double>(Int128High64(*this)), 64);
+                   static_cast<double>(Int128High64(*this)) * pow_2_64;
 }
 
 inline int128::operator long double() const {
   // See comment in int128::operator float() above.
+  constexpr long double pow_2_64 = 18446744073709551616.0L;
   return v_ < 0 && *this != Int128Min()
              ? -static_cast<long double>(-*this)
              : static_cast<long double>(Int128Low64(*this)) +
-                   std::ldexp(static_cast<long double>(Int128High64(*this)),
-                              64);
+                   static_cast<long double>(Int128High64(*this)) * pow_2_64;
 }
 #endif  // Clang on PowerPC
 
diff --git a/absl/numeric/int128_no_intrinsic.inc b/absl/numeric/int128_no_intrinsic.inc
index 195b745..a7cdcea 100644
--- a/absl/numeric/int128_no_intrinsic.inc
+++ b/absl/numeric/int128_no_intrinsic.inc
@@ -139,26 +139,29 @@
   // complement overwhelms the precision of the mantissa.
   //
   // Also check to make sure we don't negate Int128Min()
+  constexpr float pow_2_64 = 18446744073709551616.0f;
   return hi_ < 0 && *this != Int128Min()
              ? -static_cast<float>(-*this)
              : static_cast<float>(lo_) +
-                   std::ldexp(static_cast<float>(hi_), 64);
+                   static_cast<float>(hi_) * pow_2_64;
 }
 
 inline int128::operator double() const {
   // See comment in int128::operator float() above.
+  constexpr double pow_2_64 = 18446744073709551616.0;
   return hi_ < 0 && *this != Int128Min()
              ? -static_cast<double>(-*this)
              : static_cast<double>(lo_) +
-                   std::ldexp(static_cast<double>(hi_), 64);
+                   static_cast<double>(hi_) * pow_2_64;
 }
 
 inline int128::operator long double() const {
   // See comment in int128::operator float() above.
+  constexpr long double pow_2_64 = 18446744073709551616.0L;
   return hi_ < 0 && *this != Int128Min()
              ? -static_cast<long double>(-*this)
              : static_cast<long double>(lo_) +
-                   std::ldexp(static_cast<long double>(hi_), 64);
+                   static_cast<long double>(hi_) * pow_2_64;
 }
 
 // Comparison operators.