Export of internal Abseil changes.
-- 00d42e3d5433aaf29c2ed293520b2ba178ae8bdb by Greg Falcon <gfalcon@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 238061818 -- 867a7ca318fac2991ea9a4107dbae3cc9fbf974a by Abseil Team <absl-team@google.com>: Added a IWYU export pragma when including a standard header for the purpose of aliasing its symbols. PiperOrigin-RevId: 238022277 -- 17047745058f2f151cd986ea9f649512542d3876 by Matt Armstrong <marmstrong@google.com>: Clarify the comment discouraging WrapUnique<T>(x) calls. PiperOrigin-RevId: 237873803 -- 3dcb2e4968243d33ca0ce53280c445df50f4a7ec by Samuel Benzaquen <sbenza@google.com>: Workaround clang bug https://bugs.llvm.org/show_bug.cgi?id=38289 PiperOrigin-RevId: 237873551 -- f348d2dc7087a990cbdfb95aa51fd7ff478ae40e by Samuel Benzaquen <sbenza@google.com>: Reduce minimum capacity to 1. This reduces memory usage for small tables. A flat_hash_set<int> of 1 element goes from 92 bytes to 24. A flat_hash_set<string> of 1 element goes from 512 bytes to 56. PiperOrigin-RevId: 237859811 -- 9c8125be5e4e5d22a7bb62bdec8c323338385c1b by Jon Cohen <cohenjon@google.com>: Bump to CMake 3.5. This is the oldest modern cmake being included by default in most popular OS distributions according to https://repology.org/project/cmake/versions. Specifically, Ubuntu LTS 16.04 uses cmake 3.5 (https://packages.ubuntu.com/xenial/cmake) PiperOrigin-RevId: 237859345 -- 07638d672e0a4dced986a62750cfd8318ed36ffa by Derek Mauro <dmauro@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 237714597 GitOrigin-RevId: 00d42e3d5433aaf29c2ed293520b2ba178ae8bdb Change-Id: I5faecc45add4a5a774d4f9baf06e5519091f2ccc
This commit is contained in:
parent
88a152ae74
commit
256be56344
37 changed files with 180 additions and 128 deletions
|
|
@ -123,6 +123,28 @@ uint128 MakeUint128FromFloat(T v) {
|
|||
|
||||
return MakeUint128(0, static_cast<uint64_t>(v));
|
||||
}
|
||||
|
||||
#if defined(__clang__) && !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.
|
||||
uint128 MakeUint128FromFloat(long double v) {
|
||||
// Go 50 bits at a time, that fits in a double
|
||||
static_assert(std::numeric_limits<double>::digits >= 50, "");
|
||||
static_assert(std::numeric_limits<long double>::digits <= 150, "");
|
||||
// Undefined behavior if v is not finite or cannot fit into uint128.
|
||||
assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
|
||||
|
||||
v = std::ldexp(v, -100);
|
||||
uint64_t w0 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
|
||||
v = std::ldexp(v - static_cast<double>(w0), 50);
|
||||
uint64_t w1 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
|
||||
v = std::ldexp(v - static_cast<double>(w1), 50);
|
||||
uint64_t w2 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
|
||||
return (static_cast<uint128>(w0) << 100) | (static_cast<uint128>(w1) << 50) |
|
||||
static_cast<uint128>(w2);
|
||||
}
|
||||
#endif // __clang__ && !__SSE3__
|
||||
} // namespace
|
||||
|
||||
uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {}
|
||||
|
|
|
|||
|
|
@ -271,6 +271,20 @@ TEST(Uint128, ConversionTests) {
|
|||
EXPECT_EQ(static_cast<absl::uint128>(round_to_zero), 0);
|
||||
EXPECT_EQ(static_cast<absl::uint128>(round_to_five), 5);
|
||||
EXPECT_EQ(static_cast<absl::uint128>(round_to_nine), 9);
|
||||
|
||||
absl::uint128 highest_precision_in_long_double =
|
||||
~absl::uint128{} >> (128 - std::numeric_limits<long double>::digits);
|
||||
EXPECT_EQ(highest_precision_in_long_double,
|
||||
static_cast<absl::uint128>(
|
||||
static_cast<long double>(highest_precision_in_long_double)));
|
||||
// Apply a mask just to make sure all the bits are the right place.
|
||||
const absl::uint128 arbitrary_mask =
|
||||
absl::MakeUint128(0xa29f622677ded751, 0xf8ca66add076f468);
|
||||
EXPECT_EQ(highest_precision_in_long_double & arbitrary_mask,
|
||||
static_cast<absl::uint128>(static_cast<long double>(
|
||||
highest_precision_in_long_double & arbitrary_mask)));
|
||||
|
||||
EXPECT_EQ(static_cast<absl::uint128>(-0.1L), 0);
|
||||
}
|
||||
|
||||
TEST(Uint128, OperatorAssignReturnRef) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue