]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/multiprecision/traits/max_digits10.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / multiprecision / traits / max_digits10.hpp
index 1b2db5ecc426760576cde4c79e770fbcc3205b42..24a2cc4b26632e50a7685a55d8910aca5891df4f 100644 (file)
@@ -13,7 +13,6 @@ namespace detail {
 template <unsigned digits>
 struct calc_max_digits10
 {
-#ifndef BOOST_NO_CXX11_CONSTEXPR
    static constexpr unsigned max_digits_10(unsigned d)
    {
       //
@@ -25,20 +24,29 @@ struct calc_max_digits10
       //
       return static_cast<unsigned>(0.301029995663981195213738894724493026768189881462108541310 * d) + 2;
    }
-   static const unsigned value = max_digits_10(digits);
-#else
-   //
-   // This version works up to about 15K binary digits, then starts sporadically failing
-   // and giving values that are 1 too small.
-   //
-   BOOST_STATIC_CONSTANT(unsigned, value = 2 + ((static_cast<boost::uint64_t>(digits) * static_cast<boost::uint64_t>(1292913986)) >> 32));
-#endif
+   static constexpr const unsigned value = max_digits_10(digits);
+};
+
+template <std::size_t digits>
+struct calc_max_digits10_s
+{
+   static constexpr std::size_t max_digits_10(std::size_t d)
+   {
+      //
+      // We need ceil(log10(2) * d) + 1 decimal places to
+      // guarantee round tripping, see: https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/
+      // and references therein.  Since log10(2) is irrational, then d*log10(2) will
+      // never be exactly an integer so we can replace by trunc(log10(2) * d) + 2
+      // and avoid the call to ceil:
+      //
+      return static_cast<std::size_t>(0.301029995663981195213738894724493026768189881462108541310 * d) + 2;
+   }
+   static constexpr const std::size_t value = max_digits_10(digits);
 };
 
 template <unsigned digits>
 struct calc_digits10
 {
-#ifndef BOOST_NO_CXX11_CONSTEXPR
    static constexpr unsigned digits_10(unsigned d)
    {
       //
@@ -48,10 +56,22 @@ struct calc_digits10
       //
       return static_cast<unsigned>(0.301029995663981195213738894724493026768189881462108541310 * (d - 1));
    }
-   static const unsigned value = digits_10(digits);
-#else
-   BOOST_STATIC_CONSTANT(unsigned, value = ((static_cast<boost::uint64_t>(digits - 1) * static_cast<boost::uint64_t>(1292913986)) >> 32));
-#endif
+   static constexpr const unsigned value = digits_10(digits);
+};
+
+template <std::size_t digits>
+struct calc_digits10_s
+{
+   static constexpr std::size_t digits_10(std::size_t d)
+   {
+      //
+      // We need floor(log10(2) * (d-1)), see: 
+      // https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/
+      // and references therein.
+      //
+      return static_cast<std::size_t>(0.301029995663981195213738894724493026768189881462108541310 * (d - 1));
+   }
+   static constexpr const std::size_t value = digits_10(digits);
 };
 
 }}} // namespace boost::multiprecision::detail