include/tools/bigint.hxx         |   76 ++++++------
 tools/qa/cppunit/test_bigint.cxx |   12 -
 tools/source/generic/bigint.cxx  |  237 ++++++++++++++++++++-------------------
 vcl/source/control/longcurr.cxx  |   13 --
 4 files changed, 172 insertions(+), 166 deletions(-)

New commits:
commit 36df3f9ad2f71c122af3cf9fbc58c661f416658e
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Dec 20 12:17:31 2023 +0300
Commit:     Mike Kaganski <[email protected]>
CommitDate: Wed Dec 20 20:30:01 2023 +0100

    Make BigInt::DivMod public, to allow optimized division
    
    Change-Id: I4f79c30b9ab997d01e59a0dec76986e74abfc11f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161053
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/include/tools/bigint.hxx b/include/tools/bigint.hxx
index 1b089e173ef0..644bb4c3e29d 100644
--- a/include/tools/bigint.hxx
+++ b/include/tools/bigint.hxx
@@ -46,8 +46,7 @@ private:
     TOOLS_DLLPRIVATE void AddBig(BigInt& rB, BigInt& rRes);
     TOOLS_DLLPRIVATE void SubBig(BigInt& rB, BigInt& rRes);
     TOOLS_DLLPRIVATE void MultBig(BigInt const& rB, BigInt& rRes) const;
-    TOOLS_DLLPRIVATE void DivModBig(BigInt const& rB, BigInt& rRes, bool bMod) 
const;
-    TOOLS_DLLPRIVATE void DivMod(BigInt const& rVal, bool bMod);
+    TOOLS_DLLPRIVATE void DivModBig(BigInt const& rB, BigInt* pDiv, BigInt* 
pMod) const;
 
 public:
     BigInt()
@@ -113,6 +112,8 @@ public:
 
     BigInt&         operator  =( sal_Int32 nValue );
 
+    void DivMod(BigInt const& rVal, BigInt* pDiv, BigInt* pMod) const;
+
     /* Scale and round value */
     static tools::Long Scale(tools::Long nVal, tools::Long nMult, tools::Long 
nDiv);
 
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
index 3f4a82ffe33e..240494dfc15d 100644
--- a/tools/source/generic/bigint.cxx
+++ b/tools/source/generic/bigint.cxx
@@ -276,7 +276,7 @@ void BigInt::MultBig(const BigInt& rB, BigInt& rRes) const
     }
 }
 
-void BigInt::DivModBig(const BigInt& rB, BigInt& rRes, bool bMod) const
+void BigInt::DivModBig(const BigInt& rB, BigInt* pDiv, BigInt* pMod) const
 {
     assert(IsBig() && rB.IsBig());
     assert(nLen >= rB.nLen);
@@ -299,6 +299,9 @@ void BigInt::DivModBig(const BigInt& rB, BigInt& rRes, bool 
bMod) const
     assert(nDenMostSig >= 0x100000000 / 2);
     const sal_uInt64 nDen2ndSig = rB.nLen > 1 ? den[rB.nLen - 2] : 0;
 
+    BigInt aTmp;
+    BigInt& rRes = pDiv ? *pDiv : aTmp;
+
     for (size_t j = num.size() - 1; j >= den.size(); j--)
     { // guess divisor
         assert(num[j] < nDenMostSig || (num[j] == nDenMostSig && num[j - 1] == 
0));
@@ -344,17 +347,19 @@ void BigInt::DivModBig(const BigInt& rB, BigInt& rRes, 
bool bMod) const
         }
     }
 
-    if (bMod)
+    if (pMod)
     {
-        rRes.nLen = DivInPlace(num, nMult, nMult);
-        assert(rRes.nLen <= MAX_DIGITS);
-        rRes.bIsNeg = bIsNeg;
-        std::copy_n(num.begin(), rRes.nLen, rRes.nNum);
+        pMod->nLen = DivInPlace(num, nMult, nMult);
+        assert(pMod->nLen <= MAX_DIGITS);
+        pMod->bIsNeg = bIsNeg;
+        std::copy_n(num.begin(), pMod->nLen, pMod->nNum);
+        pMod->Normalize();
     }
-    else
+    if (pDiv) // rRes references pDiv
     {
-        rRes.bIsNeg = bIsNeg != rB.bIsNeg;
-        rRes.nLen = nLen - rB.nLen + 1;
+        pDiv->bIsNeg = bIsNeg != rB.bIsNeg;
+        pDiv->nLen = nLen - rB.nLen + 1;
+        pDiv->Normalize();
     }
 }
 
@@ -566,8 +571,9 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
     return *this;
 }
 
-void BigInt::DivMod(const BigInt& rVal, bool bMod)
+void BigInt::DivMod(const BigInt& rVal, BigInt* pDiv, BigInt* pMod) const
 {
+    assert(pDiv || pMod); // Avoid useless calls
     if (!rVal.IsBig())
     {
         if ( rVal.nVal == 0 )
@@ -578,66 +584,99 @@ void BigInt::DivMod(const BigInt& rVal, bool bMod)
 
         if (rVal.nVal == 1)
         {
-            if (bMod)
-                *this = 0;
+            if (pDiv)
+            {
+                *pDiv = *this;
+                pDiv->Normalize();
+            }
+            if (pMod)
+                *pMod = 0;
             return;
         }
 
         if (!IsBig())
         {
             // No overflows may occur here
-            nVal = bMod ? nVal % rVal.nVal : nVal / rVal.nVal;
+            const sal_Int32 nDiv = nVal / rVal.nVal; // Compilers usually 
optimize adjacent
+            const sal_Int32 nMod = nVal % rVal.nVal; // / and % into a single 
instruction
+            if (pDiv)
+                *pDiv = nDiv;
+            if (pMod)
+                *pMod = nMod;
             return;
         }
 
         if ( rVal.nVal == -1 )
         {
-            if (bMod)
-                *this = 0;
-            else
-                bIsNeg = !bIsNeg;
+            if (pDiv)
+            {
+                *pDiv = *this;
+                pDiv->bIsNeg = !bIsNeg;
+                pDiv->Normalize();
+            }
+            if (pMod)
+                *pMod = 0;
             return;
         }
 
         // Divide BigInt with an sal_uInt32
         sal_uInt32 nTmp;
+        bool bNegate;
         if ( rVal.nVal < 0 )
         {
             nTmp = static_cast<sal_uInt32>(-rVal.nVal);
-            bIsNeg = !bIsNeg;
+            bNegate = true;
         }
         else
+        {
             nTmp = static_cast<sal_uInt32>(rVal.nVal);
+            bNegate = false;
+        }
 
-        nLen = DivInPlace({ nNum, nLen }, nTmp, nTmp);
-        if (bMod)
-            *this = BigInt(nTmp);
+        BigInt aTmp;
+        BigInt& rDiv = pDiv ? *pDiv : aTmp;
+        rDiv = *this;
+        rDiv.nLen = DivInPlace({ rDiv.nNum, rDiv.nLen }, nTmp, nTmp);
+        if (pDiv)
+        {
+            if (bNegate)
+                pDiv->bIsNeg = !pDiv->bIsNeg;
+            pDiv->Normalize();
+        }
+        if (pMod)
+        {
+            *pMod = BigInt(nTmp);
+        }
         return;
     }
 
     BigInt tmpA = MakeBig(), tmpB = rVal.MakeBig();
     if (tmpA.ABS_IsLessBig(tmpB))
     {
-        if (!bMod)
-            *this = 0;
+        // First store *this to *pMod, then nullify *pDiv, to handle 'pDiv == 
this' case
+        if (pMod)
+        {
+            *pMod = *this;
+            pMod->Normalize();
+        }
+        if (pDiv)
+            *pDiv = 0;
         return;
     }
 
     // Divide BigInt with BigInt
-    tmpA.DivModBig(tmpB, *this, bMod);
+    tmpA.DivModBig(tmpB, pDiv, pMod);
 }
 
 BigInt& BigInt::operator/=( const BigInt& rVal )
 {
-    DivMod(rVal, false);
-    Normalize();
+    DivMod(rVal, this, nullptr);
     return *this;
 }
 
 BigInt& BigInt::operator%=( const BigInt& rVal )
 {
-    DivMod(rVal, true);
-    Normalize();
+    DivMod(rVal, nullptr, this);
     return *this;
 }
 
diff --git a/vcl/source/control/longcurr.cxx b/vcl/source/control/longcurr.cxx
index ee9451d79655..587c99cf1724 100644
--- a/vcl/source/control/longcurr.cxx
+++ b/vcl/source/control/longcurr.cxx
@@ -56,10 +56,9 @@ OUString ImplGetCurr( const LocaleDataWrapper& 
rLocaleDataWrapper, const BigInt
         return rLocaleDataWrapper.getCurr( static_cast<tools::Long>(rNumber), 
nDigits, rCurrSymbol, bShowThousandSep );
 
     BigInt aTmp( ImplPower10( nDigits ) );
-    BigInt aInteger(rNumber.Abs());
-    BigInt aFraction(aInteger);
-    aInteger  /= aTmp;
-    aFraction %= aTmp;
+    BigInt aInteger;
+    BigInt aFraction;
+    rNumber.Abs().DivMod(aTmp, &aInteger, &aFraction);
     if ( !aInteger.IsZero() )
     {
         aFraction += aTmp;
@@ -71,9 +70,7 @@ OUString ImplGetCurr( const LocaleDataWrapper& 
rLocaleDataWrapper, const BigInt
     OUStringBuffer aTemplate(rLocaleDataWrapper.getCurr( 
static_cast<tools::Long>(aFraction), nDigits, rCurrSymbol, bShowThousandSep ));
     while( !aInteger.IsZero() )
     {
-        aFraction  = aInteger;
-        aFraction %= aTmp;
-        aInteger  /= aTmp;
+        aInteger.DivMod(aTmp, &aInteger, &aFraction);
         if( !aInteger.IsZero() )
             aFraction += aTmp;
 
commit c684aa9cf33fdbae5bf5f05d2c391f27a140b56d
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Dec 20 11:02:08 2023 +0300
Commit:     Mike Kaganski <[email protected]>
CommitDate: Wed Dec 20 20:29:51 2023 +0100

    Simplify and rename for clarity
    
    Change-Id: Ic97a2b313c6f7d9da540a8867f01362c2fe7b0d0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161052
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/include/tools/bigint.hxx b/include/tools/bigint.hxx
index 1a5a2284324a..1b089e173ef0 100644
--- a/include/tools/bigint.hxx
+++ b/include/tools/bigint.hxx
@@ -40,15 +40,14 @@ private:
     sal_uInt8       nLen;    // current length, if 0, data is in nVal, 
otherwise data is in nNum
     bool            bIsNeg;    // Is Sign negative?
 
-    TOOLS_DLLPRIVATE BigInt MakeBig() const;
-    TOOLS_DLLPRIVATE void Normalize();
-    TOOLS_DLLPRIVATE bool ABS_IsLessLong(BigInt const &) const;
-    TOOLS_DLLPRIVATE void AddLong(BigInt &, BigInt &);
-    TOOLS_DLLPRIVATE void SubLong(BigInt &, BigInt &);
-    TOOLS_DLLPRIVATE void MultLong(BigInt const &, BigInt &) const;
-    TOOLS_DLLPRIVATE void DivModLong(BigInt const &, BigInt &, bool) const;
-    TOOLS_DLLPRIVATE void DivMod(BigInt const &, bool);
-    TOOLS_DLLPRIVATE bool ABS_IsLess(BigInt const &) const;
+    TOOLS_DLLPRIVATE BigInt MakeBig() const; // Create a BigInt with minimal 
non-0 nLen
+    TOOLS_DLLPRIVATE void Normalize(); // Use nVal if possible, otherwise use 
minimal nLen
+    TOOLS_DLLPRIVATE bool ABS_IsLessBig(BigInt const& rVal) const;
+    TOOLS_DLLPRIVATE void AddBig(BigInt& rB, BigInt& rRes);
+    TOOLS_DLLPRIVATE void SubBig(BigInt& rB, BigInt& rRes);
+    TOOLS_DLLPRIVATE void MultBig(BigInt const& rB, BigInt& rRes) const;
+    TOOLS_DLLPRIVATE void DivModBig(BigInt const& rB, BigInt& rRes, bool bMod) 
const;
+    TOOLS_DLLPRIVATE void DivMod(BigInt const& rVal, bool bMod);
 
 public:
     BigInt()
@@ -68,7 +67,7 @@ public:
     BigInt( double nVal );
     BigInt( sal_uInt32 nVal );
     BigInt( sal_Int64 nVal );
-    BigInt( const BigInt& rBigInt );
+    BigInt(const BigInt& rBigInt) = default;
     BigInt( std::u16string_view rString );
 
     template <typename N>
@@ -99,11 +98,11 @@ public:
     operator        double() const;
     operator        sal_Int64() const;
 
-    bool            IsNeg() const { return !IsLong() ? bIsNeg : nVal < 0; }
-    bool            IsZero() const { return IsLong() && nVal == 0; }
-    bool            IsLong() const { return nLen == 0; }
+    bool            IsNeg() const { return IsBig() ? bIsNeg : nVal < 0; }
+    bool            IsZero() const { return !IsBig() && nVal == 0; }
+    bool            IsBig() const { return nLen != 0; }
 
-    void            Abs();
+    BigInt Abs() const;
 
     BigInt&         operator  =( const BigInt& rVal );
     BigInt&         operator +=( const BigInt& rVal );
@@ -123,7 +122,7 @@ public:
 
 inline BigInt::operator sal_Int16() const
 {
-    if ( nLen == 0 && nVal >= SAL_MIN_INT16 && nVal <= SAL_MAX_INT16 )
+    if (!IsBig() && nVal >= SAL_MIN_INT16 && nVal <= SAL_MAX_INT16)
         return static_cast<sal_Int16>(nVal);
     assert(false && "out of range");
     return 0;
@@ -131,7 +130,7 @@ inline BigInt::operator sal_Int16() const
 
 inline BigInt::operator sal_uInt16() const
 {
-    if ( nLen == 0 && nVal >= 0 && nVal <= SAL_MAX_UINT16 )
+    if (!IsBig() && nVal >= 0 && nVal <= SAL_MAX_UINT16)
         return static_cast<sal_uInt16>(nVal);
     assert(false && "out of range");
     return 0;
@@ -139,7 +138,7 @@ inline BigInt::operator sal_uInt16() const
 
 inline BigInt::operator sal_Int32() const
 {
-    if (nLen == 0)
+    if (!IsBig())
         return nVal;
     assert(false && "out of range");
     return 0;
@@ -147,7 +146,7 @@ inline BigInt::operator sal_Int32() const
 
 inline BigInt::operator sal_uInt32() const
 {
-    if ( nLen == 0 && nVal >= 0 )
+    if (!IsBig() && nVal >= 0)
         return static_cast<sal_uInt32>(nVal);
     assert(false && "out of range");
     return 0;
@@ -181,47 +180,49 @@ inline BigInt& BigInt::operator =( sal_Int32 nValue )
     return *this;
 }
 
-inline void BigInt::Abs()
+inline BigInt BigInt::Abs() const
 {
-    if ( nLen != 0 )
-        bIsNeg = false;
+    BigInt aRes(*this);
+    if (IsBig())
+        aRes.bIsNeg = false;
     else if ( nVal < 0 )
-        nVal = -nVal;
+        aRes.nVal = -nVal;
+    return aRes;
 }
 
 inline BigInt operator+( const BigInt &rVal1, const BigInt &rVal2 )
 {
-    BigInt aErg( rVal1 );
-    aErg += rVal2;
-    return aErg;
+    BigInt aRes( rVal1 );
+    aRes += rVal2;
+    return aRes;
 }
 
 inline BigInt operator-( const BigInt &rVal1, const BigInt &rVal2 )
 {
-    BigInt aErg( rVal1 );
-    aErg -= rVal2;
-    return aErg;
+    BigInt aRes( rVal1 );
+    aRes -= rVal2;
+    return aRes;
 }
 
 inline BigInt operator*( const BigInt &rVal1, const BigInt &rVal2 )
 {
-    BigInt aErg( rVal1 );
-    aErg *= rVal2;
-    return aErg;
+    BigInt aRes( rVal1 );
+    aRes *= rVal2;
+    return aRes;
 }
 
 inline BigInt operator/( const BigInt &rVal1, const BigInt &rVal2 )
 {
-    BigInt aErg( rVal1 );
-    aErg /= rVal2;
-    return aErg;
+    BigInt aRes( rVal1 );
+    aRes /= rVal2;
+    return aRes;
 }
 
 inline BigInt operator%( const BigInt &rVal1, const BigInt &rVal2 )
 {
-    BigInt aErg( rVal1 );
-    aErg %= rVal2;
-    return aErg;
+    BigInt aRes( rVal1 );
+    aRes %= rVal2;
+    return aRes;
 }
 
 #endif
diff --git a/tools/qa/cppunit/test_bigint.cxx b/tools/qa/cppunit/test_bigint.cxx
index 9a958836bb5e..065a2719b9b3 100644
--- a/tools/qa/cppunit/test_bigint.cxx
+++ b/tools/qa/cppunit/test_bigint.cxx
@@ -45,7 +45,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt bi(static_cast<sal_Int64>(42));
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(!bi.IsNeg());
-        CPPUNIT_ASSERT(bi.IsLong());
+        CPPUNIT_ASSERT(!bi.IsBig());
         CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(42), 
static_cast<sal_Int32>(bi));
     }
 
@@ -54,7 +54,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt bi(static_cast<sal_Int64>(-42));
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(bi.IsNeg());
-        CPPUNIT_ASSERT(bi.IsLong());
+        CPPUNIT_ASSERT(!bi.IsBig());
         CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-42), 
static_cast<sal_Int32>(bi));
     }
 
@@ -63,7 +63,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt 
bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::max()));
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(!bi.IsNeg());
-        CPPUNIT_ASSERT(bi.IsLong());
+        CPPUNIT_ASSERT(!bi.IsBig());
         CPPUNIT_ASSERT_EQUAL(std::numeric_limits<sal_Int32>::max(), 
static_cast<sal_Int32>(bi));
     }
 
@@ -72,7 +72,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt 
bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::min()));
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(bi.IsNeg());
-        CPPUNIT_ASSERT(bi.IsLong());
+        CPPUNIT_ASSERT(!bi.IsBig());
         CPPUNIT_ASSERT_EQUAL(std::numeric_limits<sal_Int32>::min(), 
static_cast<sal_Int32>(bi));
     }
 
@@ -81,7 +81,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt 
bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::max()) + 1);
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(!bi.IsNeg());
-        CPPUNIT_ASSERT(!bi.IsLong());
+        CPPUNIT_ASSERT(bi.IsBig());
     }
 
     // negative number not fitting to sal_Int32
@@ -89,7 +89,7 @@ void BigIntTest::testConstructionFromLongLong()
         BigInt 
bi(static_cast<sal_Int64>(std::numeric_limits<sal_Int32>::min()) - 1);
         CPPUNIT_ASSERT(!bi.IsZero());
         CPPUNIT_ASSERT(bi.IsNeg());
-        CPPUNIT_ASSERT(!bi.IsLong());
+        CPPUNIT_ASSERT(bi.IsBig());
     }
 }
 
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
index 8d8afd0c3f64..3f4a82ffe33e 100644
--- a/tools/source/generic/bigint.cxx
+++ b/tools/source/generic/bigint.cxx
@@ -42,7 +42,7 @@ const sal_Int32 MY_MINLONG  = -MY_MAXLONG;
 
 BigInt BigInt::MakeBig() const
 {
-    if (!IsLong())
+    if (IsBig())
     {
         BigInt ret(*this);
         while ( ret.nLen > 1 && ret.nNum[ret.nLen-1] == 0 )
@@ -67,8 +67,7 @@ BigInt BigInt::MakeBig() const
 
 void BigInt::Normalize()
 {
-    // nLen == 0 means that the active union member is nVal, otherwise nNum
-    if ( nLen != 0 )
+    if (IsBig())
     {
         while ( nLen > 1 && nNum[nLen-1] == 0 )
             nLen--;
@@ -96,7 +95,6 @@ void BigInt::Normalize()
 // run-time index checking in debug builds.
 static std::span<sal_uInt32> Mult(std::span<const sal_uInt32> aNum, sal_uInt32 
nMul, std::span<sal_uInt32> retBuf)
 {
-    assert(aNum.size() <= MAX_DIGITS);
     assert(retBuf.size() >= aNum.size());
     sal_uInt64 nK = 0;
     for (size_t i = 0; i < aNum.size(); i++)
@@ -134,24 +132,23 @@ static size_t DivInPlace(std::span<sal_uInt32> aNum, 
sal_uInt32 nDiv, sal_uInt32
     return aNum.size();
 }
 
-bool BigInt::ABS_IsLessLong(const BigInt& rVal) const
+bool BigInt::ABS_IsLessBig(const BigInt& rVal) const
 {
-    assert(!IsLong() && !rVal.IsLong());
+    assert(IsBig() && rVal.IsBig());
     if ( rVal.nLen < nLen)
         return false;
     if ( rVal.nLen > nLen )
         return true;
 
-    int i;
-    for ( i = nLen - 1; i > 0 && nNum[i] == rVal.nNum[i]; i-- )
-    {
-    }
+    int i = nLen - 1;
+    while (i > 0 && nNum[i] == rVal.nNum[i])
+        --i;
     return nNum[i] < rVal.nNum[i];
 }
 
-void BigInt::AddLong( BigInt& rB, BigInt& rErg )
+void BigInt::AddBig(BigInt& rB, BigInt& rRes)
 {
-    assert(!IsLong() && !rB.IsLong());
+    assert(IsBig() && rB.IsBig());
     if ( bIsNeg == rB.bIsNeg )
     {
         int  i;
@@ -180,34 +177,33 @@ void BigInt::AddLong( BigInt& rB, BigInt& rErg )
                 k = 1;
             else
                 k = 0;
-            rErg.nNum[i] = static_cast<sal_uInt32>(nZ);
+            rRes.nNum[i] = static_cast<sal_uInt32>(nZ);
         }
         // If an overflow occurred, add to solution
         if (k)
         {
             assert(i < MAX_DIGITS);
-            rErg.nNum[i] = 1;
+            rRes.nNum[i] = 1;
             len++;
         }
         // Set length and sign
-        rErg.nLen   = len;
-        rErg.bIsNeg = bIsNeg;
+        rRes.nLen = len;
+        rRes.bIsNeg = bIsNeg;
     }
     // If one of the values is negative, perform subtraction instead
     else
     {
         bIsNeg = !bIsNeg;
-        rB.SubLong(*this, rErg);
+        rB.SubBig(*this, rRes);
         bIsNeg = !bIsNeg;
     }
 }
 
-void BigInt::SubLong( BigInt& rB, BigInt& rErg )
+void BigInt::SubBig(BigInt& rB, BigInt& rRes)
 {
-    assert(!IsLong() && !rB.IsLong());
+    assert(IsBig() && rB.IsBig());
     if ( bIsNeg == rB.bIsNeg )
     {
-        int  i;
         char len;
 
         // if length of the two values differ, fill remaining positions
@@ -215,74 +211,74 @@ void BigInt::SubLong( BigInt& rB, BigInt& rErg )
         if (nLen >= rB.nLen)
         {
             len = nLen;
-            for (i = rB.nLen; i < len; i++)
+            for (int i = rB.nLen; i < len; i++)
                 rB.nNum[i] = 0;
         }
         else
         {
             len = rB.nLen;
-            for (i = nLen; i < len; i++)
+            for (int i = nLen; i < len; i++)
                 nNum[i] = 0;
         }
 
-        const bool bThisIsLess = ABS_IsLessLong(rB);
+        const bool bThisIsLess = ABS_IsLessBig(rB);
         BigInt& rGreater = bThisIsLess ? rB : *this;
         BigInt& rSmaller = bThisIsLess ? *this : rB;
 
         sal_Int64 k = 0;
-        for (i = 0; i < len; i++)
+        for (int i = 0; i < len; i++)
         {
             sal_Int64 nZ = static_cast<sal_Int64>(rGreater.nNum[i]) - 
static_cast<sal_Int64>(rSmaller.nNum[i]) + k;
             if (nZ < 0)
                 k = -1;
             else
                 k = 0;
-            rErg.nNum[i] = static_cast<sal_uInt32>(nZ);
+            rRes.nNum[i] = static_cast<sal_uInt32>(nZ);
         }
 
         // if a < b, revert sign
-        rErg.bIsNeg = bThisIsLess ? !bIsNeg : bIsNeg;
-        rErg.nLen   = len;
+        rRes.bIsNeg = bThisIsLess ? !bIsNeg : bIsNeg;
+        rRes.nLen   = len;
     }
     // If one of the values is negative, perform addition instead
     else
     {
         bIsNeg = !bIsNeg;
-        AddLong(rB, rErg);
+        AddBig(rB, rRes);
         bIsNeg = !bIsNeg;
-        rErg.bIsNeg = bIsNeg;
+        rRes.bIsNeg = bIsNeg;
     }
 }
 
-void BigInt::MultLong( const BigInt& rB, BigInt& rErg ) const
+void BigInt::MultBig(const BigInt& rB, BigInt& rRes) const
 {
-    assert(!IsLong() && !rB.IsLong());
+    assert(IsBig() && rB.IsBig());
 
-    rErg.bIsNeg = bIsNeg != rB.bIsNeg;
-    rErg.nLen   = nLen + rB.nLen;
-    assert(rErg.nLen <= MAX_DIGITS);
+    rRes.bIsNeg = bIsNeg != rB.bIsNeg;
+    rRes.nLen = nLen + rB.nLen;
+    assert(rRes.nLen <= MAX_DIGITS);
 
-    int i;
-    for (i = 0; i < rErg.nLen; i++)
-        rErg.nNum[i] = 0;
+    for (int i = 0; i < rRes.nLen; i++)
+        rRes.nNum[i] = 0;
 
     for (int j = 0; j < rB.nLen; j++)
     {
         sal_uInt64 k = 0;
+        int i;
         for (i = 0; i < nLen; i++)
         {
             sal_uInt64 nZ = static_cast<sal_uInt64>(nNum[i]) * 
static_cast<sal_uInt64>(rB.nNum[j]) +
-                 static_cast<sal_uInt64>(rErg.nNum[i + j]) + k;
-            rErg.nNum[i + j] = static_cast<sal_uInt32>(nZ);
+                 static_cast<sal_uInt64>(rRes.nNum[i + j]) + k;
+            rRes.nNum[i + j] = static_cast<sal_uInt32>(nZ);
             k = nZ >> 32;
         }
-        rErg.nNum[i + j] = k;
+        rRes.nNum[i + j] = k;
     }
 }
 
-void BigInt::DivModLong(const BigInt& rB, BigInt& rErg, bool bMod) const
+void BigInt::DivModBig(const BigInt& rB, BigInt& rRes, bool bMod) const
 {
-    assert(!IsLong() && !rB.IsLong());
+    assert(IsBig() && rB.IsBig());
     assert(nLen >= rB.nLen);
 
     assert(rB.nNum[rB.nLen - 1] != 0);
@@ -331,10 +327,10 @@ void BigInt::DivModLong(const BigInt& rB, BigInt& rErg, 
bool bMod) const
         sal_uInt32& rNum(num[j - den.size() + i]);
         rNum -= nK;
         if (num[j - den.size() + i] == 0)
-            rErg.nNum[j - den.size()] = nQ;
+            rRes.nNum[j - den.size()] = nQ;
         else
         {
-            rErg.nNum[j - den.size()] = nQ - 1;
+            rRes.nNum[j - den.size()] = nQ - 1;
             nK = 0;
             for (i = 0; i < den.size(); i++)
             {
@@ -350,39 +346,18 @@ void BigInt::DivModLong(const BigInt& rB, BigInt& rErg, 
bool bMod) const
 
     if (bMod)
     {
-        rErg.nLen = DivInPlace(num, nMult, nMult);
-        assert(rErg.nLen <= MAX_DIGITS);
-        rErg.bIsNeg = bIsNeg;
-        std::copy_n(num.begin(), rErg.nLen, rErg.nNum);
+        rRes.nLen = DivInPlace(num, nMult, nMult);
+        assert(rRes.nLen <= MAX_DIGITS);
+        rRes.bIsNeg = bIsNeg;
+        std::copy_n(num.begin(), rRes.nLen, rRes.nNum);
     }
     else
     {
-        rErg.bIsNeg = bIsNeg != rB.bIsNeg;
-        rErg.nLen   = nLen - rB.nLen + 1;
+        rRes.bIsNeg = bIsNeg != rB.bIsNeg;
+        rRes.nLen = nLen - rB.nLen + 1;
     }
 }
 
-bool BigInt::ABS_IsLess( const BigInt& rB ) const
-{
-    if (nLen != 0 || rB.nLen != 0)
-        return MakeBig().ABS_IsLessLong(rB.MakeBig());
-
-    if ( nVal < 0 )
-        return nVal > (rB.nVal < 0 ? rB.nVal : -rB.nVal);
-    else
-        return nVal < (rB.nVal < 0 ? -rB.nVal : rB.nVal);
-}
-
-BigInt::BigInt( const BigInt& rBigInt )
-    : nLen(0)
-    , bIsNeg(false)
-{
-    if ( rBigInt.nLen != 0 )
-        memcpy( static_cast<void*>(this), static_cast<const void*>(&rBigInt), 
sizeof( BigInt ) );
-    else
-        nVal = rBigInt.nVal;
-}
-
 BigInt::BigInt( std::u16string_view rString )
     : nLen(0)
 {
@@ -407,7 +382,7 @@ BigInt::BigInt( std::u16string_view rString )
         *this += *p - '0';
         p++;
     }
-    if ( nLen != 0 )
+    if (IsBig())
         bIsNeg = bNeg;
     else if( bNeg )
         nVal = -nVal;
@@ -447,7 +422,7 @@ BigInt::BigInt( double nValue )
 
         nLen = i;
 
-        if ( i < 3 )
+        if ( i < 2 )
             Normalize();
     }
 }
@@ -480,19 +455,14 @@ BigInt::BigInt( sal_Int64 nValue )
     }
     else
     {
-        sal_uInt64 nUValue = static_cast<sal_uInt64>(bIsNeg ? -nValue : 
nValue);
-        for (int i = 0; (i != sizeof(sal_uInt64) / 4) && (nUValue != 0); ++i)
-        {
-            nNum[i] = static_cast<sal_uInt32>(nUValue);
-            nUValue = nUValue >> 32;
-            ++nLen;
-        }
+        for (sal_uInt64 n = static_cast<sal_uInt64>(bIsNeg ? -nValue : 
nValue); n != 0; n >>= 32)
+            nNum[nLen++] = static_cast<sal_uInt32>(n);
     }
 }
 
 BigInt::operator double() const
 {
-    if (IsLong())
+    if (!IsBig())
         return static_cast<double>(nVal);
     else
     {
@@ -518,7 +488,7 @@ BigInt& BigInt::operator=( const BigInt& rBigInt )
     if (this == &rBigInt)
         return *this;
 
-    if ( rBigInt.nLen != 0 )
+    if (rBigInt.IsBig())
         memcpy( static_cast<void*>(this), static_cast<const void*>(&rBigInt), 
sizeof( BigInt ) );
     else
     {
@@ -530,7 +500,7 @@ BigInt& BigInt::operator=( const BigInt& rBigInt )
 
 BigInt& BigInt::operator+=( const BigInt& rVal )
 {
-    if ( nLen == 0 && rVal.nLen == 0 )
+    if (!IsBig() && !rVal.IsBig())
     {
         if( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG
             && nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
@@ -547,14 +517,14 @@ BigInt& BigInt::operator+=( const BigInt& rVal )
     }
 
     BigInt aTmp2 = rVal.MakeBig();
-    MakeBig().AddLong(aTmp2, *this);
+    MakeBig().AddBig(aTmp2, *this);
     Normalize();
     return *this;
 }
 
 BigInt& BigInt::operator-=( const BigInt& rVal )
 {
-    if ( nLen == 0 && rVal.nLen == 0 )
+    if (!IsBig() && !rVal.IsBig())
     {
         if ( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG &&
              nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
@@ -571,7 +541,7 @@ BigInt& BigInt::operator-=( const BigInt& rVal )
     }
 
     BigInt aTmp2 = rVal.MakeBig();
-    MakeBig().SubLong(aTmp2, *this);
+    MakeBig().SubBig(aTmp2, *this);
     Normalize();
     return *this;
 }
@@ -581,7 +551,7 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
     static const sal_Int32 MY_MAXSHORT = 0x00007fff;
     static const sal_Int32 MY_MINSHORT = -MY_MAXSHORT;
 
-    if ( nLen == 0 && rVal.nLen == 0
+    if (!IsBig() && !rVal.IsBig()
          && nVal <= MY_MAXSHORT && rVal.nVal <= MY_MAXSHORT
          && nVal >= MY_MINSHORT && rVal.nVal >= MY_MINSHORT )
          // TODO: not optimal !!! W.P.
@@ -590,7 +560,7 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
     }
     else
     {
-        rVal.MakeBig().MultLong(MakeBig(), *this);
+        rVal.MakeBig().MultBig(MakeBig(), *this);
         Normalize();
     }
     return *this;
@@ -598,7 +568,7 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
 
 void BigInt::DivMod(const BigInt& rVal, bool bMod)
 {
-    if ( rVal.nLen == 0 )
+    if (!rVal.IsBig())
     {
         if ( rVal.nVal == 0 )
         {
@@ -613,7 +583,7 @@ void BigInt::DivMod(const BigInt& rVal, bool bMod)
             return;
         }
 
-        if ( nLen == 0 )
+        if (!IsBig())
         {
             // No overflows may occur here
             nVal = bMod ? nVal % rVal.nVal : nVal / rVal.nVal;
@@ -646,7 +616,7 @@ void BigInt::DivMod(const BigInt& rVal, bool bMod)
     }
 
     BigInt tmpA = MakeBig(), tmpB = rVal.MakeBig();
-    if (tmpA.ABS_IsLessLong(tmpB))
+    if (tmpA.ABS_IsLessBig(tmpB))
     {
         if (!bMod)
             *this = 0;
@@ -654,7 +624,7 @@ void BigInt::DivMod(const BigInt& rVal, bool bMod)
     }
 
     // Divide BigInt with BigInt
-    tmpA.DivModLong(tmpB, *this, bMod);
+    tmpA.DivModBig(tmpB, *this, bMod);
 }
 
 BigInt& BigInt::operator/=( const BigInt& rVal )
@@ -673,7 +643,7 @@ BigInt& BigInt::operator%=( const BigInt& rVal )
 
 bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
 {
-    if (rVal1.IsLong() && rVal2.IsLong())
+    if (!rVal1.IsBig() && !rVal2.IsBig())
         return rVal1.nVal == rVal2.nVal;
 
     BigInt nA = rVal1.MakeBig(), nB = rVal2.MakeBig();
@@ -683,7 +653,7 @@ bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
 
 std::strong_ordering operator<=>(const BigInt& rVal1, const BigInt& rVal2)
 {
-    if (rVal1.IsLong() && rVal2.IsLong())
+    if (!rVal1.IsBig() && !rVal2.IsBig())
         return rVal1.nVal <=> rVal2.nVal;
 
     BigInt nA = rVal1.MakeBig(), nB = rVal2.MakeBig();
diff --git a/vcl/source/control/longcurr.cxx b/vcl/source/control/longcurr.cxx
index 1d942d1e5608..ee9451d79655 100644
--- a/vcl/source/control/longcurr.cxx
+++ b/vcl/source/control/longcurr.cxx
@@ -56,11 +56,9 @@ OUString ImplGetCurr( const LocaleDataWrapper& 
rLocaleDataWrapper, const BigInt
         return rLocaleDataWrapper.getCurr( static_cast<tools::Long>(rNumber), 
nDigits, rCurrSymbol, bShowThousandSep );
 
     BigInt aTmp( ImplPower10( nDigits ) );
-    BigInt aInteger( rNumber );
-    aInteger.Abs();
+    BigInt aInteger(rNumber.Abs());
+    BigInt aFraction(aInteger);
     aInteger  /= aTmp;
-    BigInt aFraction( rNumber );
-    aFraction.Abs();
     aFraction %= aTmp;
     if ( !aInteger.IsZero() )
     {

Reply via email to