| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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; |
| } |
| |
| ScMatrix* ScMatrix::CloneIfConst() |
| { |
| return (mbCloneIfConst || IsEternalRef()) ? Clone() : this; |
| } |
| |
| 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( sal_uInt16 nError ) const |
| { |
| if ( pErrorInterpreter ) |
| pErrorInterpreter->SetError( nError); |
| } |
| |
| // |
| // File format: sal_uInt16 columns, sal_uInt16 rows, (columns*rows) entries: |
| // sal_uInt8 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! |
| sal_uInt16 nC; |
| sal_uInt16 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++) |
| { |
| sal_uInt8 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 sal_uInt16 max elements, old versions |
| // might get confused in loops for(sal_uInt16 i=0; i<nC*nR; i++) |
| if ( !pMat || nCount > ((sal_uInt16)(~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 << (sal_uInt16) 1; |
| rStream << (sal_uInt16) 1; |
| rStream << (sal_uInt8) CELLTYPE_VALUE; |
| double fVal; |
| ::rtl::math::setNan( &fVal ); |
| rStream << fVal; |
| return; |
| } |
| |
| rStream << (sal_uInt16) nColCount; |
| #if SC_ROWLIMIT_MORE_THAN_32K |
| #error row32k |
| #endif |
| rStream << (sal_uInt16) nRowCount; |
| |
| String aMatStr; |
| rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); |
| for (SCSIZE i=0; i<nCount; i++) |
| { |
| sal_uInt8 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 sal_uInt8[nCount]; |
| memset( mnValType, 0, nCount * sizeof( sal_uInt8 ) ); |
| 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, sal_uInt8 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) || sal_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.; |
| } |
| |
| sal_uInt16 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 sal_False jump path |
| sal_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 ); |
| } |
| |
| sal_uInt16 nError = GetError( nIndex); |
| if (nError) |
| { |
| SetErrorAtInterpreter( nError); |
| return ScGlobal::GetErrorString( nError); |
| } |
| |
| double fVal= GetDouble( nIndex); |
| sal_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; |
| } |
| |
| // @Author Marina Plakalovic |
| // Computes the logical XOR of elements |
| double ScMatrix::Xor() |
| { |
| SCSIZE n = nColCount * nRowCount; |
| bool bXor = false; |
| if ( mnValType ) |
| { |
| for ( SCSIZE j=0; 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)) |
| bXor ^= (pMat[j].fVal != 0.0); |
| else |
| return pMat[j].fVal; // DoubleError |
| } |
| else |
| { |
| for ( SCSIZE j=0; j<n; j++ ) |
| if ( ::rtl::math::isFinite( pMat[j].fVal)) |
| bXor ^= (pMat[j].fVal != 0.0); |
| else |
| return pMat[j].fVal; // DoubleError |
| } |
| return bXor; |
| } |