include/svl/zformat.hxx | 3 sc/qa/unit/ucalc.cxx | 156 +++++++++++++++++++++++++++++++++++++++ sc/qa/unit/ucalc.hxx | 4 + sc/source/core/data/documen4.cxx | 20 ++++- 4 files changed, 179 insertions(+), 4 deletions(-)
New commits: commit 3c68b6520e743e8ed9afa908a461f766952e030f Author: Laurent Balland-Poirier <laurent.balland-poir...@laposte.net> Date: Fri Mar 3 21:51:26 2017 +0100 tdf#106252 Engineering notation for Precision as shown with more tests Reviewed-on: https://gerrit.libreoffice.org/35089 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> (cherry picked from commit 5f2db66ad0de6fbbae309850516e17eaa17934cb) Change-Id: Ifc77b847af4eaaa3c85e904e46c2663b6d768241 Reviewed-on: https://gerrit.libreoffice.org/36369 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins <c...@libreoffice.org> diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx index 34525acad43e..4d108815d9a7 100644 --- a/include/svl/zformat.hxx +++ b/include/svl/zformat.hxx @@ -223,7 +223,8 @@ public: { return NumFor[nIx].Info().nCntPost; } /// Count of integer digits - sal_uInt16 GetFormatIntegerDigits() const { return NumFor[0].Info().nCntPre; } + sal_uInt16 GetFormatIntegerDigits( sal_uInt16 nIx = 0 ) const + { return NumFor[nIx].Info().nCntPre; } //! Read/write access on a special sal_uInt16 component, may only be used on the //! standard format 0, 5000, ... and only by the number formatter! diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index dbdd549b3ba6..ea44ff7d4f3d 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -6434,12 +6434,14 @@ void Test::testPrecisionAsShown() aCode = "0.00"; fValue = 1.0/3.0; fExpectedRoundVal = 0.33; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); - fValue = -10.001; - fExpectedRoundVal = -10.0; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 10.001; + fExpectedRoundVal = 10.0; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); } - { // thousand rounding buguous!!!! tdf#106253 + { // thousand rounding bogus!!!! tdf#106253 aCode = "0,,"; fValue = 4.0e9 / 7.0; fExpectedRoundVal = 571e6; // actual is 571428571 @@ -6452,54 +6454,105 @@ void Test::testPrecisionAsShown() aCode = "0.00%"; fValue = 4.0 / 7.0; fExpectedRoundVal = 0.5714; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); - fValue = -4.0 / 7.0; - fExpectedRoundVal = -0.5714; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 40.0 / 7.0; + fExpectedRoundVal = 5.7143; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); } { // scientific rounding aCode = "0.00E0"; fValue = 400000.0 / 7.0; fExpectedRoundVal = 57100.0; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); fValue = 4.0 / 70000.0; fExpectedRoundVal = 5.71e-5; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); - // engineering rounding bugous!!! tdf#106252 + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + // engineering rounding tdf#106252 aCode = "##0.000E0"; fValue = 400000.0 / 7.0; - fExpectedRoundVal = 57143.0; // actual is 57140 - //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fExpectedRoundVal = 57.143e3; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4000000.0 / 7.0; + fExpectedRoundVal = 571.429e3; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 40000000.0 / 7.0; + fExpectedRoundVal = 5.714e6; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); fValue = 4.0 / 70000.0; - fExpectedRoundVal = 5.7143e-5; // actual is 5.714e-05 - //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fExpectedRoundVal = 57.143e-6; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 7000.0; + fExpectedRoundVal = 571.429e-6; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 700.0; + fExpectedRoundVal = 5.714e-3; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + aCode = "##?0.0#E0"; + fValue = 400000.0 / 7.0; + fExpectedRoundVal = 5.71e4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4000000.0 / 7.0; + fExpectedRoundVal = 57.14e4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 40000000.0 / 7.0; + fExpectedRoundVal = 571.43e4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 400000000.0 / 7.0; + fExpectedRoundVal = 5714.29e4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 70000.0; + fExpectedRoundVal = 5714.29e-8; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 7000.0; + fExpectedRoundVal = 5.71e-4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 700.0; + fExpectedRoundVal = 57.14e-4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); + fValue = 4.0 / 70.0; + fExpectedRoundVal = 571.43e-4; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); } { // fraction rounding tdf#105657 aCode = "# ?/?"; fValue = 0.35; fExpectedRoundVal = 1.0/3.0; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); - fValue = -0.35; - fExpectedRoundVal = -1.0/3.0; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); } { // exact fraction aCode = "# ?/??"; fValue = 0.35; fExpectedRoundVal = 0.35; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); - fValue = -0.35; - fExpectedRoundVal = -0.35; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, -fValue, -fExpectedRoundVal ); } { // several sub-formats tdf#106052 aCode = "0.00;-0.000"; fValue = 1.0/3.0; fExpectedRoundVal = 0.33; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); fValue = -1.0/3.0; fExpectedRoundVal = -0.333; - checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); } setCalcAsShown( m_pDoc, false); diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index 6a1110b6cd80..6bb280b20d91 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -660,7 +660,8 @@ double ScDocument::RoundValueAsShown( double fVal, sal_uInt32 nFormat ) const short nPrecision; if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) { - nPrecision = (short)GetFormatTable()->GetFormatPrecision( nFormat, fVal ); + sal_uInt16 nIdx = pFormat->GetSubformatIndex( fVal ); + nPrecision = (short)pFormat->GetFormatPrecision( nIdx ); switch ( nType ) { case css::util::NumberFormat::PERCENT: // 0.41% == 0.0041 @@ -668,10 +669,23 @@ double ScDocument::RoundValueAsShown( double fVal, sal_uInt32 nFormat ) const break; case css::util::NumberFormat::SCIENTIFIC: // 1.23e-3 == 0.00123 { + short nExp = 0; if ( fVal > 0.0 ) - nPrecision = sal::static_int_cast<short>( nPrecision - (short)floor( log10( fVal ) ) ); + nExp = (short)floor( log10( fVal ) ); else if ( fVal < 0.0 ) - nPrecision = sal::static_int_cast<short>( nPrecision - (short)floor( log10( -fVal ) ) ); + nExp = (short)floor( log10( -fVal ) ); + nPrecision -= nExp; + short nInteger = (short)pFormat->GetFormatIntegerDigits( nIdx ); + if ( nInteger > 1 ) // Engineering notation + { + short nIncrement = nExp % nInteger; + if ( nIncrement != 0 ) + { + nPrecision += nIncrement; + if (nExp < 0 ) + nPrecision += nInteger; + } + } break; } case css::util::NumberFormat::FRACTION: // get value of fraction representation commit e9d13f703f212b317682c35877571903da18b4af Author: Laurent Balland-Poirier <laurent.balland-poir...@laposte.net> Date: Wed Mar 1 08:56:58 2017 +0100 Tests for "Precision as shown" following tdf#105657 tdf#106052 I was unabled to add these test svl/qa/unit/svl.cxx because they required ScDocument::RoundValueAsShown() Found that other formats are not supported by "Precision as shown" option: - engineering tdf#106252 - thousand tdf#106253 Change-Id: Iaf98c404cabec0f5c69f94f2bf863351487fe9d7 Reviewed-on: https://gerrit.libreoffice.org/34750 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> (cherry picked from commit 7496f7d3cae8a932dc43ede8a30a99289366a264) Reviewed-on: https://gerrit.libreoffice.org/36368 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 65d5892b4c5a..dbdd549b3ba6 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -6403,6 +6403,109 @@ void Test::setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown) pDoc->SetDocOptions(aOpt); } +void Test::checkPrecisionAsShown( OUString& rCode, double fValue, double fExpectedRoundVal ) +{ + SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable(); + sal_uInt32 nFormat = pFormatter->GetEntryKey( rCode ); + if ( nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { + sal_Int32 nCheckPos = 0; + short nType; + pFormatter->PutEntry( rCode, nCheckPos, nType, nFormat ); + CPPUNIT_ASSERT_EQUAL( nCheckPos, sal_Int32(0) ); + } + double fRoundValue = m_pDoc->RoundValueAsShown( fValue, nFormat ); + rtl::OString aMessage = "Format \""; + aMessage += rtl::OUStringToOString( rCode, RTL_TEXTENCODING_ASCII_US ); + aMessage += "\" is not correctly rounded"; + CPPUNIT_ASSERT_EQUAL_MESSAGE( aMessage.getStr(), fExpectedRoundVal, fRoundValue ); +} + +void Test::testPrecisionAsShown() +{ + m_pDoc->InsertTab(0, "Test"); + + // Turn on "precision as shown" option. + setCalcAsShown( m_pDoc, true); + + OUString aCode; + double fValue, fExpectedRoundVal; + { // decimal rounding + aCode = "0.00"; + fValue = 1.0/3.0; + fExpectedRoundVal = 0.33; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -10.001; + fExpectedRoundVal = -10.0; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // thousand rounding buguous!!!! tdf#106253 + aCode = "0,,"; + fValue = 4.0e9 / 7.0; + fExpectedRoundVal = 571e6; // actual is 571428571 + //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -4.0e8 / 7.0; + fExpectedRoundVal = -57e6; // actual is 57142857 + //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // percent rounding + aCode = "0.00%"; + fValue = 4.0 / 7.0; + fExpectedRoundVal = 0.5714; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -4.0 / 7.0; + fExpectedRoundVal = -0.5714; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // scientific rounding + aCode = "0.00E0"; + fValue = 400000.0 / 7.0; + fExpectedRoundVal = 57100.0; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = 4.0 / 70000.0; + fExpectedRoundVal = 5.71e-5; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + // engineering rounding bugous!!! tdf#106252 + aCode = "##0.000E0"; + fValue = 400000.0 / 7.0; + fExpectedRoundVal = 57143.0; // actual is 57140 + //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = 4.0 / 70000.0; + fExpectedRoundVal = 5.7143e-5; // actual is 5.714e-05 + //checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // fraction rounding tdf#105657 + aCode = "# ?/?"; + fValue = 0.35; + fExpectedRoundVal = 1.0/3.0; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -0.35; + fExpectedRoundVal = -1.0/3.0; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // exact fraction + aCode = "# ?/??"; + fValue = 0.35; + fExpectedRoundVal = 0.35; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -0.35; + fExpectedRoundVal = -0.35; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + { // several sub-formats tdf#106052 + aCode = "0.00;-0.000"; + fValue = 1.0/3.0; + fExpectedRoundVal = 0.33; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + fValue = -1.0/3.0; + fExpectedRoundVal = -0.333; + checkPrecisionAsShown( aCode, fValue, fExpectedRoundVal ); + } + + setCalcAsShown( m_pDoc, false); + m_pDoc->DeleteTab(0); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 041a8277a110..705536e74bad 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -60,6 +60,7 @@ public: static void setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown); + void checkPrecisionAsShown( OUString& rCode, double fValue, double fExpectedRoundVal ); template<size_t Size> static ScRange insertRangeData( @@ -488,6 +489,8 @@ public: void testEmptyCalcDocDefaults(); + void testPrecisionAsShown(); + CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testCollator); CPPUNIT_TEST(testSharedStringPool); @@ -735,6 +738,7 @@ public: CPPUNIT_TEST(testTdf97369); CPPUNIT_TEST(testTdf97587); CPPUNIT_TEST(testEmptyCalcDocDefaults); + CPPUNIT_TEST(testPrecisionAsShown); CPPUNIT_TEST_SUITE_END(); private: _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits