tdf#96918 display accurate integer double values up to (2^53)-1

Change-Id: I42001583c72bc3faab94489a4eabfa183cab5ae2
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index be8ebbe..45d07b7 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -207,6 +207,73 @@ inline void doubleToString(StringT ** pResult,
        return;
    }

    // Use integer representation for integer values that fit into the
    // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy.
    const sal_Int64 kMaxInt = (static_cast<sal_Int64>(1) << 53) - 1;
    if ((eFormat == rtl_math_StringFormat_Automatic ||
         eFormat == rtl_math_StringFormat_F) && fValue <= static_cast<double>(kMaxInt))
    {
        sal_Int64 nInt = static_cast<sal_Int64>(fValue);
        // Check the integer range again because double comparison may yield
        // true within the precision range.
        if (nInt <= kMaxInt && static_cast<double>(nInt) == fValue)
        {
            if (nDecPlaces == rtl_math_DecimalPlaces_Max || bEraseTrailingDecZeros)
                nDecPlaces = 0;
            else
                nDecPlaces = ::std::min( nDecPlaces, 15);

            // Max 1 sign, 16 integer digits, 15 group separators, 1 decimal
            // separator, 15 decimals digits.
            typename T::Char aBuf[64];
            typename T::Char * pBuf = aBuf;
            typename T::Char * p = pBuf;

            // Backward fill.
            size_t nGrouping = 0;
            sal_Int32 nGroupDigits = 0;
            do
            {
                typename T::Char nDigit = nInt % 10;
                nInt /= 10;
                *p++ = nDigit + '0';
                if (pGroups && pGroups[nGrouping] == ++nGroupDigits && nInt > 0 && cGroupSeparator)
                {
                    *p++ = cGroupSeparator;
                    if (pGroups[nGrouping+1])
                        ++nGrouping;
                    nGroupDigits = 0;
                }
            }
            while (nInt > 0);
            if (bSign)
                *p++ = '-';

            // Reverse buffer content.
            sal_Int32 n = (p - pBuf) / 2;
            for (sal_Int32 i=0; i < n; ++i)
            {
                typename T::Char c = p[-i-1];
                p[-i-1] = pBuf[i];
                pBuf[i] = c;
            }
            // Append decimals.
            if (nDecPlaces)
            {
                *p++ = cDecSeparator;
                while (nDecPlaces--)
                    *p++ = '0';
            }

            if (pResultCapacity == nullptr)
                T::createString(pResult, pBuf, p - pBuf);
            else
                T::appendChars(pResult, pResultCapacity, &nResultOffset, pBuf, p - pBuf);

            return;
        }
    }

    // find the exponent
    int nExp = 0;
    if ( fValue > 0.0 )