Export of internal Abseil changes.
-- cd076f55c1fa600131f6dda392533dfe61679fc0 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 224008762 -- e05f62b01286d51044ff86ec6ef565749b9faf82 by Abseil Team <absl-team@google.com>: Create a pow10() test helper function to compute guaranteed-precise double values of 10^x. Not all standard libraries ship bit-accurate pow() functions, causing tests to fail that rely on expected values generated by it. PiperOrigin-RevId: 223883762 -- fd88e5e3f7ab80f7f5df9fd1488cd58b4573be69 by Abseil Team <absl-team@google.com>: Remove some absl:: qualifications to work around inline namespace bugs on MSVC 2015. PiperOrigin-RevId: 223869642 -- 6276cfff969d596edd36a2bbaba65ee045808903 by Abseil Team <absl-team@google.com>: Update absl/memory/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223854224 -- 359de9afc7a34c975fd3e0cbc52afd96637d97bd by Chris Kennelly <ckennelly@google.com>: Mark spinlock_benchmark_common as alwayslink = 1. PiperOrigin-RevId: 223844536 -- 450cd8cbe2789a6d54ed1eb87170259bb334f8b9 by Abseil Team <absl-team@google.com>: Support .* (pointer-to-member dereference) expressions in demangle.cc. PiperOrigin-RevId: 223826797 -- 772ca92179c3634f3e31a80bbc272ed8022e3572 by Abseil Team <absl-team@google.com>: Fix misspellings in absl::variant comments and replace a ' with a `. PiperOrigin-RevId: 223807911 -- 35dcdc2fbf299d195658aac101887f6dcad1de2f by Abseil Team <absl-team@google.com>: Bug fix in CMakeLists.txt file (SRCS --> HDRS). The compressed_tuple header-only library is being defined with the SRCS parameter instead of the HDRS parameter and this has been observed to cause some builds on some platforms to attempt to create a static library from it which fails since there are no .cc sources. PiperOrigin-RevId: 223805367 -- 4a57a3d2045bb137c0c97958e45ce425190b8d3e by Chris Kennelly <ckennelly@google.com>: Add test that absl::make_unique value initializes memory. PiperOrigin-RevId: 223801819 -- dfe8289d7f4dcc6bb568a26aaf192a89e896bdfd by Chris Kennelly <ckennelly@google.com>: SpinLock: Use exchange to avoid missing wakeups. The default fast path for SpinLock::Unlock does not use an atomic. If the SpinLock becomes contended while we are unlocking between lockword_.load and lockword_.store, we will fail to wake up the new waiter. This can cause unexpected latency spikes. PiperOrigin-RevId: 223800369 -- 9b9d35df786482f0016f77dd31691eff81503d23 by Abseil Team <absl-team@google.com>: Update absl/hash/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223755819 -- c2014e2704b87e7cdce2d2a0287c7e2397752296 by Abseil Team <absl-team@google.com>: Update absl/debugging/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 223751986 -- d83a4e09126400e3fd80645cb03ee558f532271e by Derek Mauro <dmauro@google.com>: Cleanup synchronization benchmarks. PiperOrigin-RevId: 223589416 -- fad140b473586531b5b12843f942ec27dfcf5e93 by CJ Johnson <johnsoncj@google.com>: Makes unifies the order of forward_iterator and input_iterator overloads PiperOrigin-RevId: 223580660 -- 6cd7c96faa7cc5f79f574e35a1b13837ef187d05 by Abseil Team <absl-team@google.com>: Internal Change. PiperOrigin-RevId: 223561629 -- bd2e545356b0f548af0e3c14bb2f7f0e712e49d0 by Shaindel Schwartz <shaindel@google.com>: Remove misleading comments. try_emplace() does not exist for the hash_set containers. PiperOrigin-RevId: 223543089 -- 0cd380a53b587eb7aacc4003a4a3bbb6c78d7c10 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 223512551 -- 7156dfee599cb72e9adddfe0e6ae07a95ddf10bb by Greg Miller <jgm@google.com>: Fixes UB that would result from constructing, multiplying, or dividing a Duration with a double "NaN" value. This CL changes the absl::Duration *implementation* to return an InfiniteDuration value that has the same sign as the given NaN. PiperOrigin-RevId: 223407499 -- 196b7d18609958267951882baf7f9429e49bcafa by CJ Johnson <johnsoncj@google.com>: Addresses NVCC+MSVC compilation bug where `inlined_capacity()` was not considered valid in constexpr PiperOrigin-RevId: 223397718 GitOrigin-RevId: cd076f55c1fa600131f6dda392533dfe61679fc0 Change-Id: I5423ca6470f661a7c6f73aa8fee49990446f157f
This commit is contained in:
parent
926bfeb9ff
commit
44b0fafc62
30 changed files with 1126 additions and 383 deletions
|
@ -413,6 +413,7 @@ cc_test(
|
|||
copts = ABSL_TEST_COPTS,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":pow10_helper",
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"//absl/base:core_headers",
|
||||
|
@ -471,6 +472,8 @@ cc_test(
|
|||
srcs = ["charconv_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
deps = [
|
||||
":pow10_helper",
|
||||
":str_format",
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
|
@ -659,3 +662,23 @@ cc_test(
|
|||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "pow10_helper",
|
||||
testonly = True,
|
||||
srcs = ["internal/pow10_helper.cc"],
|
||||
hdrs = ["internal/pow10_helper.h"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "pow10_helper_test",
|
||||
srcs = ["internal/pow10_helper_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":pow10_helper",
|
||||
":str_format",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -131,6 +131,15 @@ absl_library(
|
|||
absl::strings
|
||||
)
|
||||
|
||||
# pow10_helper
|
||||
absl_library(
|
||||
TARGET
|
||||
pow10_helper
|
||||
SOURCES
|
||||
"internal/pow10_helper.cc"
|
||||
"internal/pow10_helper.h"
|
||||
)
|
||||
|
||||
#
|
||||
## TESTS
|
||||
#
|
||||
|
@ -316,7 +325,7 @@ absl_test(
|
|||
|
||||
# test numbers_test
|
||||
set(NUMBERS_TEST_SRC "numbers_test.cc")
|
||||
set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings)
|
||||
set(NUMBERS_TEST_PUBLIC_LIBRARIES absl::strings pow10_helper)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
|
@ -358,7 +367,7 @@ absl_test(
|
|||
|
||||
# test charconv_test
|
||||
set(CHARCONV_TEST_SRC "charconv_test.cc")
|
||||
set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings)
|
||||
set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings absl::str_format pow10_helper)
|
||||
|
||||
absl_test(
|
||||
TARGET
|
||||
|
@ -460,3 +469,13 @@ absl_test(
|
|||
absl::base
|
||||
)
|
||||
|
||||
# test pow10_helper_test
|
||||
absl_test(
|
||||
TARGET
|
||||
pow10_helper_test
|
||||
SOURCES
|
||||
"internal/pow10_helper_test.cc"
|
||||
PUBLIC_LIBRARIES
|
||||
pow10_helper
|
||||
absl::str_format
|
||||
)
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/internal/pow10_helper.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
#ifdef _MSC_FULL_VER
|
||||
#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
|
||||
|
@ -31,6 +33,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
using absl::strings_internal::Pow10;
|
||||
|
||||
#if ABSL_COMPILER_DOES_EXACT_ROUNDING
|
||||
|
||||
// Tests that the given string is accepted by absl::from_chars, and that it
|
||||
|
@ -678,7 +682,8 @@ void TestOverflowAndUnderflow(
|
|||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(expected, actual);
|
||||
EXPECT_EQ(expected, actual)
|
||||
<< absl::StrFormat("%a vs %a", expected, actual);
|
||||
}
|
||||
// test legal values near upper_bound
|
||||
for (index = upper_bound, step = 1; index > lower_bound;
|
||||
|
@ -690,7 +695,8 @@ void TestOverflowAndUnderflow(
|
|||
auto result =
|
||||
absl::from_chars(input.data(), input.data() + input.size(), actual);
|
||||
EXPECT_EQ(result.ec, std::errc());
|
||||
EXPECT_EQ(expected, actual);
|
||||
EXPECT_EQ(expected, actual)
|
||||
<< absl::StrFormat("%a vs %a", expected, actual);
|
||||
}
|
||||
// Test underflow values below lower_bound
|
||||
for (index = lower_bound - 1, step = 1; index > -1000000;
|
||||
|
@ -747,7 +753,7 @@ TEST(FromChars, HexdecimalFloatLimits) {
|
|||
// acceptable exponents in this test.
|
||||
TEST(FromChars, DecimalDoubleLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
|
||||
auto expected_gen = [](int index) { return std::pow(10.0, index); };
|
||||
auto expected_gen = [](int index) { return Pow10(index); };
|
||||
TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
|
||||
}
|
||||
|
||||
|
@ -759,7 +765,7 @@ TEST(FromChars, DecimalDoubleLimits) {
|
|||
// acceptable exponents in this test.
|
||||
TEST(FromChars, DecimalFloatLimits) {
|
||||
auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
|
||||
auto expected_gen = [](int index) { return std::pow(10.0, index); };
|
||||
auto expected_gen = [](int index) { return Pow10(index); };
|
||||
TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
|
||||
}
|
||||
|
||||
|
|
120
absl/strings/internal/pow10_helper.cc
Normal file
120
absl/strings/internal/pow10_helper.cc
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/strings/internal/pow10_helper.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
namespace {
|
||||
|
||||
// The exact value of 1e23 falls precisely halfway between two representable
|
||||
// doubles. Furthermore, the rounding rules we prefer (break ties by rounding
|
||||
// to the nearest even) dictate in this case that the number should be rounded
|
||||
// down, but this is not completely specified for floating-point literals in
|
||||
// C++. (It just says to use the default rounding mode of the standard
|
||||
// library.) We ensure the result we want by using a number that has an
|
||||
// unambiguous correctly rounded answer.
|
||||
constexpr double k1e23 = 9999999999999999e7;
|
||||
|
||||
constexpr double kPowersOfTen[] = {
|
||||
0.0, 1e-323, 1e-322, 1e-321, 1e-320, 1e-319, 1e-318, 1e-317, 1e-316,
|
||||
1e-315, 1e-314, 1e-313, 1e-312, 1e-311, 1e-310, 1e-309, 1e-308, 1e-307,
|
||||
1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301, 1e-300, 1e-299, 1e-298,
|
||||
1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291, 1e-290, 1e-289,
|
||||
1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281, 1e-280,
|
||||
1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271,
|
||||
1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262,
|
||||
1e-261, 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253,
|
||||
1e-252, 1e-251, 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244,
|
||||
1e-243, 1e-242, 1e-241, 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235,
|
||||
1e-234, 1e-233, 1e-232, 1e-231, 1e-230, 1e-229, 1e-228, 1e-227, 1e-226,
|
||||
1e-225, 1e-224, 1e-223, 1e-222, 1e-221, 1e-220, 1e-219, 1e-218, 1e-217,
|
||||
1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211, 1e-210, 1e-209, 1e-208,
|
||||
1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201, 1e-200, 1e-199,
|
||||
1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191, 1e-190,
|
||||
1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181,
|
||||
1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172,
|
||||
1e-171, 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163,
|
||||
1e-162, 1e-161, 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154,
|
||||
1e-153, 1e-152, 1e-151, 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145,
|
||||
1e-144, 1e-143, 1e-142, 1e-141, 1e-140, 1e-139, 1e-138, 1e-137, 1e-136,
|
||||
1e-135, 1e-134, 1e-133, 1e-132, 1e-131, 1e-130, 1e-129, 1e-128, 1e-127,
|
||||
1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120, 1e-119, 1e-118,
|
||||
1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, 1e-110, 1e-109,
|
||||
1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101, 1e-100,
|
||||
1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91,
|
||||
1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82,
|
||||
1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73,
|
||||
1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64,
|
||||
1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55,
|
||||
1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46,
|
||||
1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37,
|
||||
1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28,
|
||||
1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19,
|
||||
1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,
|
||||
1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
|
||||
1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8,
|
||||
1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17,
|
||||
1e+18, 1e+19, 1e+20, 1e+21, 1e+22, k1e23, 1e+24, 1e+25, 1e+26,
|
||||
1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35,
|
||||
1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44,
|
||||
1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53,
|
||||
1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62,
|
||||
1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71,
|
||||
1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
|
||||
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89,
|
||||
1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98,
|
||||
1e+99, 1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107,
|
||||
1e+108, 1e+109, 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116,
|
||||
1e+117, 1e+118, 1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125,
|
||||
1e+126, 1e+127, 1e+128, 1e+129, 1e+130, 1e+131, 1e+132, 1e+133, 1e+134,
|
||||
1e+135, 1e+136, 1e+137, 1e+138, 1e+139, 1e+140, 1e+141, 1e+142, 1e+143,
|
||||
1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149, 1e+150, 1e+151, 1e+152,
|
||||
1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159, 1e+160, 1e+161,
|
||||
1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169, 1e+170,
|
||||
1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179,
|
||||
1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188,
|
||||
1e+189, 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197,
|
||||
1e+198, 1e+199, 1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206,
|
||||
1e+207, 1e+208, 1e+209, 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215,
|
||||
1e+216, 1e+217, 1e+218, 1e+219, 1e+220, 1e+221, 1e+222, 1e+223, 1e+224,
|
||||
1e+225, 1e+226, 1e+227, 1e+228, 1e+229, 1e+230, 1e+231, 1e+232, 1e+233,
|
||||
1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239, 1e+240, 1e+241, 1e+242,
|
||||
1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249, 1e+250, 1e+251,
|
||||
1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259, 1e+260,
|
||||
1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269,
|
||||
1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278,
|
||||
1e+279, 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287,
|
||||
1e+288, 1e+289, 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296,
|
||||
1e+297, 1e+298, 1e+299, 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305,
|
||||
1e+306, 1e+307, 1e+308,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
double Pow10(int exp) {
|
||||
if (exp < -324) {
|
||||
return 0.0;
|
||||
} else if (exp > 308) {
|
||||
return INFINITY;
|
||||
} else {
|
||||
return kPowersOfTen[exp + 324];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
36
absl/strings/internal/pow10_helper.h
Normal file
36
absl/strings/internal/pow10_helper.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// This test helper library contains a table of powers of 10, to guarantee
|
||||
// precise values are computed across the full range of doubles. We can't rely
|
||||
// on the pow() function, because not all standard libraries ship a version
|
||||
// that is precise.
|
||||
#ifndef ABSL_STRINGS_POW10_HELPER_H_
|
||||
#define ABSL_STRINGS_POW10_HELPER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
// Computes the precise value of 10^exp. (I.e. the nearest representable
|
||||
// double to the exact value, rounding to nearest-even in the (single) case of
|
||||
// being exactly halfway between.)
|
||||
double Pow10(int exp);
|
||||
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_POW10_HELPER_H_
|
120
absl/strings/internal/pow10_helper_test.cc
Normal file
120
absl/strings/internal/pow10_helper_test.cc
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2018 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/strings/internal/pow10_helper.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
namespace absl {
|
||||
namespace strings_internal {
|
||||
|
||||
namespace {
|
||||
|
||||
struct TestCase {
|
||||
int power; // Testing Pow10(power)
|
||||
uint64_t significand; // Raw bits of the expected value
|
||||
int radix; // significand is adjusted by 2^radix
|
||||
};
|
||||
|
||||
TEST(Pow10HelperTest, Works) {
|
||||
// The logic in pow10_helper.cc is so simple that theoretically we don't even
|
||||
// need a test. However, we're paranoid and believe that there may be
|
||||
// compilers that don't round floating-point literals correctly, even though
|
||||
// it is specified by the standard. We check various edge cases, just to be
|
||||
// sure.
|
||||
constexpr TestCase kTestCases[] = {
|
||||
// Subnormals
|
||||
{-323, 0x2, -1074},
|
||||
{-322, 0x14, -1074},
|
||||
{-321, 0xca, -1074},
|
||||
{-320, 0x7e8, -1074},
|
||||
{-319, 0x4f10, -1074},
|
||||
{-318, 0x316a2, -1074},
|
||||
{-317, 0x1ee257, -1074},
|
||||
{-316, 0x134d761, -1074},
|
||||
{-315, 0xc1069cd, -1074},
|
||||
{-314, 0x78a42205, -1074},
|
||||
{-313, 0x4b6695433, -1074},
|
||||
{-312, 0x2f201d49fb, -1074},
|
||||
{-311, 0x1d74124e3d1, -1074},
|
||||
{-310, 0x12688b70e62b, -1074},
|
||||
{-309, 0xb8157268fdaf, -1074},
|
||||
{-308, 0x730d67819e8d2, -1074},
|
||||
// Values that are very close to rounding the other way.
|
||||
// Comment shows difference of significand from the true value.
|
||||
{-307, 0x11fa182c40c60d, -1072}, // -.4588
|
||||
{-290, 0x18f2b061aea072, -1016}, // .4854
|
||||
{-276, 0x11BA03F5B21000, -969}, // .4709
|
||||
{-259, 0x1899C2F6732210, -913}, // .4830
|
||||
{-252, 0x1D53844EE47DD1, -890}, // -.4743
|
||||
{-227, 0x1E5297287C2F45, -807}, // -.4708
|
||||
{-198, 0x1322E220A5B17E, -710}, // -.4714
|
||||
{-195, 0x12B010D3E1CF56, -700}, // .4928
|
||||
{-192, 0x123FF06EEA847A, -690}, // .4968
|
||||
{-163, 0x1708D0F84D3DE7, -594}, // -.4977
|
||||
{-145, 0x13FAAC3E3FA1F3, -534}, // -.4785
|
||||
{-111, 0x133D4032C2C7F5, -421}, // .4774
|
||||
{-106, 0x1D5B561574765B, -405}, // -.4869
|
||||
{-104, 0x16EF5B40C2FC77, -398}, // -.4741
|
||||
{-88, 0x197683DF2F268D, -345}, // -.4738
|
||||
{-86, 0x13E497065CD61F, -338}, // .4736
|
||||
{-76, 0x17288E1271F513, -305}, // -.4761
|
||||
{-63, 0x1A53FC9631D10D, -262}, // .4929
|
||||
{-30, 0x14484BFEEBC2A0, -152}, // .4758
|
||||
{-21, 0x12E3B40A0E9B4F, -122}, // -.4916
|
||||
{-5, 0x14F8B588E368F1, -69}, // .4829
|
||||
{23, 0x152D02C7E14AF6, 24}, // -.5000 (exactly, round-to-even)
|
||||
{29, 0x1431E0FAE6D721, 44}, // -.4870
|
||||
{34, 0x1ED09BEAD87C03, 60}, // -.4721
|
||||
{70, 0x172EBAD6DDC73D, 180}, // .4733
|
||||
{105, 0x1BE7ABD3781ECA, 296}, // -.4850
|
||||
{126, 0x17A2ECC414A03F, 366}, // -.4999
|
||||
{130, 0x1CDA62055B2D9E, 379}, // .4855
|
||||
{165, 0x115D847AD00087, 496}, // -.4913
|
||||
{172, 0x14B378469B6732, 519}, // .4818
|
||||
{187, 0x1262DFEEBBB0F9, 569}, // -.4805
|
||||
{210, 0x18557F31326BBB, 645}, // -.4992
|
||||
{212, 0x1302CB5E6F642A, 652}, // -.4838
|
||||
{215, 0x1290BA9A38C7D1, 662}, // -.4881
|
||||
{236, 0x1F736F9B3494E9, 731}, // .4707
|
||||
{244, 0x176EC98994F489, 758}, // .4924
|
||||
{250, 0x1658E3AB795204, 778}, // -.4963
|
||||
{252, 0x117571DDF6C814, 785}, // .4873
|
||||
{254, 0x1B4781EAD1989E, 791}, // -.4887
|
||||
{260, 0x1A03FDE214CAF1, 811}, // .4784
|
||||
{284, 0x1585041B2C477F, 891}, // .4798
|
||||
{304, 0x1D2A1BE4048F90, 957}, // -.4987
|
||||
// Out-of-range values
|
||||
{-324, 0x0, 0},
|
||||
{-325, 0x0, 0},
|
||||
{-326, 0x0, 0},
|
||||
{309, 1, 2000},
|
||||
{310, 1, 2000},
|
||||
{311, 1, 2000},
|
||||
};
|
||||
for (const TestCase& test_case : kTestCases) {
|
||||
EXPECT_EQ(Pow10(test_case.power),
|
||||
std::ldexp(test_case.significand, test_case.radix))
|
||||
<< absl::StrFormat("Failure for Pow10(%d): %a vs %a", test_case.power,
|
||||
Pow10(test_case.power),
|
||||
std::ldexp(test_case.significand, test_case.radix));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace strings_internal
|
||||
} // namespace absl
|
|
@ -39,6 +39,7 @@
|
|||
#include "absl/strings/str_cat.h"
|
||||
|
||||
#include "absl/strings/internal/numbers_test_common.h"
|
||||
#include "absl/strings/internal/pow10_helper.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -871,7 +872,7 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
|
|||
}
|
||||
|
||||
for (int exponent = -324; exponent <= 308; ++exponent) {
|
||||
double powten = pow(10.0, exponent);
|
||||
double powten = absl::strings_internal::Pow10(exponent);
|
||||
if (powten == 0) powten = 5e-324;
|
||||
if (kFloatNumCases >= 1e9) {
|
||||
// The exhaustive test takes a very long time, so log progress.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue