1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 #include <tools/debug.hxx> 28 29 #include "scmatrix.hxx" 30 #include "global.hxx" 31 #include "address.hxx" 32 #include "formula/errorcodes.hxx" 33 #include "interpre.hxx" 34 #include <svl/zforlist.hxx> 35 #include <tools/stream.hxx> 36 #include <rtl/math.hxx> 37 38 #include <math.h> 39 40 //------------------------------------------------------------------------ 41 42 void ScMatrix::CreateMatrix(SCSIZE nC, SCSIZE nR) // nur fuer ctor 43 { 44 pErrorInterpreter = NULL; 45 nColCount = nC; 46 nRowCount = nR; 47 SCSIZE nCount = nColCount * nRowCount; 48 if ( !nCount || nCount > GetElementsMax() ) 49 { 50 DBG_ERRORFILE("ScMatrix::CreateMatrix: dimension error"); 51 nColCount = nRowCount = 1; 52 pMat = new ScMatrixValue[1]; 53 pMat[0].fVal = CreateDoubleError( errStackOverflow); 54 } 55 else 56 pMat = new ScMatrixValue[nCount]; 57 mnValType = NULL; 58 mnNonValue = 0; 59 } 60 61 void ScMatrix::Clear() 62 { 63 DeleteIsString(); 64 delete [] pMat; 65 } 66 67 ScMatrix::~ScMatrix() 68 { 69 Clear(); 70 } 71 72 ScMatrix* ScMatrix::Clone() const 73 { 74 ScMatrix* pScMat = new ScMatrix( nColCount, nRowCount); 75 MatCopy(*pScMat); 76 pScMat->SetErrorInterpreter( pErrorInterpreter); // TODO: really? 77 return pScMat; 78 } 79 80 ScMatrix* ScMatrix::CloneIfConst() 81 { 82 return (mbCloneIfConst || IsEternalRef()) ? Clone() : this; 83 } 84 85 void ScMatrix::Resize( SCSIZE nC, SCSIZE nR) 86 { 87 Clear(); 88 CreateMatrix(nC, nR); 89 } 90 91 ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const 92 { 93 ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows); 94 MatCopy(*pScMat); 95 pScMat->SetErrorInterpreter( pErrorInterpreter); 96 return pScMat; 97 } 98 99 void ScMatrix::SetErrorAtInterpreter( sal_uInt16 nError ) const 100 { 101 if ( pErrorInterpreter ) 102 pErrorInterpreter->SetError( nError); 103 } 104 105 // 106 // File format: sal_uInt16 columns, sal_uInt16 rows, (columns*rows) entries: 107 // sal_uInt8 type ( CELLTYPE_NONE, CELLTYPE_VALUE, CELLTYPE_STRING ); nothing, double or String 108 // 109 110 ScMatrix::ScMatrix(SvStream& /* rStream */) 111 : pErrorInterpreter( NULL) 112 , nRefCnt(0) 113 { 114 #if SC_ROWLIMIT_STREAM_ACCESS 115 #error address types changed! 116 sal_uInt16 nC; 117 sal_uInt16 nR; 118 119 rStream >> nC; 120 rStream >> nR; 121 122 CreateMatrix(nC, nR); 123 DBG_ASSERT( pMat, "pMat == NULL" ); 124 125 String aMatStr; 126 double fVal; 127 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); 128 SCSIZE nCount = nColCount * nRowCount; 129 SCSIZE nReadCount = (SCSIZE) nC * nR; 130 for (SCSIZE i=0; i<nReadCount; i++) 131 { 132 sal_uInt8 nType; 133 rStream >> nType; 134 if ( nType == CELLTYPE_VALUE ) 135 { 136 if ( i < nCount ) 137 rStream >> pMat[i].fVal; 138 else 139 rStream >> fVal; 140 } 141 else 142 { 143 // For unknown types read and forget string (upwards compatibility) 144 145 if ( nType != CELLTYPE_NONE ) 146 rStream.ReadByteString( aMatStr, eCharSet ); 147 148 if ( i < nCount ) 149 { 150 if (!mnValType) 151 ResetIsString(); // init string flags 152 mnValType[i] = ( nType == CELLTYPE_NONE ? SC_MATVAL_EMPTY : SC_MATVAL_STRING ); 153 mnNonValue++; 154 155 if ( nType == CELLTYPE_STRING ) 156 pMat[i].pS = new String(aMatStr); 157 else 158 pMat[i].pS = NULL; 159 } 160 } 161 } 162 #else 163 CreateMatrix(0,0); 164 #endif // SC_ROWLIMIT_STREAM_ACCESS 165 } 166 167 void ScMatrix::Store(SvStream& /* rStream */) const 168 { 169 #if SC_ROWLIMIT_STREAM_ACCESS 170 #error address types changed! 171 SCSIZE nCount = nColCount * nRowCount; 172 // Don't store matrix with more than sal_uInt16 max elements, old versions 173 // might get confused in loops for(sal_uInt16 i=0; i<nC*nR; i++) 174 if ( !pMat || nCount > ((sal_uInt16)(~0)) ) 175 { 176 DBG_ASSERT( pMat, "ScMatrix::Store: pMat == NULL" ); 177 // We can't store a 0 dimension because old versions rely on some 178 // matrix being present, e.g. DDE link results, and old versions didn't 179 // create a matrix if dimension was 0. Store an error result. 180 rStream << (sal_uInt16) 1; 181 rStream << (sal_uInt16) 1; 182 rStream << (sal_uInt8) CELLTYPE_VALUE; 183 double fVal; 184 ::rtl::math::setNan( &fVal ); 185 rStream << fVal; 186 return; 187 } 188 189 rStream << (sal_uInt16) nColCount; 190 #if SC_ROWLIMIT_MORE_THAN_32K 191 #error row32k 192 #endif 193 rStream << (sal_uInt16) nRowCount; 194 195 String aMatStr; 196 rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); 197 for (SCSIZE i=0; i<nCount; i++) 198 { 199 sal_uInt8 nType = CELLTYPE_VALUE; 200 if ( mnValType && IsNonValueType( mnValType[i])) 201 { 202 if ( pMat[i].pS ) 203 aMatStr = *pMat[i].pS; 204 else 205 aMatStr.Erase(); 206 207 if ( mnValType[i] == SC_MATVAL_STRING ) 208 nType = CELLTYPE_STRING; 209 else 210 nType = CELLTYPE_NONE; 211 } 212 rStream << nType; 213 if ( nType == CELLTYPE_VALUE ) 214 rStream << pMat[i].fVal; 215 else if ( nType == CELLTYPE_STRING ) 216 rStream.WriteByteString( aMatStr, eCharSet ); 217 } 218 #endif // SC_ROWLIMIT_STREAM_ACCESS 219 } 220 221 void ScMatrix::ResetIsString() 222 { 223 SCSIZE nCount = nColCount * nRowCount; 224 if (mnValType) 225 { 226 for (SCSIZE i = 0; i < nCount; i++) 227 { 228 if ( IsNonValueType( mnValType[i])) 229 delete pMat[i].pS; 230 } 231 } 232 else 233 mnValType = new sal_uInt8[nCount]; 234 memset( mnValType, 0, nCount * sizeof( sal_uInt8 ) ); 235 mnNonValue = 0; 236 } 237 238 void ScMatrix::DeleteIsString() 239 { 240 if ( mnValType ) 241 { 242 SCSIZE nCount = nColCount * nRowCount; 243 for ( SCSIZE i = 0; i < nCount; i++ ) 244 { 245 if (IsNonValueType( mnValType[i])) 246 delete pMat[i].pS; 247 } 248 delete [] mnValType; 249 mnValType = NULL; 250 mnNonValue = 0; 251 } 252 } 253 254 void ScMatrix::PutDouble(double fVal, SCSIZE nC, SCSIZE nR) 255 { 256 if (ValidColRow( nC, nR)) 257 PutDouble( fVal, CalcOffset( nC, nR) ); 258 else 259 { 260 DBG_ERRORFILE("ScMatrix::PutDouble: dimension error"); 261 } 262 } 263 264 void ScMatrix::PutString(const String& rStr, SCSIZE nC, SCSIZE nR) 265 { 266 if (ValidColRow( nC, nR)) 267 PutString( rStr, CalcOffset( nC, nR) ); 268 else 269 { 270 DBG_ERRORFILE("ScMatrix::PutString: dimension error"); 271 } 272 } 273 274 void ScMatrix::PutString(const String& rStr, SCSIZE nIndex) 275 { 276 if (mnValType == NULL) 277 ResetIsString(); 278 if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) 279 *(pMat[nIndex].pS) = rStr; 280 else 281 { 282 pMat[nIndex].pS = new String(rStr); 283 mnNonValue++; 284 } 285 mnValType[nIndex] = SC_MATVAL_STRING; 286 } 287 288 void ScMatrix::PutStringEntry( const String* pStr, sal_uInt8 bFlag, SCSIZE nIndex ) 289 { 290 DBG_ASSERT( bFlag, "ScMatrix::PutStringEntry: bFlag == 0" ); 291 if (mnValType == NULL) 292 ResetIsString(); 293 // Make sure all bytes of the union are initialized to be able to access 294 // the value with if (IsValueOrEmpty()) GetDouble(). Backup pS first. 295 String* pS = pMat[nIndex].pS; 296 pMat[nIndex].fVal = 0.0; 297 // An EMPTY or EMPTYPATH entry must not have a string pointer therefor. 298 DBG_ASSERT( (((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY) && !pStr) || sal_True, 299 "ScMatrix::PutStringEntry: pStr passed through EMPTY entry"); 300 if ( IsNonValueType( mnValType[nIndex]) && pS ) 301 { 302 if ((bFlag & SC_MATVAL_EMPTY) == SC_MATVAL_EMPTY) 303 delete pS, pS = NULL; 304 if ( pStr ) 305 *pS = *pStr; 306 else if (pS) 307 pS->Erase(); 308 pMat[nIndex].pS = pS; 309 } 310 else 311 { 312 pMat[nIndex].pS = (pStr ? new String(*pStr) : NULL); 313 mnNonValue++; 314 } 315 mnValType[nIndex] = bFlag; 316 } 317 318 void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR) 319 { 320 if (ValidColRow( nC, nR)) 321 PutEmpty( CalcOffset( nC, nR) ); 322 else 323 { 324 DBG_ERRORFILE("ScMatrix::PutEmpty: dimension error"); 325 } 326 } 327 328 void ScMatrix::PutEmpty(SCSIZE nIndex) 329 { 330 if (mnValType == NULL) 331 ResetIsString(); 332 if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) 333 { 334 delete pMat[nIndex].pS; 335 } 336 else 337 { 338 mnNonValue++; 339 } 340 mnValType[nIndex] = SC_MATVAL_EMPTY; 341 pMat[nIndex].pS = NULL; 342 pMat[nIndex].fVal = 0.0; 343 } 344 345 void ScMatrix::PutEmptyPath(SCSIZE nC, SCSIZE nR) 346 { 347 if (ValidColRow( nC, nR)) 348 PutEmptyPath( CalcOffset( nC, nR) ); 349 else 350 { 351 DBG_ERRORFILE("ScMatrix::PutEmptyPath: dimension error"); 352 } 353 } 354 355 void ScMatrix::PutEmptyPath(SCSIZE nIndex) 356 { 357 if (mnValType == NULL) 358 ResetIsString(); 359 if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) 360 { 361 delete pMat[nIndex].pS; 362 } 363 else 364 { 365 mnNonValue++; 366 } 367 mnValType[nIndex] = SC_MATVAL_EMPTYPATH; 368 pMat[nIndex].pS = NULL; 369 pMat[nIndex].fVal = 0.0; 370 } 371 372 void ScMatrix::PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR) 373 { 374 if (ValidColRow( nC, nR)) 375 PutBoolean( bVal, CalcOffset( nC, nR) ); 376 else 377 { 378 DBG_ERRORFILE("ScMatrix::PutBoolean: dimension error"); 379 } 380 } 381 382 void ScMatrix::PutBoolean( bool bVal, SCSIZE nIndex) 383 { 384 if (mnValType == NULL) 385 ResetIsString(); 386 if ( IsNonValueType( mnValType[nIndex]) && pMat[nIndex].pS ) 387 { 388 delete pMat[nIndex].pS; 389 mnNonValue--; 390 } 391 392 mnValType[nIndex] = SC_MATVAL_BOOLEAN; 393 pMat[nIndex].pS = NULL; 394 pMat[nIndex].fVal = bVal ? 1. : 0.; 395 } 396 397 sal_uInt16 ScMatrix::GetError( SCSIZE nC, SCSIZE nR) const 398 { 399 if (ValidColRowOrReplicated( nC, nR )) 400 return GetError( CalcOffset( nC, nR) ); 401 else 402 { 403 DBG_ERRORFILE("ScMatrix::GetError: dimension error"); 404 return errNoValue; 405 } 406 } 407 408 double ScMatrix::GetDouble(SCSIZE nC, SCSIZE nR) const 409 { 410 if (ValidColRowOrReplicated( nC, nR )) 411 return GetDouble( CalcOffset( nC, nR) ); 412 else 413 { 414 DBG_ERRORFILE("ScMatrix::GetDouble: dimension error"); 415 return CreateDoubleError( errNoValue); 416 } 417 } 418 419 const String& ScMatrix::GetString(SCSIZE nC, SCSIZE nR) const 420 { 421 if (ValidColRowOrReplicated( nC, nR )) 422 { 423 SCSIZE nIndex = CalcOffset( nC, nR); 424 if ( IsString( nIndex ) ) 425 return GetString( nIndex ); 426 else 427 { 428 SetErrorAtInterpreter( GetError( nIndex)); 429 DBG_ERRORFILE("ScMatrix::GetString: access error, no string"); 430 } 431 } 432 else 433 { 434 DBG_ERRORFILE("ScMatrix::GetString: dimension error"); 435 } 436 return ScGlobal::GetEmptyString(); 437 } 438 439 440 String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nIndex) const 441 { 442 if (IsString( nIndex)) 443 { 444 if (IsEmptyPath( nIndex)) 445 { // result of empty sal_False jump path 446 sal_uLong nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_LOGICAL, 447 ScGlobal::eLnge); 448 String aStr; 449 Color* pColor = NULL; 450 rFormatter.GetOutputString( 0.0, nKey, aStr, &pColor); 451 return aStr; 452 } 453 return GetString( nIndex ); 454 } 455 456 sal_uInt16 nError = GetError( nIndex); 457 if (nError) 458 { 459 SetErrorAtInterpreter( nError); 460 return ScGlobal::GetErrorString( nError); 461 } 462 463 double fVal= GetDouble( nIndex); 464 sal_uLong nKey = rFormatter.GetStandardFormat( NUMBERFORMAT_NUMBER, 465 ScGlobal::eLnge); 466 String aStr; 467 rFormatter.GetInputLineString( fVal, nKey, aStr); 468 return aStr; 469 } 470 471 472 String ScMatrix::GetString( SvNumberFormatter& rFormatter, SCSIZE nC, SCSIZE nR) const 473 { 474 if (ValidColRowOrReplicated( nC, nR )) 475 { 476 SCSIZE nIndex = CalcOffset( nC, nR); 477 return GetString( rFormatter, nIndex); 478 } 479 else 480 { 481 DBG_ERRORFILE("ScMatrix::GetString: dimension error"); 482 } 483 return String(); 484 } 485 486 487 const ScMatrixValue* ScMatrix::Get(SCSIZE nC, SCSIZE nR, ScMatValType& nType) const 488 { 489 if (ValidColRowOrReplicated( nC, nR )) 490 { 491 SCSIZE nIndex = CalcOffset( nC, nR); 492 if (mnValType) 493 nType = mnValType[nIndex]; 494 else 495 nType = SC_MATVAL_VALUE; 496 return &pMat[nIndex]; 497 } 498 else 499 { 500 DBG_ERRORFILE("ScMatrix::Get: dimension error"); 501 } 502 nType = SC_MATVAL_EMPTY; 503 return NULL; 504 } 505 506 void ScMatrix::MatCopy(ScMatrix& mRes) const 507 { 508 if (nColCount > mRes.nColCount || nRowCount > mRes.nRowCount) 509 { 510 DBG_ERRORFILE("ScMatrix::MatCopy: dimension error"); 511 } 512 else if ( nColCount == mRes.nColCount && nRowCount == mRes.nRowCount ) 513 { 514 if (mnValType) 515 { 516 ScMatValType nType; 517 mRes.ResetIsString(); 518 for (SCSIZE i = 0; i < nColCount; i++) 519 { 520 SCSIZE nStart = i * nRowCount; 521 for (SCSIZE j = 0; j < nRowCount; j++) 522 { 523 if (IsNonValueType( (nType = mnValType[nStart+j]))) 524 mRes.PutStringEntry( pMat[nStart+j].pS, nType, nStart+j ); 525 else 526 { 527 mRes.pMat[nStart+j].fVal = pMat[nStart+j].fVal; 528 mRes.mnValType[nStart+j] = nType; 529 } 530 } 531 } 532 } 533 else 534 { 535 mRes.DeleteIsString(); 536 SCSIZE nCount = nColCount * nRowCount; 537 for (SCSIZE i = 0; i < nCount; i++) 538 mRes.pMat[i].fVal = pMat[i].fVal; 539 } 540 } 541 else 542 { 543 // Copy this matrix to upper left rectangle of result matrix. 544 if (mnValType) 545 { 546 ScMatValType nType; 547 mRes.ResetIsString(); 548 for (SCSIZE i = 0; i < nColCount; i++) 549 { 550 SCSIZE nStart = i * nRowCount; 551 SCSIZE nResStart = i * mRes.nRowCount; 552 for (SCSIZE j = 0; j < nRowCount; j++) 553 { 554 if (IsNonValueType( (nType = mnValType[nStart+j]))) 555 mRes.PutStringEntry( pMat[nStart+j].pS, nType, nResStart+j ); 556 else 557 { 558 mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal; 559 mRes.mnValType[nResStart+j] = nType; 560 } 561 } 562 } 563 } 564 else 565 { 566 mRes.DeleteIsString(); 567 for (SCSIZE i = 0; i < nColCount; i++) 568 { 569 SCSIZE nStart = i * nRowCount; 570 SCSIZE nResStart = i * mRes.nRowCount; 571 for (SCSIZE j = 0; j < nRowCount; j++) 572 mRes.pMat[nResStart+j].fVal = pMat[nStart+j].fVal; 573 } 574 } 575 } 576 } 577 578 void ScMatrix::MatTrans(ScMatrix& mRes) const 579 { 580 if (nColCount != mRes.nRowCount || nRowCount != mRes.nColCount) 581 { 582 DBG_ERRORFILE("ScMatrix::MatTrans: dimension error"); 583 } 584 else 585 { 586 if (mnValType) 587 { 588 ScMatValType nType; 589 mRes.ResetIsString(); 590 for ( SCSIZE i = 0; i < nColCount; i++ ) 591 { 592 SCSIZE nStart = i * nRowCount; 593 for ( SCSIZE j = 0; j < nRowCount; j++ ) 594 { 595 if (IsNonValueType( (nType = mnValType[nStart+j]))) 596 mRes.PutStringEntry( pMat[nStart+j].pS, nType, j*mRes.nRowCount+i ); 597 else 598 { 599 mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal; 600 mRes.mnValType[j*mRes.nRowCount+i] = nType; 601 } 602 } 603 } 604 } 605 else 606 { 607 mRes.DeleteIsString(); 608 for ( SCSIZE i = 0; i < nColCount; i++ ) 609 { 610 SCSIZE nStart = i * nRowCount; 611 for ( SCSIZE j = 0; j < nRowCount; j++ ) 612 { 613 mRes.pMat[j*mRes.nRowCount+i].fVal = pMat[nStart+j].fVal; 614 } 615 } 616 } 617 } 618 } 619 620 //UNUSED2009-05 void ScMatrix::MatCopyUpperLeft(ScMatrix& mRes) const 621 //UNUSED2009-05 { 622 //UNUSED2009-05 if (nColCount < mRes.nColCount || nRowCount < mRes.nRowCount) 623 //UNUSED2009-05 { 624 //UNUSED2009-05 DBG_ERRORFILE("ScMatrix::MatCopyUpperLeft: dimension error"); 625 //UNUSED2009-05 } 626 //UNUSED2009-05 else 627 //UNUSED2009-05 { 628 //UNUSED2009-05 if (mnValType) 629 //UNUSED2009-05 { 630 //UNUSED2009-05 ScMatValType nType; 631 //UNUSED2009-05 mRes.ResetIsString(); 632 //UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ ) 633 //UNUSED2009-05 { 634 //UNUSED2009-05 SCSIZE nStart = i * nRowCount; 635 //UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ ) 636 //UNUSED2009-05 { 637 //UNUSED2009-05 if ( IsNonValueType( (nType = mnValType[nStart+j]) )) 638 //UNUSED2009-05 mRes.PutStringEntry( pMat[nStart+j].pS, nType, 639 //UNUSED2009-05 i*mRes.nRowCount+j ); 640 //UNUSED2009-05 else 641 //UNUSED2009-05 { 642 //UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal; 643 //UNUSED2009-05 mRes.mnValType[i*mRes.nRowCount+j] = nType; 644 //UNUSED2009-05 } 645 //UNUSED2009-05 } 646 //UNUSED2009-05 } 647 //UNUSED2009-05 } 648 //UNUSED2009-05 else 649 //UNUSED2009-05 { 650 //UNUSED2009-05 mRes.DeleteIsString(); 651 //UNUSED2009-05 for ( SCSIZE i = 0; i < mRes.nColCount; i++ ) 652 //UNUSED2009-05 { 653 //UNUSED2009-05 SCSIZE nStart = i * nRowCount; 654 //UNUSED2009-05 for ( SCSIZE j = 0; j < mRes.nRowCount; j++ ) 655 //UNUSED2009-05 { 656 //UNUSED2009-05 mRes.pMat[i*mRes.nRowCount+j].fVal = pMat[nStart+j].fVal; 657 //UNUSED2009-05 } 658 //UNUSED2009-05 } 659 //UNUSED2009-05 } 660 //UNUSED2009-05 } 661 //UNUSED2009-05 } 662 663 void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 ) 664 { 665 if (ValidColRow( nC1, nR1) && ValidColRow( nC2, nR2)) 666 { 667 if ( nC1 == 0 && nR1 == 0 && nC2 == nColCount-1 && nR2 == nRowCount-1 ) 668 { 669 SCSIZE nEnd = nColCount * nRowCount; 670 for ( SCSIZE j=0; j<nEnd; j++ ) 671 pMat[j].fVal = fVal; 672 } 673 else 674 { 675 for ( SCSIZE i=nC1; i<=nC2; i++ ) 676 { 677 SCSIZE nOff1 = i * nRowCount + nR1; 678 SCSIZE nOff2 = nOff1 + nR2 - nR1; 679 for ( SCSIZE j=nOff1; j<=nOff2; j++ ) 680 pMat[j].fVal = fVal; 681 } 682 } 683 } 684 else 685 { 686 DBG_ERRORFILE("ScMatrix::FillDouble: dimension error"); 687 } 688 } 689 690 void ScMatrix::CompareEqual() 691 { 692 SCSIZE n = nColCount * nRowCount; 693 if ( mnValType ) 694 { 695 for ( SCSIZE j=0; j<n; j++ ) 696 if ( IsValueType( mnValType[j]) ) // else: #WERT! 697 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 698 pMat[j].fVal = (pMat[j].fVal == 0.0); 699 } 700 else 701 { 702 for ( SCSIZE j=0; j<n; j++ ) 703 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 704 pMat[j].fVal = (pMat[j].fVal == 0.0); 705 } 706 } 707 708 void ScMatrix::CompareNotEqual() 709 { 710 SCSIZE n = nColCount * nRowCount; 711 if ( mnValType ) 712 { 713 for ( SCSIZE j=0; j<n; j++ ) 714 if ( IsValueType( mnValType[j]) ) // else: #WERT! 715 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 716 pMat[j].fVal = (pMat[j].fVal != 0.0); 717 } 718 else 719 { 720 for ( SCSIZE j=0; j<n; j++ ) 721 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 722 pMat[j].fVal = (pMat[j].fVal != 0.0); 723 } 724 } 725 726 void ScMatrix::CompareLess() 727 { 728 SCSIZE n = nColCount * nRowCount; 729 if ( mnValType ) 730 { 731 for ( SCSIZE j=0; j<n; j++ ) 732 if ( IsValueType( mnValType[j]) ) // else: #WERT! 733 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 734 pMat[j].fVal = (pMat[j].fVal < 0.0); 735 } 736 else 737 { 738 for ( SCSIZE j=0; j<n; j++ ) 739 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 740 pMat[j].fVal = (pMat[j].fVal < 0.0); 741 } 742 } 743 744 void ScMatrix::CompareGreater() 745 { 746 SCSIZE n = nColCount * nRowCount; 747 if ( mnValType ) 748 { 749 for ( SCSIZE j=0; j<n; j++ ) 750 if ( IsValueType( mnValType[j]) ) // else: #WERT! 751 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 752 pMat[j].fVal = (pMat[j].fVal > 0.0); 753 } 754 else 755 { 756 for ( SCSIZE j=0; j<n; j++ ) 757 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 758 pMat[j].fVal = (pMat[j].fVal > 0.0); 759 } 760 } 761 762 void ScMatrix::CompareLessEqual() 763 { 764 SCSIZE n = nColCount * nRowCount; 765 if ( mnValType ) 766 { 767 for ( SCSIZE j=0; j<n; j++ ) 768 if ( IsValueType( mnValType[j]) ) // else: #WERT! 769 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 770 pMat[j].fVal = (pMat[j].fVal <= 0.0); 771 } 772 else 773 { 774 for ( SCSIZE j=0; j<n; j++ ) 775 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 776 pMat[j].fVal = (pMat[j].fVal <= 0.0); 777 } 778 } 779 780 void ScMatrix::CompareGreaterEqual() 781 { 782 SCSIZE n = nColCount * nRowCount; 783 if ( mnValType ) 784 { 785 for ( SCSIZE j=0; j<n; j++ ) 786 if ( IsValueType( mnValType[j]) ) // else: #WERT! 787 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 788 pMat[j].fVal = (pMat[j].fVal >= 0.0); 789 } 790 else 791 { 792 for ( SCSIZE j=0; j<n; j++ ) 793 if ( ::rtl::math::isFinite( pMat[j].fVal)) // else: DoubleError 794 pMat[j].fVal = (pMat[j].fVal >= 0.0); 795 } 796 } 797 798 double ScMatrix::And() 799 { 800 SCSIZE n = nColCount * nRowCount; 801 bool bAnd = true; 802 if ( mnValType ) 803 { 804 for ( SCSIZE j=0; bAnd && j<n; j++ ) 805 { 806 if ( !IsValueType( mnValType[j]) ) 807 { // assuming a CompareMat this is an error 808 return CreateDoubleError( errIllegalArgument ); 809 } 810 else if ( ::rtl::math::isFinite( pMat[j].fVal)) 811 bAnd = (pMat[j].fVal != 0.0); 812 else 813 return pMat[j].fVal; // DoubleError 814 } 815 } 816 else 817 { 818 for ( SCSIZE j=0; bAnd && j<n; j++ ) 819 { 820 if ( ::rtl::math::isFinite( pMat[j].fVal)) 821 bAnd = (pMat[j].fVal != 0.0); 822 else 823 return pMat[j].fVal; // DoubleError 824 } 825 } 826 return bAnd; 827 } 828 829 double ScMatrix::Or() 830 { 831 SCSIZE n = nColCount * nRowCount; 832 bool bOr = false; 833 if ( mnValType ) 834 { 835 for ( SCSIZE j=0; !bOr && j<n; j++ ) 836 if ( !IsValueType( mnValType[j]) ) 837 { // assuming a CompareMat this is an error 838 return CreateDoubleError( errIllegalArgument ); 839 } 840 else if ( ::rtl::math::isFinite( pMat[j].fVal)) 841 bOr = (pMat[j].fVal != 0.0); 842 else 843 return pMat[j].fVal; // DoubleError 844 } 845 else 846 { 847 for ( SCSIZE j=0; !bOr && j<n; j++ ) 848 if ( ::rtl::math::isFinite( pMat[j].fVal)) 849 bOr = (pMat[j].fVal != 0.0); 850 else 851 return pMat[j].fVal; // DoubleError 852 } 853 return bOr; 854 } 855