tfussell / xlnt

:bar_chart: Cross-platform user-friendly xlsx library for C++11+
Other
1.49k stars 418 forks source link

incorrect rounding #625

Open ov opened 2 years ago

ov commented 2 years ago

I got a problem with rounding 135.345 to two decimals: it becomes 135.34 instead of 135.35. I traced it down to this code in number_formatter.cpp:

    else if (p.type == format_placeholders::placeholders_type::fractional_part)
    {
        auto fractional_part = number - integer_part;
        result = std::fabs(fractional_part) < std::numeric_limits<double>::min()
            ? std::string(".")
            : serialiser_.serialise_short(fractional_part).substr(1);

The problem is with the fractional_part which is 135.345 - 135 = 0.344999999999, which then gets rounded to 0.34 which is correct for that number, but not for the original one.

I'd change it this way:

if (std::fabs(fractional_part) < std::numeric_limits<double>::min())
{
    result = std::string(".");
}
else
{
    result = serialiser_.serialise_short(fractional_part);
    result = result.substr(result.find('.'));
}

so the whole number is formatted and then the integer part is removed.