Implement general notation for non-integer results

This commit is contained in:
Matt Borland
2023-03-27 16:16:54 +02:00
parent 3b186a9c6b
commit 5563d760ef
2 changed files with 26 additions and 5 deletions

View File

@@ -22,6 +22,7 @@
#define BOOST_CHARCONV_DETAIL_FLOFF
#include <boost/charconv/detail/config.hpp>
#include <boost/charconv/chars_format.hpp>
#include <type_traits>
#include <limits>
#include <cassert>
@@ -2294,7 +2295,8 @@ namespace jkj { namespace floff {
// precision means the number of decimal significand digits minus 1.
// Assumes round-to-nearest, tie-to-even rounding.
template <class MainCache = main_cache_full, class ExtendedCache>
JKJ_SAFEBUFFERS char* floff(double const x, int const precision, char* buffer) noexcept {
JKJ_SAFEBUFFERS char* floff(double const x, int const precision, char* buffer, boost::charconv::chars_format fmt) noexcept
{
assert(precision >= 0);
using namespace detail;
@@ -4562,14 +4564,28 @@ case n:
/////////////////////////////////////////////////////////////////////////////////////////////////
fill_remaining_digits_with_0s:
std::memset(buffer, '0', remaining_digits);
buffer += remaining_digits;
if (fmt != boost::charconv::chars_format::general)
{
std::memset(buffer, '0', remaining_digits);
buffer += remaining_digits;
}
insert_decimal_dot:
buffer_starting_pos[0] = buffer_starting_pos[1];
buffer_starting_pos[1] = '.';
print_exponent_and_return:
if (fmt == boost::charconv::chars_format::general)
{
--buffer;
while (*buffer == '0')
{
--buffer;
}
++buffer;
}
if (decimal_exponent >= 0) {
std::memcpy(buffer, "e+", 2);
}

View File

@@ -290,7 +290,12 @@ boost::charconv::to_chars_result boost::charconv::to_chars( char* first, char* l
boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* last, double value, boost::charconv::chars_format fmt, int precision) noexcept
{
if (fmt == boost::charconv::chars_format::scientific)
if (fmt == boost::charconv::chars_format::general)
{
auto* ptr = jkj::floff::floff<jkj::floff::main_cache_full, jkj::floff::extended_cache_long>(value, std::numeric_limits<double>::max_digits10 - 1, first, fmt);
return { ptr, 0 };
}
else if (fmt == boost::charconv::chars_format::scientific)
{
if (precision == -1)
{
@@ -300,7 +305,7 @@ boost::charconv::to_chars_result boost::charconv::to_chars(char* first, char* la
{
return { first, EOVERFLOW };
}
auto* ptr = jkj::floff::floff<jkj::floff::main_cache_full, jkj::floff::extended_cache_long>(value, precision, first);
auto* ptr = jkj::floff::floff<jkj::floff::main_cache_full, jkj::floff::extended_cache_long>(value, precision, first, fmt);
return { ptr, 0 };
}
else