Skip to content

Commit

Permalink
Fixed rounding up bug in etl::to_string
Browse files Browse the repository at this point in the history
  • Loading branch information
jwellbelove committed Oct 31, 2019
1 parent 1784561 commit b32cc92
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 1 deletion.
12 changes: 11 additions & 1 deletion include/etl/private/to_string_helper.h
Expand Up @@ -257,10 +257,20 @@ namespace etl
multiplier *= 10U;
}

// Find the integral part of the floating point
T f_integral = (value < T(0.0) ? ceil(value) : floor(value));
int64_t integral = static_cast<int64_t>(f_integral);
int64_t integral = static_cast<int64_t>(f_integral);

// Find the fractional part of the floating point.
int64_t fractional = etl::absolute(static_cast<int64_t>(round((value - f_integral) * multiplier)));

// Check for a rounding carry to the integral.
if (fractional == multiplier)
{
++integral;
fractional = 0;
}

etl::private_to_string::add_integral_fractional(integral, fractional, str, integral_format, fractional_format);
}

Expand Down
17 changes: 17 additions & 0 deletions test/test_to_string.cpp
Expand Up @@ -296,6 +296,23 @@ namespace
CHECK_EQUAL(etl::string<20>(STR("Result -12.345678 ")), etl::to_string(-12.345678, str, Format().precision(6).width(11).left(), true));
}

//*************************************************************************
TEST(test_floating_point_rounding)
{
etl::string<20> str;

CHECK_EQUAL(etl::string<20>(STR("0.00001")), etl::to_string(0.000009, str, Format().precision(5).width(7).right()));
CHECK_EQUAL(etl::string<20>(STR("0.0001")), etl::to_string(0.000099, str, Format().precision(4).width(6).right()));
CHECK_EQUAL(etl::string<20>(STR("0.001")), etl::to_string(0.000999, str, Format().precision(3).width(5).right()));
CHECK_EQUAL(etl::string<20>(STR("0.01")), etl::to_string(0.009999, str, Format().precision(2).width(4).right()));
CHECK_EQUAL(etl::string<20>(STR("0.1")), etl::to_string(0.099999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::string<20>(STR("1.0")), etl::to_string(0.999999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::string<20>(STR("1")), etl::to_string(0.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::string<20>(STR("2")), etl::to_string(1.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::string<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::string<20>(STR("20.0")), etl::to_string(19.999999, str, Format().precision(1).width(4).right()));
}

//*************************************************************************
TEST(test_bool_no_append)
{
Expand Down
17 changes: 17 additions & 0 deletions test/test_to_u16string.cpp
Expand Up @@ -290,6 +290,23 @@ namespace
CHECK_EQUAL(etl::u16string<20>(STR("Result -12.345678 ")), etl::to_string(-12.345678, str, Format().precision(6).width(11).left(), true));
}

//*************************************************************************
TEST(test_floating_point_rounding)
{
etl::u16string<20> str;

CHECK_EQUAL(etl::u16string<20>(STR("0.00001")), etl::to_string(0.000009, str, Format().precision(5).width(7).right()));
CHECK_EQUAL(etl::u16string<20>(STR("0.0001")), etl::to_string(0.000099, str, Format().precision(4).width(6).right()));
CHECK_EQUAL(etl::u16string<20>(STR("0.001")), etl::to_string(0.000999, str, Format().precision(3).width(5).right()));
CHECK_EQUAL(etl::u16string<20>(STR("0.01")), etl::to_string(0.009999, str, Format().precision(2).width(4).right()));
CHECK_EQUAL(etl::u16string<20>(STR("0.1")), etl::to_string(0.099999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::u16string<20>(STR("1.0")), etl::to_string(0.999999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::u16string<20>(STR("1")), etl::to_string(0.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::u16string<20>(STR("2")), etl::to_string(1.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::u16string<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::u16string<20>(STR("20.0")), etl::to_string(19.999999, str, Format().precision(1).width(4).right()));
}

//*************************************************************************
TEST(test_bool_no_append)
{
Expand Down
19 changes: 19 additions & 0 deletions test/test_to_u32string.cpp
Expand Up @@ -293,6 +293,25 @@ namespace
CHECK_EQUAL(etl::u32string<20>(STR("Result -12.345678 ")), etl::to_string(-12.345678, str, Format().precision(6).width(11).left(), true));
}

//*************************************************************************
TEST(test_floating_point_rounding)
{
etl::u32string<20> str;

CHECK_EQUAL(etl::u32string<20>(STR("0.00001")), etl::to_string(0.000009, str, Format().precision(5).width(7).right()));
CHECK_EQUAL(etl::u32string<20>(STR("0.0001")), etl::to_string(0.000099, str, Format().precision(4).width(6).right()));
CHECK_EQUAL(etl::u32string<20>(STR("0.001")), etl::to_string(0.000999, str, Format().precision(3).width(5).right()));
CHECK_EQUAL(etl::u32string<20>(STR("0.01")), etl::to_string(0.009999, str, Format().precision(2).width(4).right()));
CHECK_EQUAL(etl::u32string<20>(STR("0.1")), etl::to_string(0.099999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::u32string<20>(STR("1.0")), etl::to_string(0.999999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::u32string<20>(STR("1")), etl::to_string(0.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::u32string<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::u32string<20>(STR("2")), etl::to_string(1.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::u32string<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::u32string<20>(STR("20.0")), etl::to_string(19.999999, str, Format().precision(1).width(4).right()));

}

//*************************************************************************
TEST(test_bool_no_append)
{
Expand Down
18 changes: 18 additions & 0 deletions test/test_to_wstring.cpp
Expand Up @@ -294,6 +294,24 @@ namespace
CHECK_EQUAL(etl::wstring<20>(STR("Result -12.345678 ")), etl::to_string(-12.345678, str, Format().precision(6).width(11).left(), true));
}

//*************************************************************************
TEST(test_floating_point_rounding)
{
etl::wstring<20> str;

CHECK_EQUAL(etl::wstring<20>(STR("0.00001")), etl::to_string(0.000009, str, Format().precision(5).width(7).right()));
CHECK_EQUAL(etl::wstring<20>(STR("0.0001")), etl::to_string(0.000099, str, Format().precision(4).width(6).right()));
CHECK_EQUAL(etl::wstring<20>(STR("0.001")), etl::to_string(0.000999, str, Format().precision(3).width(5).right()));
CHECK_EQUAL(etl::wstring<20>(STR("0.01")), etl::to_string(0.009999, str, Format().precision(2).width(4).right()));
CHECK_EQUAL(etl::wstring<20>(STR("0.1")), etl::to_string(0.099999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::wstring<20>(STR("1.0")), etl::to_string(0.999999, str, Format().precision(1).width(3).right()));
CHECK_EQUAL(etl::wstring<20>(STR("1")), etl::to_string(0.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::wstring<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::wstring<20>(STR("2")), etl::to_string(1.999999, str, Format().precision(0).width(1).right()));
CHECK_EQUAL(etl::wstring<20>(STR("10.0")), etl::to_string(9.999999, str, Format().precision(1).width(4).right()));
CHECK_EQUAL(etl::wstring<20>(STR("20.0")), etl::to_string(19.999999, str, Format().precision(1).width(4).right()));
}

//*************************************************************************
TEST(test_bool_no_append)
{
Expand Down
1 change: 1 addition & 0 deletions test/vs2017/Debug No Unit Tests/etl.tlog/.gitignore
@@ -0,0 +1 @@
*.1.tlog

0 comments on commit b32cc92

Please sign in to comment.