From 121ffc6fe574cc0df5c77f9010acff970aa89899 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Thu, 19 Sep 2024 16:50:02 +0200 Subject: [PATCH] Adding proposed fix, with tests, resolves #792 --- .../spirit/home/karma/numeric/real_policies.hpp | 16 ++++++++++++++-- test/karma/real3.cpp | 10 ++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/boost/spirit/home/karma/numeric/real_policies.hpp b/include/boost/spirit/home/karma/numeric/real_policies.hpp index a5c7099fba..974e60fb28 100644 --- a/include/boost/spirit/home/karma/numeric/real_policies.hpp +++ b/include/boost/spirit/home/karma/numeric/real_policies.hpp @@ -257,8 +257,20 @@ namespace boost { namespace spirit { namespace karma // generate(sink, right_align(precision, '0')[ulong], n); // but it's spelled out to avoid inter-modular dependencies. - typename remove_const::type digits = - (traits::test_zero(n) ? 1 : ceil(log10(n + T(1.)))); + unsigned int digits=1; //should be number of digits n(truncating any fraction) + if(!boost::spirit::traits::test_zero(n)) { + static constexpr uint64_t limit = UINT64_MAX / 10; + const T num = floor(n); + for (uint64_t x = 10u, i = 1u;; x *= 10, i++) { + if (num < x) { + digits=i;break; + } + if (x > limit) { + digits= i + 1;break; + } + } + } + bool r = true; for (/**/; r && digits < precision_; digits = digits + 1) r = char_inserter<>::call(sink, '0'); diff --git a/test/karma/real3.cpp b/test/karma/real3.cpp index 2b6a014503..ab264388a5 100644 --- a/test/karma/real3.cpp +++ b/test/karma/real3.cpp @@ -198,6 +198,16 @@ int main() )); } + // test for #792: off by a magnitude due to fraction_part + // notice that it applies to all forms of fractions + // that end with a sequence of 0.009999 + { + BOOST_TEST(test("1.09e-06", + double_, + 1.09e-06 + )); + } + return boost::report_errors(); }