diff options
Diffstat (limited to 'sc/source/core/tool/scmatrix.cxx')
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx new file mode 100644 index 000000000000..fbb859b64ebf --- /dev/null +++ b/sc/source/core/tool/scmatrix.cxx @@ -0,0 +1,854 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include <tools/debug.hxx> + +#include "scmatrix.hxx" +#include "global.hxx" +#include "address.hxx" +#include "formula/errorcodes.hxx" +#include "interpre.hxx" +#include <svl/zforlist.hxx> +#include <tools/stream.hxx> +#include <rtl/math.hxx> + +#include <math.h> + +//------------------------------------------------------------------------ + +void ScMatrix::CreateMatrix(SCSIZE nC, SCSIZE nR) // nur fuer ctor +{ + pErrorInterpreter = NULL; + nColCount = nC; + nRowCount = nR; + SCSIZE nCount = nColCount * nRowCount; + if ( !nCount || nCount > GetElementsMax() ) + { + DBG_ERRORFILE("ScMatrix::CreateMatrix: dimension error"); + nColCount = nRowCount = 1; + pMat = new ScMatrixValue[1]; + pMat[0].fVal = CreateDoubleError( errStackOverflow); + } + else + pMat = new ScMatrixValue[nCount]; + mnValType = NULL; + mnNonValue = 0; +} + +void ScMatrix::Clear() +{ + DeleteIsString(); + delete [] pMat; +} + +ScMatrix::~ScMatrix() +{ + Clear(); +} + +ScMatrix* ScMatrix::Clone() const +{ + ScMatrix* pScMat = new ScMatrix( nColCount, nRowCount); + MatCopy(*pScMat); + pScMat->SetErrorInterpreter( pErrorInterpreter); // TODO: really? + return pScMat; +} + +void ScMatrix::Resize( SCSIZE nC, SCSIZE nR) +{ + Clear(); + CreateMatrix(nC, nR); +} + +ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const +{ + ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows); + MatCopy(*pScMat); + pScMat->SetErrorInterpreter( pErrorInterpreter); + return pScMat; +} + +void ScMatrix::SetErrorAtInterpreter( USHORT nError ) const +{ + if ( pErrorInterpreter ) + pErrorInterpreter->SetError( nError); +} + +// +// File format: USHORT columns, USHORT rows, (columns*rows) entries: +// BYTE type ( CELLTYPE_NONE, CELLTYPE_VALUE, CELLTYPE_STRING ); nothing, double or String +// + +ScMatrix::ScMatrix(SvStream& /* rStream */) + : pErrorInterpreter( NULL) + , nRefCnt(0) +{ +#if SC_ROWLIMIT_STREAM_ACCESS +#error address types changed! + USHORT nC; + USHORT nR; + + rStream >> nC; + rStream >> nR; + + CreateMatrix(nC, nR); + DBG_ASSERT( pMat, "pMat == NULL" ); + + String aMatStr; + double fVal; + rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); + SCSIZE nCount = nColCount * nRowCount; + SCSIZE nReadCount = (SCSIZE) nC * nR; + for (SCSIZE i=0; i<nReadCount; i++) + { + BYTE nType; + rStream >> nType; + if ( nType == CELLTYPE_VALUE ) + { + if ( i < nCount ) + rStream >> pMat[i].fVal; + else + rStream >> fVal; + } + else + { + // For unknown types read and forget string (upwards compatibility) + + if ( nType != CELLTYPE_NONE ) + rStream.ReadByteString( aMatStr, eCharSet ); + + if ( i < nCount ) + { + if (!mnValType) + ResetIsString(); // init string flags + mnValType[i] = ( nType == CELLTYPE_NONE ? SC_MATVAL_EMPTY : SC_MATVAL_STRING ); + mnNonValue++; + + if ( nType == CELLTYPE_STRING ) + pMat[i].pS = new String(aMatStr); + else + pMat[i].pS = NULL; + } + } + } +#else + CreateMatrix(0,0); +#endif // SC_ROWLIMIT_STREAM_ACCESS +} + +void ScMatrix::Store(SvStream& /* rStream */) const +{ +#if SC_ROWLIMIT_STREAM_ACCESS +#error address types changed! + SCSIZE nCount = nColCount * nRowCount; + // Don't store matrix with more than USHORT max elements, old versions + // might get confused in loops for(USHORT i=0; i<nC*nR; i++) + if ( !pMat || nCount > ((USHORT)(~0)) ) + { + DBG_ASSERT( pMat, "ScMatrix::Store: pMat == NULL" ); + // We can't store a 0 dimension because old versions rely on some + // matrix being present, e.g. DDE link results, and old versions didn't + // create a matrix if dimension was 0. Store an error result. + rStream << (USHORT) 1; + rStream << (USHORT) 1; + rStream << (BYTE) CELLTYPE_VALUE; + double fVal; + ::rtl::math::setNan( &fVal ); + rStream << fVal; + return; + } + + rStream << (USHORT) nColCount; +#if SC_ROWLIMIT_MORE_THAN_32K + #error row32k +#endif + rStream << (USHORT) nRowCount; + + String aMatStr; + rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); + for (SCSIZE i=0; i<nCount; i++) + { + BYTE nType = CELLTYPE_VALUE; + if ( mnValType && IsNonValueType( mnValType[i])) + { + if ( pMat[i].pS ) + aMatStr = *pMat[i].pS; + else + aMatStr.Erase(); + + if ( mnValType[i] == SC_MATVAL_STRING ) + nType = CELLTYPE_STRING; + else + nType = CELLTYPE_NONE; + } + rStream << nType; + if ( nType == CELLTYPE_VALUE ) + rStream << pMat[i].fVal; + else if ( nType == CELLTYPE_STRING ) + rStream.WriteByteString( aMatStr, eCharSet ); + } +#endif // SC_ROWLIMIT_STREAM_ACCESS +} + +void ScMatrix::ResetIsString() +{ + SCSIZE nCount = nColCount * nRowCount; + if (mnValType) + { + for (SCSIZE i = 0; i < nCount; i++) + { + if ( IsNonValueType( mnValType[i])) + delete pMat[i].pS; + } + } + else + mnValType = new BYTE[nCount]; + memset( mnValType, 0, nCount * sizeof( BYTE ) ); + mnNonValue = 0; +} + +void ScMatrix::DeleteIsString() +{ + if ( mnValType ) + { + SCSIZE nCount = nColCount * nRowCount; + for ( SCSIZE i = 0; i < nCount; i++ ) + { + if (IsNonValueType( mnValType[i])) + delete pMat[i].pS; + } + delete [] mnValType; + mnValType = NULL; + mnNonValue = 0; + } +} + +void ScMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR) +{ + if (ValidColRow( nC, nR)) + PutDouble( fVal, CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::PutDouble: dimension error"); + } +} + +void ScMatrix::PutString(const String& rStr, SCSIZE nC, SCSIZE nR) +{ + if (ValidColRow( nC, nR)) + PutString( rStr, CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::PutString: dimension error"); + } +} + +void ScMatrix::PutString(const String& rStr, SCSIZE nIndex) +{ + if (mnValType == NULL) + ResetIsString(); + if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) + *(pMat[nIndex].pS) = rStr; + else + { + pMat[nIndex].pS = new String(rStr); + mnNonValue++; + } + mnValType[nIndex] = SC_MATVAL_STRING; +} + +void ScMatrix::PutStringEntry( const String* pStr, BYTE bFlag, SCSIZE nIndex ) +{ + DBG_ASSERT( bFlag, "ScMatrix::PutStringEntry: bFlag == 0" ); + if (mnValType == NULL) + ResetIsString(); + // Make sure all bytes of the union are initialized to be able to access + // the value with if (IsValueOrEmpty()) GetDouble(). Backup pS first. + String* pS = pMat[nIndex].pS; + pMat[nIndex].fVal = 0.0; + // An EMPTY or EMPTYPATH entry must not have a string pointer therefor. + DBG_ASSERT( (((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY) && !pStr) || TRUE, + "ScMatrix::PutStringEntry: pStr passed through EMPTY entry"); + if ( IsNonValueType( mnValType[nIndex]) && pS ) + { + if ((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY) + delete pS, pS = NULL; + if ( pStr ) + *pS = *pStr; + else if (pS) + pS->Erase(); + pMat[nIndex].pS = pS; + } + else + { + pMat[nIndex].pS = (pStr ? new String(*pStr) : NULL); + mnNonValue++; + } + mnValType[nIndex] = bFlag; +} + +void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR) +{ + if (ValidColRow( nC, nR)) + PutEmpty( CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::PutEmpty: dimension error"); + } +} + +void ScMatrix::PutEmpty(SCSIZE nIndex) +{ + if (mnValType == NULL) + ResetIsString(); + if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) + { + delete pMat[nIndex].pS; + } + else + { + mnNonValue++; + } + mnValType[nIndex] = SC_MATVAL_EMPTY; + pMat[nIndex].pS = NULL; + pMat[nIndex].fVal = 0.0; +} + +void ScMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR) +{ + if (ValidColRow( nC, nR)) + PutEmptyPath( CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::PutEmptyPath: dimension error"); + } +} + +void ScMatrix::PutEmptyPath(SCSIZE nIndex) +{ + if (mnValType == NULL) + ResetIsString(); + if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) + { + delete pMat[nIndex].pS; + } + else + { + mnNonValue++; + } + mnValType[nIndex] = SC_MATVAL_EMPTYPATH; + pMat[nIndex].pS = NULL; + pMat[nIndex].fVal = 0.0; +} + +void ScMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) +{ + if (ValidColRow( nC, nR)) + PutBoolean( bVal, CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::PutBoolean: dimension error"); + } +} + +void ScMatrix::PutBoolean( bool bVal, SCSIZE nIndex) +{ + if (mnValType == NULL) + ResetIsString(); + if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) + { + delete pMat[nIndex].pS; + mnNonValue--; + } + + mnValType[nIndex] = SC_MATVAL_BOOLEAN; + pMat[nIndex].pS = NULL; + pMat[nIndex].fVal = bVal ? 1. : 0.; +} + +USHORT ScMatrix::GetError( SCSIZE nC, SCSIZE nR) const +{ + if (ValidColRowOrReplicated( nC, nR )) + return GetError( CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::GetError: dimension error"); + return errNoValue; + } +} + +double ScMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const +{ + if (ValidColRowOrReplicated( nC, nR )) + return GetDouble( CalcOffset( nC, nR) ); + else + { + DBG_ERRORFILE("ScMatrix::GetDouble: dimension error"); + return CreateDoubleError( errNoValue); + } +} + +const String& ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const +{ + if (ValidColRowOrReplicated( nC, nR )) + { + SCSIZE nIndex = CalcOffset( nC, nR); + if ( IsString( nIndex ) ) + return GetString( nIndex ); + else + { + SetErrorAtInterpreter( GetError( nIndex)); + DBG_ERRORFILE("ScMatrix::GetString: access error, no string"); + } + } + else + { + DBG_ERRORFILE("ScMatrix::GetString: dimension error"); + } + return ScGlobal::GetEmptyString(); +} + + +String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nIndex) const +{ + if (IsString( nIndex)) + { + if (IsEmptyPath( nIndex)) + { // result of empty FALSE jump path + ULONG nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_LOGICAL, + ScGlobal::eLnge); + String aStr; + Color* pColor = NULL; + rFormatter.GetOutputString( 0.0, nKey, aStr, &pColor); + return aStr; + } + return GetString( nIndex ); + } + + USHORT nError = GetError( nIndex); + if (nError) + { + SetErrorAtInterpreter( nError); + return ScGlobal::GetErrorString( nError); + } + + double fVal= GetDouble( nIndex); + ULONG nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + String aStr; + rFormatter.GetInputLineString( fVal, nKey, aStr); + return aStr; +} + + +String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const +{ + if (ValidColRowOrReplicated( nC, nR )) + { + SCSIZE nIndex = CalcOffset( nC, nR); + return GetString( rFormatter, nIndex); + } + else + { + DBG_ERRORFILE("ScMatrix::GetString: dimension error"); + } + return String(); +} + + +const ScMatrixValue* ScMatrix::Get(SCSIZE nC, SCSIZE nR, ScMatValType& nType) const +{ + if (ValidColRowOrReplicated( nC, nR )) + { + SCSIZE nIndex = CalcOffset( nC, nR); + if (mnValType) + nType = mnValType[nIndex]; + else + nType = SC_MATVAL_VALUE; + return &pMat[nIndex]; + } + else + { + DBG_ERRORFILE("ScMatrix::Get: dimension error"); + } + nType = SC_MATVAL_EMPTY; + return NULL; +} + +void ScMatrix::MatCopy(ScMatrix& mRes) const +{ + if (nColCount > mRes.nColCount || nRowCount > mRes.nRowCount) + { + DBG_ERRORFILE("ScMatrix::MatCopy: dimension error"); + } + else if ( nColCount == mRes.nColCount && nRowCount == mRes.nRowCount ) + { + if (mnValType) + { + ScMatValType nType; + mRes.ResetIsString(); + for (SCSIZE i = 0; i < nColCount; i++) + { + SCSIZE nStart = i * nRowCount; + for (SCSIZE j = 0; j < nRowCount; j++) + { + if (IsNonValueType( (nType = mnValType[nStart+j]))) + mRes.PutStringEntry( pMat[nStart+j].pS, nType, nStart+j ); + else + { + mRes.pMat[nStart+j].fVal = pMat[nStart+j].fVal; + mRes.mnValType[nStart+j] = nType; + } + } + } + } + else + { + mRes.DeleteIsString(); + SCSIZE nCount = nColCount * nRowCount; + for (SCSIZE i = 0; i < nCount; i++) + mRes.pMat[i].fVal = pMat[i].fVal; + } + } + else + { + // Copy this matrix to upper left rectangle of result matrix. + if (mnValType) + { + ScMatValType nType; + mRes.ResetIsString(); + for (SCSIZE i = 0; i < nColCount; i++) + { + SCSIZE nStart = i * nRowCount; + SCSIZE nResStart = i * mRes.nRowCount; + for (SCSIZE j = 0; j < nRowCount; j++) + { + if (IsNonValueType( (nType = mnValType[nStart+j]))) + mRes.PutStringEntry( pMat[nStart+j].pS, nType, nResStart+j ); + else + { + mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal; + mRes.mnValType[nResStart+j] = nType; + } + } + } + } + else + { + mRes.DeleteIsString(); + for (SCSIZE i = 0; i < nColCount; i++) + { + SCSIZE nStart = i * nRowCount; + SCSIZE nResStart = i * mRes.nRowCount; + for (SCSIZE j = 0; j < nRowCount; j++) + mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal; + } + } + } +} + +void ScMatrix::MatTrans(ScMatrix& mRes) const +{ + if (nColCount != mRes.nRowCount || nRowCount != mRes.nColCount) + { + DBG_ERRORFILE("ScMatrix::MatTrans: dimension error"); + } + else + { + if (mnValType) + { + ScMatValType nType; + mRes.ResetIsString(); + for ( SCSIZE i = 0; i < nColCount; i++ ) + { + SCSIZE nStart = i * nRowCount; + for ( SCSIZE j = 0; j < nRowCount; j++ ) + { + if (IsNonValueType( (nType = mnValType[nStart+j]))) + mRes.PutStringEntry( pMat[nStart+j].pS, nType, j*mRes.nRowCount+i ); + else + { + mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal; + mRes.mnValType[j*mRes.nRowCount+i] = nType; + } + } + } + } + else + { + mRes.DeleteIsString(); + for ( SCSIZE i = 0; i < nColCount; i++ ) + { + SCSIZE nStart = i * nRowCount; + for ( SCSIZE j = 0; j < nRowCount; j++ ) + { + mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal; + } + } + } + } +} + +//UNUSED2009-05 void ScMatrix::MatCopyUpperLeft(ScMatrix& mRes) const +//UNUSED2009-05 { +//UNUSED2009-05 if (nColCount < mRes.nColCount || nRowCount < mRes.nRowCount) +//UNUSED2009-05 { +//UNUSED2009-05 DBG_ERRORFILE("ScMatrix::MatCopyUpperLeft: dimension error"); +//UNUSED2009-05 } +//UNUSED2009-05 else +//UNUSED2009-05 { +//UNUSED2009-05 if (mnValType) +//UNUSED2009-05 { +//UNUSED2009-05 ScMatValType nType; +//UNUSED2009-05 mRes.ResetIsString(); +//UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ ) +//UNUSED2009-05 { +//UNUSED2009-05 SCSIZE nStart = i * nRowCount; +//UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ ) +//UNUSED2009-05 { +//UNUSED2009-05 if ( IsNonValueType( (nType = mnValType[nStart+j]) )) +//UNUSED2009-05 mRes.PutStringEntry( pMat[nStart+j].pS, nType, +//UNUSED2009-05 i*mRes.nRowCount+j ); +//UNUSED2009-05 else +//UNUSED2009-05 { +//UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal; +//UNUSED2009-05 mRes.mnValType[i*mRes.nRowCount+j] = nType; +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 else +//UNUSED2009-05 { +//UNUSED2009-05 mRes.DeleteIsString(); +//UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ ) +//UNUSED2009-05 { +//UNUSED2009-05 SCSIZE nStart = i * nRowCount; +//UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ ) +//UNUSED2009-05 { +//UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal; +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 } +//UNUSED2009-05 } + +void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) +{ + if (ValidColRow( nC1, nR1) && ValidColRow( nC2, nR2)) + { + if ( nC1 == 0 && nR1 == 0 && nC2 == nColCount-1 && nR2 == nRowCount-1 ) + { + SCSIZE nEnd = nColCount * nRowCount; + for ( SCSIZE j=0; j<nEnd; j++ ) + pMat[j].fVal = fVal; + } + else + { + for ( SCSIZE i=nC1; i<=nC2; i++ ) + { + SCSIZE nOff1 = i * nRowCount + nR1; + SCSIZE nOff2 = nOff1 + nR2 - nR1; + for ( SCSIZE j=nOff1; j<=nOff2; j++ ) + pMat[j].fVal = fVal; + } + } + } + else + { + DBG_ERRORFILE("ScMatrix::FillDouble: dimension error"); + } +} + +void ScMatrix::CompareEqual() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal == 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal == 0.0); + } +} + +void ScMatrix::CompareNotEqual() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal != 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal != 0.0); + } +} + +void ScMatrix::CompareLess() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal < 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal < 0.0); + } +} + +void ScMatrix::CompareGreater() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal > 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal > 0.0); + } +} + +void ScMatrix::CompareLessEqual() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal <= 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal <= 0.0); + } +} + +void ScMatrix::CompareGreaterEqual() +{ + SCSIZE n = nColCount * nRowCount; + if ( mnValType ) + { + for ( SCSIZE j=0; j<n; j++ ) + if ( IsValueType( mnValType[j]) ) // else: #WERT! + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal >= 0.0); + } + else + { + for ( SCSIZE j=0; j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError + pMat[j].fVal = (pMat[j].fVal >= 0.0); + } +} + +double ScMatrix::And() +{ + SCSIZE n = nColCount * nRowCount; + bool bAnd = true; + if ( mnValType ) + { + for ( SCSIZE j=0; bAnd && j<n; j++ ) + { + if ( !IsValueType( mnValType[j]) ) + { // assuming a CompareMat this is an error + return CreateDoubleError( errIllegalArgument ); + } + else if ( ::rtl::math::isFinite( pMat[j].fVal)) + bAnd = (pMat[j].fVal != 0.0); + else + return pMat[j].fVal; // DoubleError + } + } + else + { + for ( SCSIZE j=0; bAnd && j<n; j++ ) + { + if ( ::rtl::math::isFinite( pMat[j].fVal)) + bAnd = (pMat[j].fVal != 0.0); + else + return pMat[j].fVal; // DoubleError + } + } + return bAnd; +} + +double ScMatrix::Or() +{ + SCSIZE n = nColCount * nRowCount; + bool bOr = false; + if ( mnValType ) + { + for ( SCSIZE j=0; !bOr && j<n; j++ ) + if ( !IsValueType( mnValType[j]) ) + { // assuming a CompareMat this is an error + return CreateDoubleError( errIllegalArgument ); + } + else if ( ::rtl::math::isFinite( pMat[j].fVal)) + bOr = (pMat[j].fVal != 0.0); + else + return pMat[j].fVal; // DoubleError + } + else + { + for ( SCSIZE j=0; !bOr && j<n; j++ ) + if ( ::rtl::math::isFinite( pMat[j].fVal)) + bOr = (pMat[j].fVal != 0.0); + else + return pMat[j].fVal; // DoubleError + } + return bOr; +} + |