svl/qa/unit/svl.cxx            |    5 +++++
 svl/source/numbers/zformat.cxx |   12 ++++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

New commits:
commit 51df96790ec1ab24bd98a9d186e78164a401fddd
Author:     Xisco Fauli <[email protected]>
AuthorDate: Tue Jan 27 10:57:03 2026 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Tue Jan 27 14:40:03 2026 +0100

    tdf#167892: svl_qa_cppunit: Add test
    
    Change-Id: I56925b648518c8e3399e534e3c82eb9bc0bfa335
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198192
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198200

diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 4b482e0c1d9b..a98a253831ea 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -1437,6 +1437,11 @@ void Test::testUserDefinedNumberFormats()
         sExpected = "-1/2";
         checkPreviewString(aFormatter, sCode, -0.5, eLang, sExpected);
     }
+    {  // tdf#167892: hang formatting as fraction
+        sCode =     "#/?";
+        sExpected = "0/1";
+        checkPreviewString(aFormatter, sCode, 0.0000000000000000001, eLang, 
sExpected);
+    }
     {  // tdf#52510
         sCode =     "_($* #,##0.00_);_($* (#,##0.00);";
         sExpected = "";
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 89968ba942c5..0c33ade1f94c 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -2884,14 +2884,14 @@ void SvNumberformat::ImpGetFractionElements ( double& 
fNumber, sal_uInt16 nIx,
         {
             double fTemp = 1.0 / fRemainder;             // 64bits precision 
required when fRemainder is very weak
             nPartialDenom = static_cast<sal_Int64>(floor(fTemp));   // due to 
floating point notation with double precision
-#ifdef _WIN32
             // The fTemp value may be out of range for sal_Int64 (e.g. 1e+19), 
and the result of
-            // casting that is undefined. In practice, gcc/llvm gives us a 
large positive number, but MSVC may create
-            // a large negative number, which will make this algorithm 
oscillate, so apply a correction that makes
-            // MSVC end up with the same thing. There is probably a better 
algorithm to be used here.
+            // casting that is undefined. In practice, gcc/llvm gives us a 
large positive number,
+            // but depending on the compiler, we have either a large positive 
number (which works fine)
+            // or a a large negative number, which will make this algorithm 
oscillate.
+            // So apply a correction that makes all the compilers work 
reasonbly.
+            // There is probably a better algorithm to be used here for this 
whole function.
             if (nPartialDenom < 0)
                 nPartialDenom = -(nPartialDenom+1);
-#endif
             fRemainder = fTemp - static_cast<double>(nPartialDenom);
             nDivNext = nPartialDenom * nDiv + nDivPrev;
             if (nDivNext <= nBasis) // continue loop
commit aee02120d8252ece180dc7a601d572923606f4dc
Author:     Noel Grandin <[email protected]>
AuthorDate: Mon Jan 26 20:12:37 2026 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Tue Jan 27 14:39:57 2026 +0100

    tdf#167892 fix hang formatting very small number on windows
    
    Workaround undefined behaviour where llvm/gcc produces different
    code from MSVC, resulting in oscillation in this algorithm.
    
    regression from
      commit 44d17f8feca372acd41142d1b607d3360282bf30
      Author: Eike Rathke <[email protected]>
      Date:   Tue Oct 13 21:41:45 2020 +0200
      Resolves: tdf#137453 Implicit conversion from sal_uInt64 to sal_Int32 is 
bad..
    
    Change-Id: I486e8caabcbf582cf94b47547efc89d1b206503e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198163
    Reviewed-by: Noel Grandin <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198199

diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 65855709854a..89968ba942c5 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -2853,7 +2853,7 @@ double SvNumberformat::GetRoundFractionValue ( double 
fNumber ) const
 void SvNumberformat::ImpGetFractionElements ( double& fNumber, sal_uInt16 nIx,
                                               double& fIntPart, sal_Int64& 
nFrac, sal_Int64& nDiv ) const
 {
-    if ( fNumber < 0.0 )
+    if (fNumber < 0.0)
         fNumber = -fNumber;
     fIntPart = floor(fNumber); // Integral part
     fNumber -= fIntPart;         // Fractional part
@@ -2884,9 +2884,17 @@ void SvNumberformat::ImpGetFractionElements ( double& 
fNumber, sal_uInt16 nIx,
         {
             double fTemp = 1.0 / fRemainder;             // 64bits precision 
required when fRemainder is very weak
             nPartialDenom = static_cast<sal_Int64>(floor(fTemp));   // due to 
floating point notation with double precision
+#ifdef _WIN32
+            // The fTemp value may be out of range for sal_Int64 (e.g. 1e+19), 
and the result of
+            // casting that is undefined. In practice, gcc/llvm gives us a 
large positive number, but MSVC may create
+            // a large negative number, which will make this algorithm 
oscillate, so apply a correction that makes
+            // MSVC end up with the same thing. There is probably a better 
algorithm to be used here.
+            if (nPartialDenom < 0)
+                nPartialDenom = -(nPartialDenom+1);
+#endif
             fRemainder = fTemp - static_cast<double>(nPartialDenom);
             nDivNext = nPartialDenom * nDiv + nDivPrev;
-            if ( nDivNext <= nBasis )  // continue loop
+            if (nDivNext <= nBasis) // continue loop
             {
                 nFracNext = nPartialDenom * nFrac + nFracPrev;
                 nFracPrev = nFrac;

Reply via email to