diff options
author | Benjamin Barenblat <bbaren@google.com> | 2021-04-27 10:22:00 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@google.com> | 2021-06-01 14:28:49 -0400 |
commit | ebc3d7213cf73b26b5e44edff58c759ea44ee9aa (patch) | |
tree | 268965c54acf3d25a653a09c22666ebe42c9fb9b /debian | |
parent | 5b48955810e393a365858fd62cd9d21d73b36966 (diff) |
Add patch to correct floating-point rounding
Diffstat (limited to 'debian')
-rw-r--r-- | debian/patches/float-rounding.diff | 46 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 47 insertions, 0 deletions
diff --git a/debian/patches/float-rounding.diff b/debian/patches/float-rounding.diff new file mode 100644 index 00000000..005e08be --- /dev/null +++ b/debian/patches/float-rounding.diff @@ -0,0 +1,46 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Round floats using round(x), not static_cast<int>(x + 0.5) +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/d96e287417766deddbff2d01b96321288c59491e + +Adding 0.5 to an IEEE float may cause one bit of precision loss, which +is enough to change the result in certain cases. For example, + + static_cast<int>(std::round(0.49999999999999994)) == 0 + static_cast<int>(0.49999999999999994 + 0.5) == 1 + +The author works at Google. Upstream applied this patch as Piper +revision 369926519 and exported it to GitHub; the Applied-Upstream URL +above points to the exported commit. + +--- a/absl/time/duration_test.cc ++++ b/absl/time/duration_test.cc +@@ -1320,7 +1320,7 @@ TEST(Duration, SmallConversions) { + + EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0)); + // TODO(bww): Is the next one OK? +- EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0.124999999e-9)); ++ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(std::nextafter(0.125e-9, 0))); + EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.125e-9)); + EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.250e-9)); + EXPECT_EQ(absl::Nanoseconds(1) / 2, absl::Seconds(0.375e-9)); +@@ -1330,7 +1330,7 @@ TEST(Duration, SmallConversions) { + EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(0.875e-9)); + EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(1.000e-9)); + +- EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(-0.124999999e-9)); ++ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(std::nextafter(-0.125e-9, 0))); + EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.125e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.250e-9)); + EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.375e-9)); +--- a/absl/time/time.h ++++ b/absl/time/time.h +@@ -1352,7 +1352,7 @@ + inline Duration MakePosDoubleDuration(double n) { + const int64_t int_secs = static_cast<int64_t>(n); + const uint32_t ticks = static_cast<uint32_t>( +- (n - static_cast<double>(int_secs)) * kTicksPerSecond + 0.5); ++ std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); + return ticks < kTicksPerSecond + ? MakeDuration(int_secs, ticks) + : MakeDuration(int_secs + 1, ticks - kTicksPerSecond); diff --git a/debian/patches/series b/debian/patches/series index e963b998..4e55e401 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,3 +3,4 @@ std-hash.diff latomic.diff cordrepring-typo.diff thumb-function-bounds.diff +float-rounding.diff |