diff options
-rw-r--r-- | Makefile.fetch | 1 | ||||
-rw-r--r-- | RepositoryExternal.mk | 9 | ||||
-rw-r--r-- | download.lst | 2 | ||||
-rw-r--r-- | external/Module_external.mk | 1 | ||||
-rw-r--r-- | external/dragonbox/Module_dragonbox.mk | 16 | ||||
-rw-r--r-- | external/dragonbox/README | 4 | ||||
-rw-r--r-- | external/dragonbox/UnpackedTarball_dragonbox.mk | 14 | ||||
-rw-r--r-- | readlicense_oo/license/license.xml | 21 | ||||
-rw-r--r-- | sal/Library_sal.mk | 1 | ||||
-rw-r--r-- | sal/qa/rtl/math/test-rtl-math.cxx | 13 | ||||
-rw-r--r-- | sal/rtl/math.cxx | 288 | ||||
-rw-r--r-- | sd/qa/unit/export-tests-ooxml2.cxx | 2 |
12 files changed, 146 insertions, 226 deletions
diff --git a/Makefile.fetch b/Makefile.fetch index 78ff78b9e312..af6f0ce7aa5f 100644 --- a/Makefile.fetch +++ b/Makefile.fetch @@ -110,6 +110,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S $(call fetch_Optional,CAIRO,PIXMAN_TARBALL) \ $(call fetch_Optional,CDR,CDR_TARBALL) \ $(call fetch_Optional,CLUCENE,CLUCENE_TARBALL) \ + DRAGONBOX_TARBALL \ DTOA_TARBALL \ $(call fetch_Optional,LIBCMIS,LIBCMIS_TARBALL) \ $(call fetch_Optional,COINMP,COINMP_TARBALL) \ diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 2e7e86266e34..779e318ebc49 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -4132,6 +4132,15 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo,\ )) endif +define gb_LinkTarget__use_dragonbox +$(call gb_LinkTarget_use_unpacked,$(1),dragonbox) +$(call gb_LinkTarget_set_include,$(1),\ + -I$(call gb_UnpackedTarball_get_dir,dragonbox/include/)\ + $$(INCLUDE) \ +) + +endef + define gb_LinkTarget__use_dtoa $(call gb_LinkTarget_use_unpacked,$(1),dtoa) $(call gb_LinkTarget_set_include,$(1),\ diff --git a/download.lst b/download.lst index 33842d7282ee..bb4d12649d8f 100644 --- a/download.lst +++ b/download.lst @@ -23,6 +23,8 @@ export CDR_SHA256SUM := 5666249d613466b9aa1e987ea4109c04365866e9277d80f6cd9663e8 export CDR_TARBALL := libcdr-0.1.7.tar.xz export CLUCENE_SHA256SUM := ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8c51d79732eab export CLUCENE_TARBALL := 48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz +export DRAGONBOX_SHA256SUM := 293247ccba995ec47ae3abb52c3e83904a7d71efb7093d4c0d2c6367c1cc1e20 +export DRAGONBOX_TARBALL := dragonbox-1.1.0.tar.gz export DTOA_SHA256SUM := 0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4 export DTOA_TARBALL := dtoa-20180411.tgz export LIBCMIS_SHA256SUM := d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2 diff --git a/external/Module_external.mk b/external/Module_external.mk index 946b9dd16ed7..5420092797a1 100644 --- a/external/Module_external.mk +++ b/external/Module_external.mk @@ -30,6 +30,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\ $(call gb_Helper_optional,CPPUNIT,cppunit) \ $(call gb_Helper_optional,CT2N,ct2n) \ $(call gb_Helper_optional,CURL,curl) \ + dragonbox \ dtoa \ $(call gb_Helper_optional,EBOOK,libebook) \ $(call gb_Helper_optional,EPM,epm) \ diff --git a/external/dragonbox/Module_dragonbox.mk b/external/dragonbox/Module_dragonbox.mk new file mode 100644 index 000000000000..2ed608f1e5e8 --- /dev/null +++ b/external/dragonbox/Module_dragonbox.mk @@ -0,0 +1,16 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Module_Module,dragonbox)) + +$(eval $(call gb_Module_add_targets,dragonbox,\ + UnpackedTarball_dragonbox \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/external/dragonbox/README b/external/dragonbox/README new file mode 100644 index 000000000000..28db2711b9e4 --- /dev/null +++ b/external/dragonbox/README @@ -0,0 +1,4 @@ +Dragonbox is available from [ https://github.com/jk-jeon/dragonbox ]. + +Used to convert a double to a decimal string, providing breakout of significand and exponent +as integers, allowing to create custom number representation (e.g., locale-specific). diff --git a/external/dragonbox/UnpackedTarball_dragonbox.mk b/external/dragonbox/UnpackedTarball_dragonbox.mk new file mode 100644 index 000000000000..c483f19a3c56 --- /dev/null +++ b/external/dragonbox/UnpackedTarball_dragonbox.mk @@ -0,0 +1,14 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_UnpackedTarball_UnpackedTarball,dragonbox)) + +$(eval $(call gb_UnpackedTarball_set_tarball,dragonbox,$(DRAGONBOX_TARBALL))) + +# vim: set noet sw=4 ts=4: diff --git a/readlicense_oo/license/license.xml b/readlicense_oo/license/license.xml index 56b36c71fa02..f0a2484b8acb 100644 --- a/readlicense_oo/license/license.xml +++ b/readlicense_oo/license/license.xml @@ -1844,6 +1844,27 @@ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</p> </div> + <h2>Dragonbox</h2> + <p>The following software may be included in this product: Dragonbox.</p> + <p>Dragonbox code is covered by the following license:</p> + <p><a href="#a__Apache_License_version_2_0">Jump to Apache License Version 2.0</a></p> + <blockquote> + <p>--- LLVM Exceptions to the Apache 2.0 License ----</p> + + <p>As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into an Object form of such source code, you + may redistribute such embedded portions in such Object form without complying + with the conditions of Sections 4(a), 4(b) and 4(d) of the License.</p> + + <p>In addition, if you combine or link compiled forms of this Software with + software that is licensed under the GPLv2 ("Combined Software") and if a + court of competent jurisdiction determines that the patent provision (Section + 3), the indemnity provision (Section 9) or other Section of the License + conflicts with the conditions of the GPLv2, you may retroactively and + prospectively choose to deem waived or otherwise exclude such Section(s) of + the License, but only in their entirety and only with respect to the Combined + Software.</p> + </blockquote> <h2>dtoa</h2> <p>The following software may be included in this product: dtoa.</p> <p>dtoa code is covered by the MIT license:</p> diff --git a/sal/Library_sal.mk b/sal/Library_sal.mk index d8d409195a39..aae7c97f0310 100644 --- a/sal/Library_sal.mk +++ b/sal/Library_sal.mk @@ -43,6 +43,7 @@ $(eval $(call gb_Library_use_libraries,sal,\ )) $(eval $(call gb_Library_use_externals,sal,\ + dragonbox \ dtoa \ valgrind \ zlib \ diff --git a/sal/qa/rtl/math/test-rtl-math.cxx b/sal/qa/rtl/math/test-rtl-math.cxx index aaadccc8e97c..94840dbdb7e8 100644 --- a/sal/qa/rtl/math/test-rtl-math.cxx +++ b/sal/qa/rtl/math/test-rtl-math.cxx @@ -432,7 +432,8 @@ public: fVal = std::nextafter( fVal, 0); aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true); - CPPUNIT_ASSERT_EQUAL( OUString("1.7976931348623149E+308"), aRes); + CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862315E+308"), aRes); + CPPUNIT_ASSERT_EQUAL(fVal, rtl::math::stringToDouble(aRes, '.', ',')); // Test roundtrip // DBL_MAX and 4 nextafters rounded to 15 decimals fVal = DBL_MAX; @@ -463,24 +464,20 @@ public: // DBL_MAX rounded to 2 decimals fVal = DBL_MAX; aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 2, '.', true); - CPPUNIT_ASSERT_EQUAL( OUString("1.80E+308"), aRes); + CPPUNIT_ASSERT_EQUAL( OUString("1.8E+308"), aRes); // Crashed after commit eae24a9488814e77254d175c11fc4a138c1dbd30 fVal = 123456.789; aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_E, 2, '.', false); CPPUNIT_ASSERT_EQUAL(OUString("1.23E+005"), aRes); - // Testing "after-treatment of up-rounding to the next decade" branch - // See void doubleToString in sal/rtl/math.cxx - // 1. Yet empty buffer fVal = 9.9999999999999929; aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true); - CPPUNIT_ASSERT_EQUAL(OUString("10"), aRes); + CPPUNIT_ASSERT_EQUAL(OUString("9.99999999999999"), aRes); - // 2. Buffer with some content fVal = 0.99999999999999933; aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_F, rtl_math_DecimalPlaces_Max, '.', true); - CPPUNIT_ASSERT_EQUAL(OUString("1"), aRes); + CPPUNIT_ASSERT_EQUAL(OUString("0.999999999999999"), aRes); } void test_approx() { diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx index bec83c380b32..edb894cb7820 100644 --- a/sal/rtl/math.cxx +++ b/sal/rtl/math.cxx @@ -19,6 +19,7 @@ #include <rtl/math.h> +#include <o3tl/safeint.hxx> #include <osl/diagnose.h> #include <rtl/character.hxx> #include <rtl/math.hxx> @@ -34,6 +35,7 @@ #include <memory> #include <stdlib.h> +#include <dragonbox/dragonbox.h> #include <dtoa.h> constexpr int minExp = -323, maxExp = 308; @@ -104,11 +106,6 @@ static double getN10Exp(int nExp) namespace { -double const nCorrVal[] = { - 0, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, 9e-8, - 9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14, 9e-15 -}; - struct StringTraits { typedef char Char; @@ -245,6 +242,38 @@ int getBitsInFracPart(double fAbsValue) return std::max(nBitsInFracPart, 0); } +constexpr sal_uInt64 eX[] = { 10ull, + 100ull, + 1000ull, + 10000ull, + 100000ull, + 1000000ull, + 10000000ull, + 100000000ull, + 1000000000ull, + 10000000000ull, + 100000000000ull, + 1000000000000ull, + 10000000000000ull, + 100000000000000ull, + 1000000000000000ull, + 10000000000000000ull, + 100000000000000000ull, + 1000000000000000000ull, + 10000000000000000000ull }; + +int decimalDigits(sal_uInt64 n) +{ + return std::distance(std::begin(eX), std::upper_bound(std::begin(eX), std::end(eX), n)) + 1; +} + +sal_uInt64 roundToPow10(sal_uInt64 n, int e) +{ + assert(e > 0 && o3tl::make_unsigned(e) <= std::size(eX)); + const sal_uInt64 d = eX[e - 1]; + return (n + d / 2) / d * d; +} + template< typename T > void doubleToString(typename T::String ** pResult, sal_Int32 * pResultCapacity, sal_Int32 nResultOffset, @@ -254,18 +283,6 @@ void doubleToString(typename T::String ** pResult, typename T::Char cGroupSeparator, bool bEraseTrailingDecZeros) { - static double const nRoundVal[] = { - 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, - 0.5e-7, 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14 - }; - - // sign adjustment, instead of testing for fValue<0.0 this will also fetch - // -0.0 - bool bSign = std::signbit(fValue); - - if (bSign) - fValue = -fValue; - if (std::isnan(fValue)) { // #i112652# XMLSchema-2 @@ -283,8 +300,7 @@ void doubleToString(typename T::String ** pResult, return; } - bool bHuge = fValue == HUGE_VAL; // g++ 3.0.1 requires it this way... - if (bHuge || std::isinf(fValue)) + if (std::isinf(fValue)) { // #i112652# XMLSchema-2 sal_Int32 nCapacity = RTL_CONSTASCII_LENGTH("-INF"); @@ -295,7 +311,7 @@ void doubleToString(typename T::String ** pResult, nResultOffset = 0; } - if ( bSign ) + if (std::signbit(fValue)) T::appendAscii(pResult, pResultCapacity, &nResultOffset, RTL_CONSTASCII_STRINGPARAM("-")); @@ -305,6 +321,18 @@ void doubleToString(typename T::String ** pResult, return; } + decltype(jkj::dragonbox::to_decimal(fValue)) aParts{}; + if (fValue) // to_decimal is documented to only handle non-zero finite numbers + aParts = jkj::dragonbox::to_decimal(fValue); + else + aParts.is_negative = std::signbit(fValue); // Handle -0.0 + + int nOrigDigits = decimalDigits(aParts.significand); + int nExp = nOrigDigits + aParts.exponent - 1; + int nRoundDigits = 15; + if (aParts.is_negative) + fValue = -fValue; + // Unfortunately the old rounding below writes 1.79769313486232e+308 for // DBL_MAX and 4 subsequent nextafter(...,0). static const double fB1 = std::nextafter( DBL_MAX, 0); @@ -318,77 +346,17 @@ void doubleToString(typename T::String ** pResult, // they exceed range they should not be written to exchange strings or // file formats. - // Writing pDig up to decimals(-1,-2) then appending one digit from - // pRou xor one or two digits from pSlot[]. - constexpr char pDig[] = "7976931348623157"; - constexpr char pRou[] = "8087931359623267"; // the only up-carry is 80 - static_assert(SAL_N_ELEMENTS(pDig) == SAL_N_ELEMENTS(pRou), "digit count mismatch"); - constexpr sal_Int32 nDig2 = RTL_CONSTASCII_LENGTH(pRou) - 2; - sal_Int32 nCapacity = RTL_CONSTASCII_LENGTH(pRou) + 8; // + "-1.E+308" - const char pSlot[5][2][3] = - { // rounded, not - "67", "57", // DBL_MAX - "65", "55", - "53", "53", - "51", "51", - "59", "49", - }; - - if (!pResultCapacity) - { - pResultCapacity = &nCapacity; - T::createBuffer(pResult, pResultCapacity); - nResultOffset = 0; - } - - if (bSign) - T::appendAscii(pResult, pResultCapacity, &nResultOffset, - RTL_CONSTASCII_STRINGPARAM("-")); - - nDecPlaces = std::clamp<sal_Int32>( nDecPlaces, 0, RTL_CONSTASCII_LENGTH(pRou)); - if (nDecPlaces == 0) - { - T::appendAscii(pResult, pResultCapacity, &nResultOffset, - RTL_CONSTASCII_STRINGPARAM("2")); - } - else - { - T::appendAscii(pResult, pResultCapacity, &nResultOffset, - RTL_CONSTASCII_STRINGPARAM("1")); - T::appendChars(pResult, pResultCapacity, &nResultOffset, &cDecSeparator, 1); - if (nDecPlaces <= 2) - { - T::appendAscii(pResult, pResultCapacity, &nResultOffset, pRou, nDecPlaces); - } - else if (nDecPlaces <= nDig2) - { - T::appendAscii(pResult, pResultCapacity, &nResultOffset, pDig, nDecPlaces - 1); - T::appendAscii(pResult, pResultCapacity, &nResultOffset, pRou + nDecPlaces - 1, 1); - } - else - { - const sal_Int32 nDec = nDecPlaces - nDig2; - nDecPlaces -= nDec; - // nDec-1 is also offset into slot, rounded(1-1=0) or not(2-1=1) - const size_t nSlot = ((fValue < fB3) ? 4 : ((fValue < fB2) ? 3 - : ((fValue < fB1) ? 2 : ((fValue < DBL_MAX) ? 1 : 0)))); - - T::appendAscii(pResult, pResultCapacity, &nResultOffset, pDig, nDecPlaces); - T::appendAscii(pResult, pResultCapacity, &nResultOffset, pSlot[nSlot][nDec-1], nDec); - } - } - T::appendAscii(pResult, pResultCapacity, &nResultOffset, - RTL_CONSTASCII_STRINGPARAM("E+308")); - - return; + eFormat = rtl_math_StringFormat_E; + nDecPlaces = std::clamp<sal_Int32>( nDecPlaces, 0, 16); + nRoundDigits = 17; } // Use integer representation for integer values that fit into the // mantissa (1.((2^53)-1)) with a precision of 1 for highest accuracy. if ((eFormat == rtl_math_StringFormat_Automatic || - eFormat == rtl_math_StringFormat_F) && isRepresentableInteger(fValue)) + eFormat == rtl_math_StringFormat_F) && aParts.exponent >= 0 && fValue < 0x1p53) { - sal_Int64 nInt = static_cast< sal_Int64 >(fValue); + eFormat = rtl_math_StringFormat_F; if (nDecPlaces == rtl_math_DecimalPlaces_Max) nDecPlaces = 0; else @@ -397,68 +365,7 @@ void doubleToString(typename T::String ** pResult, if (bEraseTrailingDecZeros && nDecPlaces > 0) nDecPlaces = 0; - // Round before decimal position. - if (nDecPlaces < 0) - { - sal_Int64 nRounding = static_cast< sal_Int64 >(getN10Exp(-nDecPlaces - 1)); - const sal_Int64 nTemp = (nInt / nRounding + 5) / 10; - nInt = nTemp * 10 * nRounding; - } - - // Max 1 sign, 16 integer digits, 15 group separators, 1 decimal - // separator, 15 decimals digits. - typename T::Char aBuf[64]; - typename T::Char* pEnd = aBuf + 40; - typename T::Char* pStart = pEnd; - - // Backward fill. - sal_Int32 nGrouping = cGroupSeparator && pGroups ? *pGroups : 0; - sal_Int32 nGroupDigits = 0; - do - { - typename T::Char nDigit = nInt % 10; - nInt /= 10; - *--pStart = nDigit + '0'; - if (nGrouping && nGrouping == ++nGroupDigits && nInt) - { - *--pStart = cGroupSeparator; - if (*(pGroups + 1)) - nGrouping = *++pGroups; - nGroupDigits = 0; - } - } - while (nInt); - if (bSign) - *--pStart = '-'; - - // Append decimals. - if (nDecPlaces > 0) - { - *pEnd++ = cDecSeparator; - pEnd = std::fill_n(pEnd, nDecPlaces, '0'); - } - - if (!pResultCapacity) - T::createString(pResult, pStart, pEnd - pStart); - else - T::appendChars(pResult, pResultCapacity, &nResultOffset, pStart, pEnd - pStart); - - return; - } - - // find the exponent - int nExp = 0; - if ( fValue > 0.0 ) - { - // Cap nExp at a small value beyond which "fValue /= N10Exp" would lose precision (or N10Exp - // might even be zero); that will produce output with the decimal point in a non-normalized - // position, but the current quality of output for such small values is probably abysmal, - // anyway: - nExp = std::max( - static_cast< int >(floor(log10(fValue))), std::numeric_limits<double>::min_exponent10); - double const N10Exp = getN10Exp(nExp); - assert(N10Exp != 0); - fValue /= N10Exp; + nRoundDigits = nOrigDigits; // no rounding } switch (eFormat) @@ -531,12 +438,14 @@ void doubleToString(typename T::String ** pResult, nDigits += nExp; // Round the number - if(nDigits >= 0) + nRoundDigits = std::min<int>(nDigits, nRoundDigits); + if(nDigits >= 0 && nOrigDigits > nRoundDigits) { - fValue += nRoundVal[std::min<sal_Int32>(nDigits, 15)]; - if (fValue >= 10) + aParts.significand = roundToPow10(aParts.significand, nOrigDigits - nRoundDigits); + assert(aParts.significand <= eX[nOrigDigits - 1]); + if (aParts.significand == eX[nOrigDigits - 1]) // up-rounding to the next decade { - fValue = 1.0; + nOrigDigits++; nExp++; if (eFormat == rtl_math_StringFormat_F) @@ -552,7 +461,7 @@ void doubleToString(typename T::String ** pResult, assert(nBuf <= 1024); typename T::Char* pBuf = static_cast<typename T::Char*>(alloca(nBuf * sizeof(typename T::Char))); typename T::Char * p = pBuf; - if ( bSign ) + if (aParts.is_negative) *p++ = '-'; bool bHasDec = false; @@ -612,77 +521,22 @@ void doubleToString(typename T::String ** pResult, // print the number if (nDigits > 0) { - for (int i = 0; ; i++) + for (int nCurExp = nOrigDigits - 1;;) { - if (i < 15) // was 16 in ancient versions, which leads to inaccuracies + int nDigit; + if (aParts.significand > 0 && nCurExp > 0) { - int nDigit; - if (nDigits-1 == 0 && i > 0 && i < 14) - nDigit = floor( fValue + nCorrVal[15-i]); - else - nDigit = fValue + 1E-15; - - if (nDigit >= 10) - { // after-treatment of up-rounding to the next decade - typename T::Char* p1 = pBuf; - // Assert that no one changed the logic we rely on. - assert(!bSign || *p1 == '-'); - // Do not touch leading minus sign put earlier. - if (bSign) - ++p1; - assert(p1 <= p); - if (p1 == p) - { - *p++ = '1'; - if (eFormat != rtl_math_StringFormat_F) - { - *p++ = cDecSeparator; - nExp++; - bHasDec = true; - } - *p++ = '0'; - } - else - { - for (typename T::Char* p2 = p - 1; p2 >= p1; --p2) - { - typename T::Char cS = *p2; - if (cS == cDecSeparator) - continue; - if (cS != '9') - { - ++*p2; - break; - } - *p2 = '0'; - if (p2 == p1) // The number consisted of all 9s replaced to all 0s - { - if (eFormat == rtl_math_StringFormat_F) - { // move everything to the right before inserting '1' - std::memmove(p2 + 1, p2, (p++ - p2) * sizeof(*p)); - } - else - { - nExp++; - } - *p2 = '1'; - } - } - - *p++ = '0'; - } - fValue = 0.0; - } - else - { - *p++ = nDigit + '0'; - fValue = (fValue - nDigit) * 10.0; - } + --nCurExp; + nDigit = aParts.significand / eX[nCurExp]; + aParts.significand %= eX[nCurExp]; } else { - *p++ = '0'; + nDigit = aParts.significand; + aParts.significand = 0; } + assert(nDigit >= 0 && nDigit < 10); + *p++ = nDigit + '0'; if (!--nDigits) break; // for diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 4777845308c5..08326f923c0d 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -1632,7 +1632,7 @@ void SdOOXMLExportTest2::testTdf118825() xmlDocUniquePtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml"); - CPPUNIT_ASSERT_MOTIONPATH("M 0.0449285714285714 0.00368253968253968 C 0.0575714285714285 -0.00095238095238096 0.0704264795523803 -0.00370117418637049 0.0831071428571428 -0.00819047619047622 C 0.0953550597998766 -0.0125265741339082 0.107821870086751 -0.010397536991717 0.120321428571429 -0.0115555555555556 C 0.133179018681433 -0.0127467438724762 0.151318627483861 -0.0158700272533852 0.1585 0.00539682539682542 C 0.16478291361998 0.0240029898688431 0.15828642886492 0.0483806254341085 0.161392857142857 0.0698412698412698 C 0.165179286017685 0.0959996731216037 0.17453898927982 0.119735912694626 0.187142857142857 0.132634920634921 C 0.199788991845377 0.145577185161529 0.215607110490848 0.142889773028431 0.230107142857143 0.142857142857143 C 0.243821417584191 0.142826280916829 0.257716514999779 0.142685979556724 0.271142857142857 0.137777777777778 C 0.286895094567923 0.132019309914514 0.302318190711873 0.122962218306185 0.317928571428571 0.11568253968254 C 0.333496771884547 0.108422531222479 0.348787823719556 0.0990570571890929 0.363714285714286 0.0885079365079364 C 0.374930683062651 0.080580865157908 0.385357142857143 0.0693333333333332 0.396178571428571 0.0596825396825396 L 0.404785714285714 0.0410158730158729 L 0.401892857142857 0.0342222222222221 E", getXPath(pXmlDocContent, "(//p:animMotion)[1]", "path")); + CPPUNIT_ASSERT_MOTIONPATH("M 0.0449285714285714 0.00368253968253968 C 0.0575714285714285 -0.00095238095238096 0.0704264795523803 -0.00370117418637049 0.0831071428571428 -0.00819047619047622 C 0.0953550597998766 -0.0125265741339082 0.107821870086751 -0.010397536991717 0.120321428571429 -0.0115555555555556 C 0.133179018681433 -0.0127467438724762 0.151318627483861 -0.0158700272533852 0.1585 0.00539682539682542 C 0.16478291361998 0.0240029898688431 0.15828642886492 0.0483806254341085 0.161392857142857 0.0698412698412698 C 0.165179286017685 0.0959996731216037 0.17453898927982 0.119735912694626 0.187142857142857 0.132634920634921 C 0.199788991845377 0.145577185161529 0.215607110490848 0.142889773028431 0.230107142857143 0.142857142857143 C 0.243821417584191 0.142826280916829 0.257716514999779 0.142685979556724 0.271142857142857 0.137777777777778 C 0.286895094567923 0.132019309914514 0.302318190711873 0.122962218306185 0.317928571428571 0.11568253968254 C 0.333496771884548 0.108422531222479 0.348787823719556 0.0990570571890929 0.363714285714286 0.0885079365079364 C 0.374930683062651 0.080580865157908 0.385357142857143 0.0693333333333332 0.396178571428571 0.0596825396825396 L 0.404785714285714 0.0410158730158729 L 0.401892857142857 0.0342222222222221 E", getXPath(pXmlDocContent, "(//p:animMotion)[1]", "path")); CPPUNIT_ASSERT_MOTIONPATH("M 0.025 0.0571428571428571 L 0.0821428571428571 0.184126984126984 L -0.175 0.234920634920635 L -0.246428571428571 -0.0190476190476191 L -0.0821428571428573 -0.133333333333333 E", getXPath(pXmlDocContent, "(//p:animMotion)[2]", "path")); CPPUNIT_ASSERT_MOTIONPATH("M -0.0107142857142857 0.00634920634920635 C -0.110714285714286 0.501587301587301 -0.153571428571429 -0.00634920634920635 -0.246428571428572 0.184126984126984 C -0.339285714285715 0.374603174603175 -0.296428571428572 0.514285714285714 -0.267857142857143 0.603174603174603 C -0.239285714285715 0.692063492063492 0.0607142857142858 0.590476190476191 0.0607142857142858 0.590476190476191 E", getXPath(pXmlDocContent, "(//p:animMotion)[3]", "path")); CPPUNIT_ASSERT_MOTIONPATH("M 0.0535714285714286 -0.0444444444444444 L 0.132142857142857 -0.0444444444444444 L 0.132142857142857 -0.146031746031746 L 0.0964285714285715 -0.146031746031746 E", getXPath(pXmlDocContent, "(//p:animMotion)[4]", "path")); |