From 1ce8615345a0167b8307b6390950dcd91aa2abc8 Mon Sep 17 00:00:00 2001 From: zhenyipeng Date: Thu, 1 Aug 2019 12:02:08 +0800 Subject: [PATCH] Add min exponent width option in double-to-string shortest conversion --- double-conversion/double-to-string.cc | 5 +++++ double-conversion/double-to-string.h | 7 +++++-- test/cctest/test-conversions.cc | 30 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/double-conversion/double-to-string.cc b/double-conversion/double-to-string.cc index 13c7110..e708097 100644 --- a/double-conversion/double-to-string.cc +++ b/double-conversion/double-to-string.cc @@ -105,6 +105,11 @@ void DoubleToStringConverter::CreateExponentialRepresentation( buffer[--first_char_pos] = '0' + (exponent % 10); exponent /= 10; } + // Add prefix '0' to make exponent width >= min(min_exponent_with_, kMaxExponentLength) + // For example: convert 1e+9 -> 1e+09, if min_exponent_with_ is set to 2 + while(kMaxExponentLength - first_char_pos < std::min(min_exponent_width_, kMaxExponentLength)) { + buffer[--first_char_pos] = '0'; + } result_builder->AddSubstring(&buffer[first_char_pos], kMaxExponentLength - first_char_pos); } diff --git a/double-conversion/double-to-string.h b/double-conversion/double-to-string.h index c1be34d..194f80b 100644 --- a/double-conversion/double-to-string.h +++ b/double-conversion/double-to-string.h @@ -111,7 +111,8 @@ class DoubleToStringConverter { int decimal_in_shortest_low, int decimal_in_shortest_high, int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode) + int max_trailing_padding_zeroes_in_precision_mode, + int min_exponent_width = 0) : flags_(flags), infinity_symbol_(infinity_symbol), nan_symbol_(nan_symbol), @@ -121,7 +122,8 @@ class DoubleToStringConverter { max_leading_padding_zeroes_in_precision_mode_( max_leading_padding_zeroes_in_precision_mode), max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode) { + max_trailing_padding_zeroes_in_precision_mode), + min_exponent_width_(min_exponent_width) { // When 'trailing zero after the point' is set, then 'trailing point' // must be set too. DOUBLE_CONVERSION_ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || @@ -378,6 +380,7 @@ class DoubleToStringConverter { const int decimal_in_shortest_high_; const int max_leading_padding_zeroes_in_precision_mode_; const int max_trailing_padding_zeroes_in_precision_mode_; + const int min_exponent_width_; DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); }; diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc index 397d8b3..0753489 100644 --- a/test/cctest/test-conversions.cc +++ b/test/cctest/test-conversions.cc @@ -71,6 +71,36 @@ TEST(DoubleToShortest) { CHECK(dc.ToShortest(-0.0, &builder)); CHECK_EQ("0", builder.Finalize()); + // Exponent min width test + flags = DoubleToStringConverter::UNIQUE_ZERO | + DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; + DoubleToStringConverter dcExpWidth(flags, NULL, NULL, 'e', -4, 6, 0, 0, 2); + builder.Reset(); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(11111111111.0, &builder)); + CHECK_EQ("1.1111111111e+10", builder.Finalize()); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(1111111111.0, &builder)); + CHECK_EQ("1.111111111e+09", builder.Finalize()); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(1111111.0, &builder)); + CHECK_EQ("1.111111e+06", builder.Finalize()); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(111111.0, &builder)); + CHECK_EQ("111111", builder.Finalize()); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(10000000000.0, &builder)); + CHECK_EQ("1e+10", builder.Finalize()); + + builder.Reset(); + CHECK(dcExpWidth.ToShortest(1000000000.0, &builder)); + CHECK_EQ("1e+09", builder.Finalize()); + flags = DoubleToStringConverter::NO_FLAGS; DoubleToStringConverter dc2(flags, NULL, NULL, 'e', -1, 1, 0, 0); builder.Reset();