summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/interpr2.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2020-07-29 16:12:49 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2020-07-29 20:44:14 +0200
commit382ecc31a9480fc0d19dddc917d16a7e744a00e3 (patch)
treecf12f657597a797aaaad351f32c8b0a4e662aff4 /sc/source/core/tool/interpr2.cxx
parent6446f79f6a13aad9c60cb52ecfb66ccd9bd4065b (diff)
loplugin:flatten in sc/core/tool
Change-Id: Ibe5302ee320cf2e89c814dfb34ad42f9d72a25aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99700 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sc/source/core/tool/interpr2.cxx')
-rw-r--r--sc/source/core/tool/interpr2.cxx2778
1 files changed, 1389 insertions, 1389 deletions
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 6d202166db54..96716236cfa5 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -194,48 +194,48 @@ void ScInterpreter::ScGetDateValue()
void ScInterpreter::ScGetDayOfWeek()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
- {
- sal_Int16 nFlag;
- if (nParamCount == 2)
- nFlag = GetInt16();
- else
- nFlag = 1;
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
- Date aDate = pFormatter->GetNullDate();
- aDate.AddDays( GetInt32());
- int nVal = static_cast<int>(aDate.GetDayOfWeek()); // MONDAY = 0
- switch (nFlag)
- {
- case 1: // Sunday = 1
- if (nVal == 6)
- nVal = 1;
- else
- nVal += 2;
- break;
- case 2: // Monday = 1
- nVal += 1;
- break;
- case 3: // Monday = 0
- ; // nothing
- break;
- case 11: // Monday = 1
- case 12: // Tuesday = 1
- case 13: // Wednesday = 1
- case 14: // Thursday = 1
- case 15: // Friday = 1
- case 16: // Saturday = 1
- case 17: // Sunday = 1
- if (nVal < nFlag - 11) // x = nFlag - 11 = 0,1,2,3,4,5,6
- nVal += 19 - nFlag; // nVal += (8 - (nFlag - 11) = 8 - x = 8,7,6,5,4,3,2)
- else
- nVal -= nFlag - 12; // nVal -= ((nFlag - 11) - 1 = x - 1 = -1,0,1,2,3,4,5)
- break;
- default:
- SetError( FormulaError::IllegalArgument);
- }
- PushInt( nVal );
+ sal_Int16 nFlag;
+ if (nParamCount == 2)
+ nFlag = GetInt16();
+ else
+ nFlag = 1;
+
+ Date aDate = pFormatter->GetNullDate();
+ aDate.AddDays( GetInt32());
+ int nVal = static_cast<int>(aDate.GetDayOfWeek()); // MONDAY = 0
+ switch (nFlag)
+ {
+ case 1: // Sunday = 1
+ if (nVal == 6)
+ nVal = 1;
+ else
+ nVal += 2;
+ break;
+ case 2: // Monday = 1
+ nVal += 1;
+ break;
+ case 3: // Monday = 0
+ ; // nothing
+ break;
+ case 11: // Monday = 1
+ case 12: // Tuesday = 1
+ case 13: // Wednesday = 1
+ case 14: // Thursday = 1
+ case 15: // Friday = 1
+ case 16: // Saturday = 1
+ case 17: // Sunday = 1
+ if (nVal < nFlag - 11) // x = nFlag - 11 = 0,1,2,3,4,5,6
+ nVal += 19 - nFlag; // nVal += (8 - (nFlag - 11) = 8 - x = 8,7,6,5,4,3,2)
+ else
+ nVal -= nFlag - 12; // nVal -= ((nFlag - 11) - 1 = x - 1 = -1,0,1,2,3,4,5)
+ break;
+ default:
+ SetError( FormulaError::IllegalArgument);
}
+ PushInt( nVal );
}
void ScInterpreter::ScWeeknumOOo()
@@ -253,51 +253,51 @@ void ScInterpreter::ScWeeknumOOo()
void ScInterpreter::ScGetWeekOfYear()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
- {
- sal_Int16 nFlag;
- if (nParamCount == 1)
- nFlag = 1;
- else
- nFlag = GetInt16();
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
- Date aDate = pFormatter->GetNullDate();
- aDate.AddDays( GetInt32());
+ sal_Int16 nFlag;
+ if (nParamCount == 1)
+ nFlag = 1;
+ else
+ nFlag = GetInt16();
- sal_Int32 nMinimumNumberOfDaysInWeek;
- DayOfWeek eFirstDayOfWeek;
- switch ( nFlag )
- {
- case 1 :
- eFirstDayOfWeek = SUNDAY;
- nMinimumNumberOfDaysInWeek = 1;
- break;
- case 2 :
- eFirstDayOfWeek = MONDAY;
- nMinimumNumberOfDaysInWeek = 1;
- break;
- case 11 :
- case 12 :
- case 13 :
- case 14 :
- case 15 :
- case 16 :
- case 17 :
- eFirstDayOfWeek = static_cast<DayOfWeek>( nFlag - 11 ); // MONDAY := 0
- nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1
- break;
- case 21 :
- case 150 :
- // ISO 8601
- eFirstDayOfWeek = MONDAY;
- nMinimumNumberOfDaysInWeek = 4;
- break;
- default :
- PushIllegalArgument();
- return;
- }
- PushInt( static_cast<int>(aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek )) );
+ Date aDate = pFormatter->GetNullDate();
+ aDate.AddDays( GetInt32());
+
+ sal_Int32 nMinimumNumberOfDaysInWeek;
+ DayOfWeek eFirstDayOfWeek;
+ switch ( nFlag )
+ {
+ case 1 :
+ eFirstDayOfWeek = SUNDAY;
+ nMinimumNumberOfDaysInWeek = 1;
+ break;
+ case 2 :
+ eFirstDayOfWeek = MONDAY;
+ nMinimumNumberOfDaysInWeek = 1;
+ break;
+ case 11 :
+ case 12 :
+ case 13 :
+ case 14 :
+ case 15 :
+ case 16 :
+ case 17 :
+ eFirstDayOfWeek = static_cast<DayOfWeek>( nFlag - 11 ); // MONDAY := 0
+ nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1
+ break;
+ case 21 :
+ case 150 :
+ // ISO 8601
+ eFirstDayOfWeek = MONDAY;
+ nMinimumNumberOfDaysInWeek = 4;
+ break;
+ default :
+ PushIllegalArgument();
+ return;
}
+ PushInt( static_cast<int>(aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek )) );
}
void ScInterpreter::ScGetIsoWeekOfYear()
@@ -313,42 +313,42 @@ void ScInterpreter::ScGetIsoWeekOfYear()
void ScInterpreter::ScEasterSunday()
{
nFuncFmtType = SvNumFormatType::DATE;
- if ( MustHaveParamCount( GetByte(), 1 ) )
+ if ( !MustHaveParamCount( GetByte(), 1 ) )
+ return;
+
+ sal_Int16 nDay, nMonth, nYear;
+ nYear = GetInt16();
+ if (nGlobalError != FormulaError::NONE)
{
- sal_Int16 nDay, nMonth, nYear;
- nYear = GetInt16();
- if (nGlobalError != FormulaError::NONE)
- {
- PushError( nGlobalError);
- return;
- }
- if ( nYear < 100 )
- nYear = pFormatter->ExpandTwoDigitYear( nYear );
- if (nYear < 1583 || nYear > 9956)
- {
- // Valid Gregorian and maximum year constraints not met.
- PushIllegalArgument();
- return;
- }
- // don't worry, be happy :)
- int B,C,D,E,F,G,H,I,K,L,M,N,O;
- N = nYear % 19;
- B = int(nYear / 100);
- C = nYear % 100;
- D = int(B / 4);
- E = B % 4;
- F = int((B + 8) / 25);
- G = int((B - F + 1) / 3);
- H = (19 * N + B - D - G + 15) % 30;
- I = int(C / 4);
- K = C % 4;
- L = (32 + 2 * E + 2 * I - H - K) % 7;
- M = int((N + 11 * H + 22 * L) / 451);
- O = H + L - 7 * M + 114;
- nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 );
- nMonth = sal::static_int_cast<sal_Int16>( int(O / 31) );
- PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) );
+ PushError( nGlobalError);
+ return;
+ }
+ if ( nYear < 100 )
+ nYear = pFormatter->ExpandTwoDigitYear( nYear );
+ if (nYear < 1583 || nYear > 9956)
+ {
+ // Valid Gregorian and maximum year constraints not met.
+ PushIllegalArgument();
+ return;
}
+ // don't worry, be happy :)
+ int B,C,D,E,F,G,H,I,K,L,M,N,O;
+ N = nYear % 19;
+ B = int(nYear / 100);
+ C = nYear % 100;
+ D = int(B / 4);
+ E = B % 4;
+ F = int((B + 8) / 25);
+ G = int((B - F + 1) / 3);
+ H = (19 * N + B - D - G + 15) % 30;
+ I = int(C / 4);
+ K = C % 4;
+ L = (32 + 2 * E + 2 * I - H - K) % 7;
+ M = int((N + 11 * H + 22 * L) / 451);
+ O = H + L - 7 * M + 114;
+ nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 );
+ nMonth = sal::static_int_cast<sal_Int16>( int(O / 31) );
+ PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) );
}
FormulaError ScInterpreter::GetWeekendAndHolidayMasks(
@@ -512,131 +512,131 @@ FormulaError ScInterpreter::GetWeekendAndHolidayMasks_MS(
void ScInterpreter::ScNetWorkdays( bool bOOXML_Version )
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2, 4 ) )
+ if ( !MustHaveParamCount( nParamCount, 2, 4 ) )
+ return;
+
+ vector<double> nSortArray;
+ bool bWeekendMask[ 7 ];
+ const Date& rNullDate = pFormatter->GetNullDate();
+ sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
+ FormulaError nErr;
+ if ( bOOXML_Version )
{
- vector<double> nSortArray;
- bool bWeekendMask[ 7 ];
- const Date& rNullDate = pFormatter->GetNullDate();
- sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
- FormulaError nErr;
- if ( bOOXML_Version )
+ nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
+ nSortArray, bWeekendMask, false );
+ }
+ else
+ {
+ nErr = GetWeekendAndHolidayMasks( nParamCount, nNullDate,
+ nSortArray, bWeekendMask );
+ }
+ if ( nErr != FormulaError::NONE )
+ PushError( nErr );
+ else
+ {
+ sal_uInt32 nDate2 = GetUInt32();
+ sal_uInt32 nDate1 = GetUInt32();
+ if (nGlobalError != FormulaError::NONE || (nDate1 > SAL_MAX_UINT32 - nNullDate) || nDate2 > (SAL_MAX_UINT32 - nNullDate))
{
- nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
- nSortArray, bWeekendMask, false );
+ PushIllegalArgument();
+ return;
}
- else
+ nDate2 += nNullDate;
+ nDate1 += nNullDate;
+
+ sal_Int32 nCnt = 0;
+ size_t nRef = 0;
+ bool bReverse = ( nDate1 > nDate2 );
+ if ( bReverse )
{
- nErr = GetWeekendAndHolidayMasks( nParamCount, nNullDate,
- nSortArray, bWeekendMask );
+ sal_uInt32 nTemp = nDate1;
+ nDate1 = nDate2;
+ nDate2 = nTemp;
}
- if ( nErr != FormulaError::NONE )
- PushError( nErr );
- else
+ size_t nMax = nSortArray.size();
+ while ( nDate1 <= nDate2 )
{
- sal_uInt32 nDate2 = GetUInt32();
- sal_uInt32 nDate1 = GetUInt32();
- if (nGlobalError != FormulaError::NONE || (nDate1 > SAL_MAX_UINT32 - nNullDate) || nDate2 > (SAL_MAX_UINT32 - nNullDate))
- {
- PushIllegalArgument();
- return;
- }
- nDate2 += nNullDate;
- nDate1 += nNullDate;
-
- sal_Int32 nCnt = 0;
- size_t nRef = 0;
- bool bReverse = ( nDate1 > nDate2 );
- if ( bReverse )
- {
- sal_uInt32 nTemp = nDate1;
- nDate1 = nDate2;
- nDate2 = nTemp;
- }
- size_t nMax = nSortArray.size();
- while ( nDate1 <= nDate2 )
+ if ( !bWeekendMask[ GetDayOfWeek( nDate1 ) ] )
{
- if ( !bWeekendMask[ GetDayOfWeek( nDate1 ) ] )
- {
- while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 )
- nRef++;
- if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 )
- nCnt++;
- }
- ++nDate1;
+ while ( nRef < nMax && nSortArray.at( nRef ) < nDate1 )
+ nRef++;
+ if ( nRef >= nMax || nSortArray.at( nRef ) != nDate1 )
+ nCnt++;
}
- PushDouble( static_cast<double>( bReverse ? -nCnt : nCnt ) );
+ ++nDate1;
}
+ PushDouble( static_cast<double>( bReverse ? -nCnt : nCnt ) );
}
}
void ScInterpreter::ScWorkday_MS()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2, 4 ) )
- {
- nFuncFmtType = SvNumFormatType::DATE;
- vector<double> nSortArray;
- bool bWeekendMask[ 7 ];
- const Date& rNullDate = pFormatter->GetNullDate();
- sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
- FormulaError nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
- nSortArray, bWeekendMask, true );
- if ( nErr != FormulaError::NONE )
- PushError( nErr );
- else
+ if ( !MustHaveParamCount( nParamCount, 2, 4 ) )
+ return;
+
+ nFuncFmtType = SvNumFormatType::DATE;
+ vector<double> nSortArray;
+ bool bWeekendMask[ 7 ];
+ const Date& rNullDate = pFormatter->GetNullDate();
+ sal_uInt32 nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
+ FormulaError nErr = GetWeekendAndHolidayMasks_MS( nParamCount, nNullDate,
+ nSortArray, bWeekendMask, true );
+ if ( nErr != FormulaError::NONE )
+ PushError( nErr );
+ else
+ {
+ sal_Int32 nDays = GetInt32();
+ sal_uInt32 nDate = GetUInt32();
+ if (nGlobalError != FormulaError::NONE || (nDate > SAL_MAX_UINT32 - nNullDate))
{
- sal_Int32 nDays = GetInt32();
- sal_uInt32 nDate = GetUInt32();
- if (nGlobalError != FormulaError::NONE || (nDate > SAL_MAX_UINT32 - nNullDate))
- {
- PushIllegalArgument();
- return;
- }
- nDate += nNullDate;
+ PushIllegalArgument();
+ return;
+ }
+ nDate += nNullDate;
- if ( !nDays )
- PushDouble( static_cast<double>( nDate - nNullDate ) );
- else
+ if ( !nDays )
+ PushDouble( static_cast<double>( nDate - nNullDate ) );
+ else
+ {
+ size_t nMax = nSortArray.size();
+ if ( nDays > 0 )
{
- size_t nMax = nSortArray.size();
- if ( nDays > 0 )
+ size_t nRef = 0;
+ while ( nDays )
{
- size_t nRef = 0;
- while ( nDays )
+ do
{
- do
- {
- ++nDate;
- }
- while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s)
+ ++nDate;
+ }
+ while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s)
- while ( nRef < nMax && nSortArray.at( nRef ) < nDate )
- nRef++;
+ while ( nRef < nMax && nSortArray.at( nRef ) < nDate )
+ nRef++;
- if ( nRef >= nMax || nSortArray.at( nRef ) != nDate || nRef >= nMax )
- nDays--;
- }
+ if ( nRef >= nMax || nSortArray.at( nRef ) != nDate || nRef >= nMax )
+ nDays--;
}
- else
+ }
+ else
+ {
+ sal_Int16 nRef = nMax - 1;
+ while ( nDays )
{
- sal_Int16 nRef = nMax - 1;
- while ( nDays )
+ do
{
- do
- {
- --nDate;
- }
- while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s)
+ --nDate;
+ }
+ while ( bWeekendMask[ GetDayOfWeek( nDate ) ] ); //jump over weekend day(s)
- while ( nRef >= 0 && nSortArray.at( nRef ) > nDate )
- nRef--;
+ while ( nRef >= 0 && nSortArray.at( nRef ) > nDate )
+ nRef--;
- if (nRef < 0 || nSortArray.at(nRef) != nDate)
- nDays++;
- }
+ if (nRef < 0 || nSortArray.at(nRef) != nDate)
+ nDays++;
}
- PushDouble( static_cast<double>( nDate - nNullDate ) );
}
+ PushDouble( static_cast<double>( nDate - nNullDate ) );
}
}
}
@@ -644,19 +644,19 @@ void ScInterpreter::ScWorkday_MS()
void ScInterpreter::ScGetDate()
{
nFuncFmtType = SvNumFormatType::DATE;
- if ( MustHaveParamCount( GetByte(), 3 ) )
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+
+ sal_Int16 nDay = GetInt16();
+ sal_Int16 nMonth = GetInt16();
+ if (IsMissing())
+ SetError( FormulaError::ParameterExpected); // Year must be given.
+ sal_Int16 nYear = GetInt16();
+ if (nGlobalError != FormulaError::NONE || nYear < 0)
+ PushIllegalArgument();
+ else
{
- sal_Int16 nDay = GetInt16();
- sal_Int16 nMonth = GetInt16();
- if (IsMissing())
- SetError( FormulaError::ParameterExpected); // Year must be given.
- sal_Int16 nYear = GetInt16();
- if (nGlobalError != FormulaError::NONE || nYear < 0)
- PushIllegalArgument();
- else
- {
- PushDouble(GetDateSerial(nYear, nMonth, nDay, false));
- }
+ PushDouble(GetDateSerial(nYear, nMonth, nDay, false));
}
}
@@ -714,220 +714,220 @@ void ScInterpreter::ScGetDiffDate360()
*/
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return;
+
+ bool bFlag;
+ if (nParamCount == 3)
+ bFlag = GetBool();
+ else
+ bFlag = false;
+ sal_Int32 nDate2 = GetInt32();
+ sal_Int32 nDate1 = GetInt32();
+ if (nGlobalError != FormulaError::NONE)
+ PushError( nGlobalError);
+ else
{
- bool bFlag;
- if (nParamCount == 3)
- bFlag = GetBool();
- else
- bFlag = false;
- sal_Int32 nDate2 = GetInt32();
- sal_Int32 nDate1 = GetInt32();
- if (nGlobalError != FormulaError::NONE)
- PushError( nGlobalError);
+ sal_Int32 nSign;
+ // #i84934# only for non-US European algorithm swap dates. Else
+ // follow Excel's meaningless extrapolation for "interoperability".
+ if (bFlag && (nDate2 < nDate1))
+ {
+ nSign = nDate1;
+ nDate1 = nDate2;
+ nDate2 = nSign;
+ nSign = -1;
+ }
else
+ nSign = 1;
+ Date aDate1 = pFormatter->GetNullDate();
+ aDate1.AddDays( nDate1);
+ Date aDate2 = pFormatter->GetNullDate();
+ aDate2.AddDays( nDate2);
+ if (aDate1.GetDay() == 31)
+ aDate1.AddDays( -1);
+ else if (!bFlag)
{
- sal_Int32 nSign;
- // #i84934# only for non-US European algorithm swap dates. Else
- // follow Excel's meaningless extrapolation for "interoperability".
- if (bFlag && (nDate2 < nDate1))
- {
- nSign = nDate1;
- nDate1 = nDate2;
- nDate2 = nSign;
- nSign = -1;
- }
- else
- nSign = 1;
- Date aDate1 = pFormatter->GetNullDate();
- aDate1.AddDays( nDate1);
- Date aDate2 = pFormatter->GetNullDate();
- aDate2.AddDays( nDate2);
- if (aDate1.GetDay() == 31)
- aDate1.AddDays( -1);
- else if (!bFlag)
+ if (aDate1.GetMonth() == 2)
{
- if (aDate1.GetMonth() == 2)
+ switch ( aDate1.GetDay() )
{
- switch ( aDate1.GetDay() )
- {
- case 28 :
- if ( !aDate1.IsLeapYear() )
- aDate1.SetDay(30);
- break;
- case 29 :
+ case 28 :
+ if ( !aDate1.IsLeapYear() )
aDate1.SetDay(30);
- break;
- }
+ break;
+ case 29 :
+ aDate1.SetDay(30);
+ break;
}
}
- if (aDate2.GetDay() == 31)
+ }
+ if (aDate2.GetDay() == 31)
+ {
+ if (!bFlag )
{
- if (!bFlag )
- {
- if (aDate1.GetDay() == 30)
- aDate2.AddDays( -1);
- }
- else
- aDate2.SetDay(30);
+ if (aDate1.GetDay() == 30)
+ aDate2.AddDays( -1);
}
- PushDouble( static_cast<double>(nSign) *
- ( static_cast<double>(aDate2.GetDay()) + static_cast<double>(aDate2.GetMonth()) * 30.0 +
- static_cast<double>(aDate2.GetYear()) * 360.0
- - static_cast<double>(aDate1.GetDay()) - static_cast<double>(aDate1.GetMonth()) * 30.0
- - static_cast<double>(aDate1.GetYear()) * 360.0) );
+ else
+ aDate2.SetDay(30);
}
+ PushDouble( static_cast<double>(nSign) *
+ ( static_cast<double>(aDate2.GetDay()) + static_cast<double>(aDate2.GetMonth()) * 30.0 +
+ static_cast<double>(aDate2.GetYear()) * 360.0
+ - static_cast<double>(aDate1.GetDay()) - static_cast<double>(aDate1.GetMonth()) * 30.0
+ - static_cast<double>(aDate1.GetYear()) * 360.0) );
}
}
// fdo#44456 function DATEDIF as defined in ODF1.2 (Par. 6.10.3)
void ScInterpreter::ScGetDateDif()
{
- if ( MustHaveParamCount( GetByte(), 3 ) )
- {
- OUString aInterval = GetString().getString();
- sal_Int32 nDate2 = GetInt32();
- sal_Int32 nDate1 = GetInt32();
-
- if (nGlobalError != FormulaError::NONE)
- {
- PushError( nGlobalError);
- return;
- }
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
- // Excel doesn't swap dates or return negative numbers, so don't we.
- if (nDate1 > nDate2)
- {
- PushIllegalArgument();
- return;
- }
+ OUString aInterval = GetString().getString();
+ sal_Int32 nDate2 = GetInt32();
+ sal_Int32 nDate1 = GetInt32();
- double dd = nDate2 - nDate1;
- // Zero difference or number of days can be returned immediately.
- if (dd == 0.0 || aInterval.equalsIgnoreAsciiCase( "d" ))
- {
- PushDouble( dd );
- return;
- }
+ if (nGlobalError != FormulaError::NONE)
+ {
+ PushError( nGlobalError);
+ return;
+ }
- // split dates in day, month, year for use with formats other than "d"
- sal_uInt16 d1, m1, d2, m2;
- sal_Int16 y1, y2;
- Date aDate1( pFormatter->GetNullDate());
- aDate1.AddDays( nDate1);
- y1 = aDate1.GetYear();
- m1 = aDate1.GetMonth();
- d1 = aDate1.GetDay();
- Date aDate2( pFormatter->GetNullDate());
- aDate2.AddDays( nDate2);
- y2 = aDate2.GetYear();
- m2 = aDate2.GetMonth();
- d2 = aDate2.GetDay();
+ // Excel doesn't swap dates or return negative numbers, so don't we.
+ if (nDate1 > nDate2)
+ {
+ PushIllegalArgument();
+ return;
+ }
- // Close the year 0 gap to calculate year difference.
- if (y1 < 0 && y2 > 0)
- ++y1;
- else if (y1 > 0 && y2 < 0)
- ++y2;
+ double dd = nDate2 - nDate1;
+ // Zero difference or number of days can be returned immediately.
+ if (dd == 0.0 || aInterval.equalsIgnoreAsciiCase( "d" ))
+ {
+ PushDouble( dd );
+ return;
+ }
- if ( aInterval.equalsIgnoreAsciiCase( "m" ) )
+ // split dates in day, month, year for use with formats other than "d"
+ sal_uInt16 d1, m1, d2, m2;
+ sal_Int16 y1, y2;
+ Date aDate1( pFormatter->GetNullDate());
+ aDate1.AddDays( nDate1);
+ y1 = aDate1.GetYear();
+ m1 = aDate1.GetMonth();
+ d1 = aDate1.GetDay();
+ Date aDate2( pFormatter->GetNullDate());
+ aDate2.AddDays( nDate2);
+ y2 = aDate2.GetYear();
+ m2 = aDate2.GetMonth();
+ d2 = aDate2.GetDay();
+
+ // Close the year 0 gap to calculate year difference.
+ if (y1 < 0 && y2 > 0)
+ ++y1;
+ else if (y1 > 0 && y2 < 0)
+ ++y2;
+
+ if ( aInterval.equalsIgnoreAsciiCase( "m" ) )
+ {
+ // Return number of months.
+ int md = m2 - m1 + 12 * (y2 - y1);
+ if (d1 > d2)
+ --md;
+ PushInt( md );
+ }
+ else if ( aInterval.equalsIgnoreAsciiCase( "y" ) )
+ {
+ // Return number of years.
+ int yd;
+ if ( y2 > y1 )
{
- // Return number of months.
- int md = m2 - m1 + 12 * (y2 - y1);
- if (d1 > d2)
- --md;
- PushInt( md );
+ if (m2 > m1 || (m2 == m1 && d2 >= d1))
+ yd = y2 - y1; // complete years between dates
+ else
+ yd = y2 - y1 - 1; // one incomplete year
}
- else if ( aInterval.equalsIgnoreAsciiCase( "y" ) )
+ else
{
- // Return number of years.
- int yd;
- if ( y2 > y1 )
- {
- if (m2 > m1 || (m2 == m1 && d2 >= d1))
- yd = y2 - y1; // complete years between dates
- else
- yd = y2 - y1 - 1; // one incomplete year
- }
- else
+ // Year is equal as we don't allow reversed arguments, no
+ // complete year between dates.
+ yd = 0;
+ }
+ PushInt( yd );
+ }
+ else if ( aInterval.equalsIgnoreAsciiCase( "md" ) )
+ {
+ // Return number of days, excluding months and years.
+ // This is actually the remainder of days when subtracting years
+ // and months from the difference of dates. Birthday-like 23 years
+ // and 10 months and 19 days.
+
+ // Algorithm's roll-over behavior extracted from Excel by try and
+ // error...
+ // If day1 <= day2 then simply day2 - day1.
+ // If day1 > day2 then set month1 to month2-1 and year1 to
+ // year2(-1) and subtract dates, e.g. for 2012-01-28,2012-03-01 set
+ // 2012-02-28 and then (2012-03-01)-(2012-02-28) => 2 days (leap
+ // year).
+ // For 2011-01-29,2011-03-01 the non-existent 2011-02-29 rolls over
+ // to 2011-03-01 so the result is 0. Same for day 31 in months with
+ // only 30 days.
+
+ long nd;
+ if (d1 <= d2)
+ nd = d2 - d1;
+ else
+ {
+ if (m2 == 1)
{
- // Year is equal as we don't allow reversed arguments, no
- // complete year between dates.
- yd = 0;
+ aDate1.SetYear( y2 == 1 ? -1 : y2 - 1 );
+ aDate1.SetMonth( 12 );
}
- PushInt( yd );
- }
- else if ( aInterval.equalsIgnoreAsciiCase( "md" ) )
- {
- // Return number of days, excluding months and years.
- // This is actually the remainder of days when subtracting years
- // and months from the difference of dates. Birthday-like 23 years
- // and 10 months and 19 days.
-
- // Algorithm's roll-over behavior extracted from Excel by try and
- // error...
- // If day1 <= day2 then simply day2 - day1.
- // If day1 > day2 then set month1 to month2-1 and year1 to
- // year2(-1) and subtract dates, e.g. for 2012-01-28,2012-03-01 set
- // 2012-02-28 and then (2012-03-01)-(2012-02-28) => 2 days (leap
- // year).
- // For 2011-01-29,2011-03-01 the non-existent 2011-02-29 rolls over
- // to 2011-03-01 so the result is 0. Same for day 31 in months with
- // only 30 days.
-
- long nd;
- if (d1 <= d2)
- nd = d2 - d1;
else
{
- if (m2 == 1)
- {
- aDate1.SetYear( y2 == 1 ? -1 : y2 - 1 );
- aDate1.SetMonth( 12 );
- }
- else
- {
- aDate1.SetYear( y2 );
- aDate1.SetMonth( m2 - 1 );
- }
- aDate1.Normalize();
- nd = aDate2 - aDate1;
- }
- PushDouble( nd );
- }
- else if ( aInterval.equalsIgnoreAsciiCase( "ym" ) )
- {
- // Return number of months, excluding years.
- int md = m2 - m1 + 12 * (y2 - y1);
- if (d1 > d2)
- --md;
- md %= 12;
- PushInt( md );
- }
- else if ( aInterval.equalsIgnoreAsciiCase( "yd" ) )
- {
- // Return number of days, excluding years.
-
- // Condition corresponds with "y".
- if (m2 > m1 || (m2 == m1 && d2 >= d1))
aDate1.SetYear( y2 );
- else
- aDate1.SetYear( y2 - 1 );
- // XXX NOTE: Excel for the case 1988-06-22,2012-05-11 returns
- // 323, whereas the result here is 324. Don't they use the leap
- // year of 2012?
- // http://www.cpearson.com/excel/datedif.aspx "DATEDIF And Leap
- // Years" is not correct and Excel 2010 correctly returns 0 in
- // both cases mentioned there. Also using year1 as mentioned
- // produces incorrect results in other cases and different from
- // Excel 2010. Apparently they fixed some calculations.
+ aDate1.SetMonth( m2 - 1 );
+ }
aDate1.Normalize();
- double fd = aDate2 - aDate1;
- PushDouble( fd );
+ nd = aDate2 - aDate1;
}
+ PushDouble( nd );
+ }
+ else if ( aInterval.equalsIgnoreAsciiCase( "ym" ) )
+ {
+ // Return number of months, excluding years.
+ int md = m2 - m1 + 12 * (y2 - y1);
+ if (d1 > d2)
+ --md;
+ md %= 12;
+ PushInt( md );
+ }
+ else if ( aInterval.equalsIgnoreAsciiCase( "yd" ) )
+ {
+ // Return number of days, excluding years.
+
+ // Condition corresponds with "y".
+ if (m2 > m1 || (m2 == m1 && d2 >= d1))
+ aDate1.SetYear( y2 );
else
- PushIllegalArgument(); // unsupported format
+ aDate1.SetYear( y2 - 1 );
+ // XXX NOTE: Excel for the case 1988-06-22,2012-05-11 returns
+ // 323, whereas the result here is 324. Don't they use the leap
+ // year of 2012?
+ // http://www.cpearson.com/excel/datedif.aspx "DATEDIF And Leap
+ // Years" is not correct and Excel 2010 correctly returns 0 in
+ // both cases mentioned there. Also using year1 as mentioned
+ // produces incorrect results in other cases and different from
+ // Excel 2010. Apparently they fixed some calculations.
+ aDate1.Normalize();
+ double fd = aDate2 - aDate1;
+ PushDouble( fd );
}
+ else
+ PushIllegalArgument(); // unsupported format
}
void ScInterpreter::ScGetTimeValue()
@@ -976,36 +976,36 @@ void ScInterpreter::ScInt()
void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode )
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fVal = 0.0;
+ if (nParamCount == 1)
+ fVal = ::rtl::math::round( GetDouble(), 0, eMode );
+ else
{
- double fVal = 0.0;
- if (nParamCount == 1)
- fVal = ::rtl::math::round( GetDouble(), 0, eMode );
+ sal_Int16 nDec = GetInt16();
+ double fX = GetDouble();
+ if ( nGlobalError != FormulaError::NONE || nDec < -20 || nDec > 20 )
+ PushIllegalArgument();
else
{
- sal_Int16 nDec = GetInt16();
- double fX = GetDouble();
- if ( nGlobalError != FormulaError::NONE || nDec < -20 || nDec > 20 )
- PushIllegalArgument();
- else
+ if ( ( eMode == rtl_math_RoundingMode_Down ||
+ eMode == rtl_math_RoundingMode_Up ) &&
+ nDec < 12 && fmod( fX, 1.0 ) != 0.0 )
{
- if ( ( eMode == rtl_math_RoundingMode_Down ||
- eMode == rtl_math_RoundingMode_Up ) &&
- nDec < 12 && fmod( fX, 1.0 ) != 0.0 )
- {
- // tdf124286 : round to 12 significant digits before rounding
- // down or up to avoid unexpected rounding errors
- // caused by decimal -> binary -> decimal conversion
- double fRes;
- RoundSignificant( fX, 12, fRes );
- fVal = ::rtl::math::round( fRes, nDec, eMode );
- }
- else
- fVal = ::rtl::math::round( fX, nDec, eMode );
+ // tdf124286 : round to 12 significant digits before rounding
+ // down or up to avoid unexpected rounding errors
+ // caused by decimal -> binary -> decimal conversion
+ double fRes;
+ RoundSignificant( fX, 12, fRes );
+ fVal = ::rtl::math::round( fRes, nDec, eMode );
}
+ else
+ fVal = ::rtl::math::round( fX, nDec, eMode );
}
- PushDouble(fVal);
}
+ PushDouble(fVal);
}
void ScInterpreter::ScRound()
@@ -1037,24 +1037,24 @@ void ScInterpreter::RoundSignificant( double fX, double fDigits, double &fRes )
// tdf#106931
void ScInterpreter::ScRoundSignificant()
{
- if ( MustHaveParamCount( GetByte(), 2 ) )
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ double fDigits = ::rtl::math::approxFloor( GetDouble() );
+ double fX = GetDouble();
+ if ( nGlobalError != FormulaError::NONE || fDigits < 1.0 )
{
- double fDigits = ::rtl::math::approxFloor( GetDouble() );
- double fX = GetDouble();
- if ( nGlobalError != FormulaError::NONE || fDigits < 1.0 )
- {
- PushIllegalArgument();
- return;
- }
+ PushIllegalArgument();
+ return;
+ }
- if ( fX == 0.0 )
- PushDouble( 0.0 );
- else
- {
- double fRes;
- RoundSignificant( fX, fDigits, fRes );
- PushDouble( fRes );
- }
+ if ( fX == 0.0 )
+ PushDouble( 0.0 );
+ else
+ {
+ double fRes;
+ RoundSignificant( fX, fDigits, fRes );
+ PushDouble( fRes );
}
}
@@ -1068,39 +1068,39 @@ void ScInterpreter::ScRoundSignificant()
void ScInterpreter::ScCeil( bool bODFF )
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 3 ) )
+ if ( !MustHaveParamCount( nParamCount, 1, 3 ) )
+ return;
+
+ bool bAbs = nParamCount == 3 && GetBool();
+ double fDec, fVal;
+ if ( nParamCount == 1 )
{
- bool bAbs = nParamCount == 3 && GetBool();
- double fDec, fVal;
- if ( nParamCount == 1 )
- {
- fVal = GetDouble();
+ fVal = GetDouble();
+ fDec = ( fVal < 0 ? -1 : 1 );
+ }
+ else
+ {
+ bool bArgumentMissing = IsMissing();
+ fDec = GetDouble();
+ fVal = GetDouble();
+ if ( bArgumentMissing )
fDec = ( fVal < 0 ? -1 : 1 );
- }
- else
- {
- bool bArgumentMissing = IsMissing();
- fDec = GetDouble();
- fVal = GetDouble();
- if ( bArgumentMissing )
- fDec = ( fVal < 0 ? -1 : 1 );
- }
- if ( fVal == 0 || fDec == 0.0 )
- PushInt( 0 );
+ }
+ if ( fVal == 0 || fDec == 0.0 )
+ PushInt( 0 );
+ else
+ {
+ if ( bODFF && fVal * fDec < 0 )
+ PushIllegalArgument();
else
{
- if ( bODFF && fVal * fDec < 0 )
- PushIllegalArgument();
- else
- {
- if ( fVal * fDec < 0.0 )
- fDec = -fDec;
+ if ( fVal * fDec < 0.0 )
+ fDec = -fDec;
- if ( !bAbs && fVal < 0.0 )
- PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
- else
- PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
- }
+ if ( !bAbs && fVal < 0.0 )
+ PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
+ else
+ PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
}
}
}
@@ -1108,42 +1108,42 @@ void ScInterpreter::ScCeil( bool bODFF )
void ScInterpreter::ScCeil_MS()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2 ) )
- {
- double fDec = GetDouble();
- double fVal = GetDouble();
- if ( fVal == 0 || fDec == 0.0 )
- PushInt(0);
- else if ( fVal * fDec > 0 )
- PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
- else if ( fVal < 0.0 )
- PushDouble(::rtl::math::approxFloor( fVal / -fDec ) * -fDec );
- else
- PushIllegalArgument();
- }
+ if ( !MustHaveParamCount( nParamCount, 2 ) )
+ return;
+
+ double fDec = GetDouble();
+ double fVal = GetDouble();
+ if ( fVal == 0 || fDec == 0.0 )
+ PushInt(0);
+ else if ( fVal * fDec > 0 )
+ PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
+ else if ( fVal < 0.0 )
+ PushDouble(::rtl::math::approxFloor( fVal / -fDec ) * -fDec );
+ else
+ PushIllegalArgument();
}
void ScInterpreter::ScCeil_Precise()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fDec, fVal;
+ if ( nParamCount == 1 )
{
- double fDec, fVal;
- if ( nParamCount == 1 )
- {
- fVal = GetDouble();
- fDec = 1.0;
- }
- else
- {
- fDec = fabs( GetDoubleWithDefault( 1.0 ));
- fVal = GetDouble();
- }
- if ( fDec == 0.0 || fVal == 0.0 )
- PushInt( 0 );
- else
- PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
+ fVal = GetDouble();
+ fDec = 1.0;
+ }
+ else
+ {
+ fDec = fabs( GetDoubleWithDefault( 1.0 ));
+ fVal = GetDouble();
}
+ if ( fDec == 0.0 || fVal == 0.0 )
+ PushInt( 0 );
+ else
+ PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
}
/** tdf69552 ODFF1.2 function FLOOR and Excel function FLOOR.MATH
@@ -1156,39 +1156,39 @@ void ScInterpreter::ScCeil_Precise()
void ScInterpreter::ScFloor( bool bODFF )
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 3 ) )
+ if ( !MustHaveParamCount( nParamCount, 1, 3 ) )
+ return;
+
+ bool bAbs = ( nParamCount == 3 && GetBool() );
+ double fDec, fVal;
+ if ( nParamCount == 1 )
{
- bool bAbs = ( nParamCount == 3 && GetBool() );
- double fDec, fVal;
- if ( nParamCount == 1 )
- {
- fVal = GetDouble();
+ fVal = GetDouble();
+ fDec = ( fVal < 0 ? -1 : 1 );
+ }
+ else
+ {
+ bool bArgumentMissing = IsMissing();
+ fDec = GetDouble();
+ fVal = GetDouble();
+ if ( bArgumentMissing )
fDec = ( fVal < 0 ? -1 : 1 );
- }
- else
- {
- bool bArgumentMissing = IsMissing();
- fDec = GetDouble();
- fVal = GetDouble();
- if ( bArgumentMissing )
- fDec = ( fVal < 0 ? -1 : 1 );
- }
- if ( fDec == 0.0 || fVal == 0.0 )
- PushInt( 0 );
+ }
+ if ( fDec == 0.0 || fVal == 0.0 )
+ PushInt( 0 );
+ else
+ {
+ if ( bODFF && ( fVal * fDec < 0.0 ) )
+ PushIllegalArgument();
else
{
- if ( bODFF && ( fVal * fDec < 0.0 ) )
- PushIllegalArgument();
- else
- {
- if ( fVal * fDec < 0.0 )
- fDec = -fDec;
+ if ( fVal * fDec < 0.0 )
+ fDec = -fDec;
- if ( !bAbs && fVal < 0.0 )
- PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
- else
- PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
- }
+ if ( !bAbs && fVal < 0.0 )
+ PushDouble(::rtl::math::approxCeil( fVal / fDec ) * fDec );
+ else
+ PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
}
}
}
@@ -1196,45 +1196,45 @@ void ScInterpreter::ScFloor( bool bODFF )
void ScInterpreter::ScFloor_MS()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2 ) )
- {
- double fDec = GetDouble();
- double fVal = GetDouble();
+ if ( !MustHaveParamCount( nParamCount, 2 ) )
+ return;
- if ( fVal == 0 )
- PushInt( 0 );
- else if ( fVal * fDec > 0 )
- PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
- else if ( fDec == 0 )
- PushIllegalArgument();
- else if ( fVal < 0.0 )
- PushDouble(::rtl::math::approxCeil( fVal / -fDec ) * -fDec );
- else
- PushIllegalArgument();
- }
+ double fDec = GetDouble();
+ double fVal = GetDouble();
+
+ if ( fVal == 0 )
+ PushInt( 0 );
+ else if ( fVal * fDec > 0 )
+ PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
+ else if ( fDec == 0 )
+ PushIllegalArgument();
+ else if ( fVal < 0.0 )
+ PushDouble(::rtl::math::approxCeil( fVal / -fDec ) * -fDec );
+ else
+ PushIllegalArgument();
}
void ScInterpreter::ScFloor_Precise()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fDec, fVal;
+ if ( nParamCount == 1 )
{
- double fDec, fVal;
- if ( nParamCount == 1 )
- {
- fVal = GetDouble();
- fDec = 1.0;
- }
- else
- {
- fDec = fabs( GetDoubleWithDefault( 1.0 ) );
- fVal = GetDouble();
- }
- if ( fDec == 0.0 || fVal == 0.0 )
- PushInt( 0 );
- else
- PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
+ fVal = GetDouble();
+ fDec = 1.0;
+ }
+ else
+ {
+ fDec = fabs( GetDoubleWithDefault( 1.0 ) );
+ fVal = GetDouble();
}
+ if ( fDec == 0.0 || fVal == 0.0 )
+ PushInt( 0 );
+ else
+ PushDouble(::rtl::math::approxFloor( fVal / fDec ) * fDec );
}
void ScInterpreter::ScEven()
@@ -1277,19 +1277,19 @@ void ScInterpreter::ScArcTan2()
void ScInterpreter::ScLog()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
- {
- double fBase;
- if (nParamCount == 2)
- fBase = GetDouble();
- else
- fBase = 10.0;
- double fVal = GetDouble();
- if (fVal > 0.0 && fBase > 0.0 && fBase != 1.0)
- PushDouble(log(fVal) / log(fBase));
- else
- PushIllegalArgument();
- }
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fBase;
+ if (nParamCount == 2)
+ fBase = GetDouble();
+ else
+ fBase = 10.0;
+ double fVal = GetDouble();
+ if (fVal > 0.0 && fBase > 0.0 && fBase != 1.0)
+ PushDouble(log(fVal) / log(fBase));
+ else
+ PushIllegalArgument();
}
void ScInterpreter::ScLn()
@@ -1314,98 +1314,98 @@ void ScInterpreter::ScNPV()
{
nFuncFmtType = SvNumFormatType::CURRENCY;
short nParamCount = GetByte();
- if ( MustHaveParamCountMin( nParamCount, 2) )
+ if ( !MustHaveParamCountMin( nParamCount, 2) )
+ return;
+
+ double fVal = 0.0;
+ // We turn the stack upside down!
+ ReverseStack( nParamCount);
+ if (nGlobalError == FormulaError::NONE)
{
- double fVal = 0.0;
- // We turn the stack upside down!
- ReverseStack( nParamCount);
- if (nGlobalError == FormulaError::NONE)
- {
- double fCount = 1.0;
- double fRate = GetDouble();
- --nParamCount;
- size_t nRefInList = 0;
- ScRange aRange;
- while (nParamCount-- > 0)
+ double fCount = 1.0;
+ double fRate = GetDouble();
+ --nParamCount;
+ size_t nRefInList = 0;
+ ScRange aRange;
+ while (nParamCount-- > 0)
+ {
+ switch (GetStackType())
{
- switch (GetStackType())
+ case svDouble :
+ {
+ fVal += (GetDouble() / pow(1.0 + fRate, fCount));
+ fCount++;
+ }
+ break;
+ case svSingleRef :
{
- case svDouble :
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ ScRefCellValue aCell(*pDok, aAdr);
+ if (!aCell.hasEmptyValue() && aCell.hasNumeric())
{
- fVal += (GetDouble() / pow(1.0 + fRate, fCount));
+ double fCellVal = GetCellValue(aAdr, aCell);
+ fVal += (fCellVal / pow(1.0 + fRate, fCount));
fCount++;
}
- break;
- case svSingleRef :
+ }
+ break;
+ case svDoubleRef :
+ case svRefList :
+ {
+ FormulaError nErr = FormulaError::NONE;
+ double fCellVal;
+ PopDoubleRef( aRange, nParamCount, nRefInList);
+ ScHorizontalValueIterator aValIter( pDok, aRange );
+ while ((nErr == FormulaError::NONE) && aValIter.GetNext(fCellVal, nErr))
{
- ScAddress aAdr;
- PopSingleRef( aAdr );
- ScRefCellValue aCell(*pDok, aAdr);
- if (!aCell.hasEmptyValue() && aCell.hasNumeric())
- {
- double fCellVal = GetCellValue(aAdr, aCell);
- fVal += (fCellVal / pow(1.0 + fRate, fCount));
- fCount++;
- }
+ fVal += (fCellVal / pow(1.0 + fRate, fCount));
+ fCount++;
}
- break;
- case svDoubleRef :
- case svRefList :
+ if ( nErr != FormulaError::NONE )
+ SetError(nErr);
+ }
+ break;
+ case svMatrix :
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ {
+ ScMatrixRef pMat = GetMatrix();
+ if (pMat)
{
- FormulaError nErr = FormulaError::NONE;
- double fCellVal;
- PopDoubleRef( aRange, nParamCount, nRefInList);
- ScHorizontalValueIterator aValIter( pDok, aRange );
- while ((nErr == FormulaError::NONE) && aValIter.GetNext(fCellVal, nErr))
+ SCSIZE nC, nR;
+ pMat->GetDimensions(nC, nR);
+ if (nC == 0 || nR == 0)
{
- fVal += (fCellVal / pow(1.0 + fRate, fCount));
- fCount++;
+ PushIllegalArgument();
+ return;
}
- if ( nErr != FormulaError::NONE )
- SetError(nErr);
- }
- break;
- case svMatrix :
- case svExternalSingleRef:
- case svExternalDoubleRef:
- {
- ScMatrixRef pMat = GetMatrix();
- if (pMat)
+ else
{
- SCSIZE nC, nR;
- pMat->GetDimensions(nC, nR);
- if (nC == 0 || nR == 0)
- {
- PushIllegalArgument();
- return;
- }
- else
+ double fx;
+ for ( SCSIZE j = 0; j < nC; j++ )
{
- double fx;
- for ( SCSIZE j = 0; j < nC; j++ )
+ for (SCSIZE k = 0; k < nR; ++k)
{
- for (SCSIZE k = 0; k < nR; ++k)
+ if (!pMat->IsValue(j,k))
{
- if (!pMat->IsValue(j,k))
- {
- PushIllegalArgument();
- return;
- }
- fx = pMat->GetDouble(j,k);
- fVal += (fx / pow(1.0 + fRate, fCount));
- fCount++;
+ PushIllegalArgument();
+ return;
}
+ fx = pMat->GetDouble(j,k);
+ fVal += (fx / pow(1.0 + fRate, fCount));
+ fCount++;
}
}
}
}
- break;
- default : SetError(FormulaError::IllegalParameter); break;
}
+ break;
+ default : SetError(FormulaError::IllegalParameter); break;
}
}
- PushDouble(fVal);
}
+ PushDouble(fVal);
}
void ScInterpreter::ScIRR()
@@ -1477,124 +1477,124 @@ void ScInterpreter::ScIRR()
void ScInterpreter::ScMIRR()
{ // range_of_values ; rate_invest ; rate_reinvest
nFuncFmtType = SvNumFormatType::PERCENT;
- if ( MustHaveParamCount( GetByte(), 3 ) )
- {
- double fRate1_reinvest = GetDouble() + 1;
- double fRate1_invest = GetDouble() + 1;
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
- ScRange aRange;
- ScMatrixRef pMat;
- SCSIZE nC = 0;
- SCSIZE nR = 0;
- bool bIsMatrix = false;
- switch ( GetStackType() )
- {
- case svDoubleRef :
- PopDoubleRef( aRange );
- break;
- case svMatrix :
- case svExternalSingleRef:
- case svExternalDoubleRef:
+ double fRate1_reinvest = GetDouble() + 1;
+ double fRate1_invest = GetDouble() + 1;
+
+ ScRange aRange;
+ ScMatrixRef pMat;
+ SCSIZE nC = 0;
+ SCSIZE nR = 0;
+ bool bIsMatrix = false;
+ switch ( GetStackType() )
+ {
+ case svDoubleRef :
+ PopDoubleRef( aRange );
+ break;
+ case svMatrix :
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ {
+ pMat = GetMatrix();
+ if ( pMat )
{
- pMat = GetMatrix();
- if ( pMat )
- {
- pMat->GetDimensions( nC, nR );
- if ( nC == 0 || nR == 0 )
- SetError( FormulaError::IllegalArgument );
- bIsMatrix = true;
- }
- else
+ pMat->GetDimensions( nC, nR );
+ if ( nC == 0 || nR == 0 )
SetError( FormulaError::IllegalArgument );
+ bIsMatrix = true;
}
- break;
- default :
- SetError( FormulaError::IllegalParameter );
- break;
- }
+ else
+ SetError( FormulaError::IllegalArgument );
+ }
+ break;
+ default :
+ SetError( FormulaError::IllegalParameter );
+ break;
+ }
- if ( nGlobalError != FormulaError::NONE )
- PushError( nGlobalError );
- else
- {
- double fNPV_reinvest = 0.0;
- double fPow_reinvest = 1.0;
- double fNPV_invest = 0.0;
- double fPow_invest = 1.0;
- sal_uLong nCount = 0;
- bool bHasPosValue = false;
- bool bHasNegValue = false;
+ if ( nGlobalError != FormulaError::NONE )
+ PushError( nGlobalError );
+ else
+ {
+ double fNPV_reinvest = 0.0;
+ double fPow_reinvest = 1.0;
+ double fNPV_invest = 0.0;
+ double fPow_invest = 1.0;
+ sal_uLong nCount = 0;
+ bool bHasPosValue = false;
+ bool bHasNegValue = false;
- if ( bIsMatrix )
+ if ( bIsMatrix )
+ {
+ double fX;
+ for ( SCSIZE j = 0; j < nC; j++ )
{
- double fX;
- for ( SCSIZE j = 0; j < nC; j++ )
+ for ( SCSIZE k = 0; k < nR; ++k )
{
- for ( SCSIZE k = 0; k < nR; ++k )
- {
- if ( !pMat->IsValue( j, k ) )
- continue;
- fX = pMat->GetDouble( j, k );
- if ( nGlobalError != FormulaError::NONE )
- break;
-
- if ( fX > 0.0 )
- { // reinvestments
- bHasPosValue = true;
- fNPV_reinvest += fX * fPow_reinvest;
- }
- else if ( fX < 0.0 )
- { // investments
- bHasNegValue = true;
- fNPV_invest += fX * fPow_invest;
- }
- fPow_reinvest /= fRate1_reinvest;
- fPow_invest /= fRate1_invest;
- nCount++;
- }
- }
- }
- else
- {
- ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags );
- double fCellValue;
- FormulaError nIterError = FormulaError::NONE;
+ if ( !pMat->IsValue( j, k ) )
+ continue;
+ fX = pMat->GetDouble( j, k );
+ if ( nGlobalError != FormulaError::NONE )
+ break;
- bool bLoop = aValIter.GetFirst( fCellValue, nIterError );
- while( bLoop )
- {
- if( fCellValue > 0.0 ) // reinvestments
+ if ( fX > 0.0 )
{ // reinvestments
bHasPosValue = true;
- fNPV_reinvest += fCellValue * fPow_reinvest;
+ fNPV_reinvest += fX * fPow_reinvest;
}
- else if( fCellValue < 0.0 ) // investments
+ else if ( fX < 0.0 )
{ // investments
bHasNegValue = true;
- fNPV_invest += fCellValue * fPow_invest;
+ fNPV_invest += fX * fPow_invest;
}
fPow_reinvest /= fRate1_reinvest;
fPow_invest /= fRate1_invest;
nCount++;
-
- bLoop = aValIter.GetNext( fCellValue, nIterError );
}
-
- if ( nIterError != FormulaError::NONE )
- SetError( nIterError );
}
- if ( !( bHasPosValue && bHasNegValue ) )
- SetError( FormulaError::IllegalArgument );
+ }
+ else
+ {
+ ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags );
+ double fCellValue;
+ FormulaError nIterError = FormulaError::NONE;
- if ( nGlobalError != FormulaError::NONE )
- PushError( nGlobalError );
- else
+ bool bLoop = aValIter.GetFirst( fCellValue, nIterError );
+ while( bLoop )
{
- double fResult = -fNPV_reinvest / fNPV_invest;
- fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) );
- fResult = pow( fResult, div( 1.0, (nCount - 1)) );
- PushDouble( fResult - 1.0 );
+ if( fCellValue > 0.0 ) // reinvestments
+ { // reinvestments
+ bHasPosValue = true;
+ fNPV_reinvest += fCellValue * fPow_reinvest;
+ }
+ else if( fCellValue < 0.0 ) // investments
+ { // investments
+ bHasNegValue = true;
+ fNPV_invest += fCellValue * fPow_invest;
+ }
+ fPow_reinvest /= fRate1_reinvest;
+ fPow_invest /= fRate1_invest;
+ nCount++;
+
+ bLoop = aValIter.GetNext( fCellValue, nIterError );
}
+
+ if ( nIterError != FormulaError::NONE )
+ SetError( nIterError );
+ }
+ if ( !( bHasPosValue && bHasNegValue ) )
+ SetError( FormulaError::IllegalArgument );
+
+ if ( nGlobalError != FormulaError::NONE )
+ PushError( nGlobalError );
+ else
+ {
+ double fResult = -fNPV_reinvest / fNPV_invest;
+ fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) );
+ fResult = pow( fResult, div( 1.0, (nCount - 1)) );
+ PushDouble( fResult - 1.0 );
}
}
}
@@ -1698,23 +1698,23 @@ void ScInterpreter::ScDDB()
{
nFuncFmtType = SvNumFormatType::CURRENCY;
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 4, 5 ) )
- {
- double fFactor;
- if (nParamCount == 5)
- fFactor = GetDouble();
- else
- fFactor = 2.0;
- double fPeriod = GetDouble();
- double fLife = GetDouble();
- double fSalvage = GetDouble();
- double fCost = GetDouble();
- if (fCost < 0.0 || fSalvage < 0.0 || fFactor <= 0.0 || fSalvage > fCost
- || fPeriod < 1.0 || fPeriod > fLife)
- PushIllegalArgument();
- else
- PushDouble(ScGetDDB(fCost, fSalvage, fLife, fPeriod, fFactor));
- }
+ if ( !MustHaveParamCount( nParamCount, 4, 5 ) )
+ return;
+
+ double fFactor;
+ if (nParamCount == 5)
+ fFactor = GetDouble();
+ else
+ fFactor = 2.0;
+ double fPeriod = GetDouble();
+ double fLife = GetDouble();
+ double fSalvage = GetDouble();
+ double fCost = GetDouble();
+ if (fCost < 0.0 || fSalvage < 0.0 || fFactor <= 0.0 || fSalvage > fCost
+ || fPeriod < 1.0 || fPeriod > fLife)
+ PushIllegalArgument();
+ else
+ PushDouble(ScGetDDB(fCost, fSalvage, fLife, fPeriod, fFactor));
}
void ScInterpreter::ScDB()
@@ -1811,86 +1811,86 @@ void ScInterpreter::ScVDB()
{
nFuncFmtType = SvNumFormatType::CURRENCY;
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 5, 7 ) )
+ if ( !MustHaveParamCount( nParamCount, 5, 7 ) )
+ return;
+
+ double fCost, fSalvage, fLife, fStart, fEnd, fFactor, fVdb = 0.0;
+ bool bNoSwitch;
+ if (nParamCount == 7)
+ bNoSwitch = GetBool();
+ else
+ bNoSwitch = false;
+ if (nParamCount >= 6)
+ fFactor = GetDouble();
+ else
+ fFactor = 2.0;
+ fEnd = GetDouble();
+ fStart = GetDouble();
+ fLife = GetDouble();
+ fSalvage = GetDouble();
+ fCost = GetDouble();
+ if (fStart < 0.0 || fEnd < fStart || fEnd > fLife || fCost < 0.0
+ || fSalvage > fCost || fFactor <= 0.0)
+ PushIllegalArgument();
+ else
{
- double fCost, fSalvage, fLife, fStart, fEnd, fFactor, fVdb = 0.0;
- bool bNoSwitch;
- if (nParamCount == 7)
- bNoSwitch = GetBool();
- else
- bNoSwitch = false;
- if (nParamCount >= 6)
- fFactor = GetDouble();
- else
- fFactor = 2.0;
- fEnd = GetDouble();
- fStart = GetDouble();
- fLife = GetDouble();
- fSalvage = GetDouble();
- fCost = GetDouble();
- if (fStart < 0.0 || fEnd < fStart || fEnd > fLife || fCost < 0.0
- || fSalvage > fCost || fFactor <= 0.0)
- PushIllegalArgument();
- else
- {
- double fIntStart = ::rtl::math::approxFloor(fStart);
- double fIntEnd = ::rtl::math::approxCeil(fEnd);
- sal_uLong nLoopStart = static_cast<sal_uLong>(fIntStart);
- sal_uLong nLoopEnd = static_cast<sal_uLong>(fIntEnd);
+ double fIntStart = ::rtl::math::approxFloor(fStart);
+ double fIntEnd = ::rtl::math::approxCeil(fEnd);
+ sal_uLong nLoopStart = static_cast<sal_uLong>(fIntStart);
+ sal_uLong nLoopEnd = static_cast<sal_uLong>(fIntEnd);
- fVdb = 0.0;
- if (bNoSwitch)
+ fVdb = 0.0;
+ if (bNoSwitch)
+ {
+ for (sal_uLong i = nLoopStart + 1; i <= nLoopEnd; i++)
{
- for (sal_uLong i = nLoopStart + 1; i <= nLoopEnd; i++)
- {
- double fTerm = ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(i), fFactor);
+ double fTerm = ScGetDDB(fCost, fSalvage, fLife, static_cast<double>(i), fFactor);
- //respect partial period in the Beginning/ End:
- if ( i == nLoopStart+1 )
- fTerm *= ( std::min( fEnd, fIntStart + 1.0 ) - fStart );
- else if ( i == nLoopEnd )
- fTerm *= ( fEnd + 1.0 - fIntEnd );
+ //respect partial period in the Beginning/ End:
+ if ( i == nLoopStart+1 )
+ fTerm *= ( std::min( fEnd, fIntStart + 1.0 ) - fStart );
+ else if ( i == nLoopEnd )
+ fTerm *= ( fEnd + 1.0 - fIntEnd );
- fVdb += fTerm;
- }
+ fVdb += fTerm;
}
- else
+ }
+ else
+ {
+ double fPart = 0.0;
+ // respect partial period in the Beginning / End:
+ if ( !::rtl::math::approxEqual( fStart, fIntStart ) ||
+ !::rtl::math::approxEqual( fEnd, fIntEnd ) )
{
- double fPart = 0.0;
- // respect partial period in the Beginning / End:
- if ( !::rtl::math::approxEqual( fStart, fIntStart ) ||
- !::rtl::math::approxEqual( fEnd, fIntEnd ) )
+ if ( !::rtl::math::approxEqual( fStart, fIntStart ) )
{
- if ( !::rtl::math::approxEqual( fStart, fIntStart ) )
- {
- // part to be subtracted at the beginning
- double fTempIntEnd = fIntStart + 1.0;
- double fTempValue = fCost -
- ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
- fPart += ( fStart - fIntStart ) *
- ScInterVDB( fTempValue, fSalvage, fLife, fLife - fIntStart,
- fTempIntEnd - fIntStart, fFactor);
- }
- if ( !::rtl::math::approxEqual( fEnd, fIntEnd ) )
- {
- // part to be subtracted at the end
- double fTempIntStart = fIntEnd - 1.0;
- double fTempValue = fCost -
- ScInterVDB( fCost, fSalvage, fLife, fLife, fTempIntStart, fFactor );
- fPart += ( fIntEnd - fEnd ) *
- ScInterVDB( fTempValue, fSalvage, fLife, fLife - fTempIntStart,
- fIntEnd - fTempIntStart, fFactor);
- }
+ // part to be subtracted at the beginning
+ double fTempIntEnd = fIntStart + 1.0;
+ double fTempValue = fCost -
+ ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
+ fPart += ( fStart - fIntStart ) *
+ ScInterVDB( fTempValue, fSalvage, fLife, fLife - fIntStart,
+ fTempIntEnd - fIntStart, fFactor);
+ }
+ if ( !::rtl::math::approxEqual( fEnd, fIntEnd ) )
+ {
+ // part to be subtracted at the end
+ double fTempIntStart = fIntEnd - 1.0;
+ double fTempValue = fCost -
+ ScInterVDB( fCost, fSalvage, fLife, fLife, fTempIntStart, fFactor );
+ fPart += ( fIntEnd - fEnd ) *
+ ScInterVDB( fTempValue, fSalvage, fLife, fLife - fTempIntStart,
+ fIntEnd - fTempIntStart, fFactor);
}
- // calculate depreciation for whole periods
- fCost -= ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
- fVdb = ScInterVDB( fCost, fSalvage, fLife, fLife - fIntStart,
- fIntEnd - fIntStart, fFactor);
- fVdb -= fPart;
}
+ // calculate depreciation for whole periods
+ fCost -= ScInterVDB( fCost, fSalvage, fLife, fLife, fIntStart, fFactor );
+ fVdb = ScInterVDB( fCost, fSalvage, fLife, fLife - fIntStart,
+ fIntEnd - fIntStart, fFactor);
+ fVdb -= fPart;
}
- PushDouble(fVdb);
}
+ PushDouble(fVdb);
}
void ScInterpreter::ScPDuration()
@@ -2269,104 +2269,104 @@ void ScInterpreter::ScPpmt()
void ScInterpreter::ScCumIpmt()
{
nFuncFmtType = SvNumFormatType::CURRENCY;
- if ( MustHaveParamCount( GetByte(), 6 ) )
- {
- double fRate, fNper, fPv, fStart, fEnd;
- double fFlag = GetDoubleWithDefault( -1.0 );
- fEnd = ::rtl::math::approxFloor(GetDouble());
- fStart = ::rtl::math::approxFloor(GetDouble());
- fPv = GetDouble();
- fNper = GetDouble();
- fRate = GetDouble();
- if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
- fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
- ( fFlag != 0.0 && fFlag != 1.0 ))
- PushIllegalArgument();
- else
+ if ( !MustHaveParamCount( GetByte(), 6 ) )
+ return;
+
+ double fRate, fNper, fPv, fStart, fEnd;
+ double fFlag = GetDoubleWithDefault( -1.0 );
+ fEnd = ::rtl::math::approxFloor(GetDouble());
+ fStart = ::rtl::math::approxFloor(GetDouble());
+ fPv = GetDouble();
+ fNper = GetDouble();
+ fRate = GetDouble();
+ if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
+ fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
+ ( fFlag != 0.0 && fFlag != 1.0 ))
+ PushIllegalArgument();
+ else
+ {
+ bool bPayInAdvance = static_cast<bool>(fFlag);
+ sal_uLong nStart = static_cast<sal_uLong>(fStart);
+ sal_uLong nEnd = static_cast<sal_uLong>(fEnd) ;
+ double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
+ double fIpmt = 0.0;
+ if (nStart == 1)
{
- bool bPayInAdvance = static_cast<bool>(fFlag);
- sal_uLong nStart = static_cast<sal_uLong>(fStart);
- sal_uLong nEnd = static_cast<sal_uLong>(fEnd) ;
- double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
- double fIpmt = 0.0;
- if (nStart == 1)
- {
- if (!bPayInAdvance)
- fIpmt = -fPv;
- nStart++;
- }
- for (sal_uLong i = nStart; i <= nEnd; i++)
- {
- if (bPayInAdvance)
- fIpmt += ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt;
- else
- fIpmt += ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false);
- }
- fIpmt *= fRate;
- PushDouble(fIpmt);
+ if (!bPayInAdvance)
+ fIpmt = -fPv;
+ nStart++;
}
+ for (sal_uLong i = nStart; i <= nEnd; i++)
+ {
+ if (bPayInAdvance)
+ fIpmt += ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt;
+ else
+ fIpmt += ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false);
+ }
+ fIpmt *= fRate;
+ PushDouble(fIpmt);
}
}
void ScInterpreter::ScCumPrinc()
{
nFuncFmtType = SvNumFormatType::CURRENCY;
- if ( MustHaveParamCount( GetByte(), 6 ) )
- {
- double fRate, fNper, fPv, fStart, fEnd;
- double fFlag = GetDoubleWithDefault( -1.0 );
- fEnd = ::rtl::math::approxFloor(GetDouble());
- fStart = ::rtl::math::approxFloor(GetDouble());
- fPv = GetDouble();
- fNper = GetDouble();
- fRate = GetDouble();
- if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
- fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
- ( fFlag != 0.0 && fFlag != 1.0 ))
- PushIllegalArgument();
- else
+ if ( !MustHaveParamCount( GetByte(), 6 ) )
+ return;
+
+ double fRate, fNper, fPv, fStart, fEnd;
+ double fFlag = GetDoubleWithDefault( -1.0 );
+ fEnd = ::rtl::math::approxFloor(GetDouble());
+ fStart = ::rtl::math::approxFloor(GetDouble());
+ fPv = GetDouble();
+ fNper = GetDouble();
+ fRate = GetDouble();
+ if (fStart < 1.0 || fEnd < fStart || fRate <= 0.0 ||
+ fEnd > fNper || fNper <= 0.0 || fPv <= 0.0 ||
+ ( fFlag != 0.0 && fFlag != 1.0 ))
+ PushIllegalArgument();
+ else
+ {
+ bool bPayInAdvance = static_cast<bool>(fFlag);
+ double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
+ double fPpmt = 0.0;
+ sal_uLong nStart = static_cast<sal_uLong>(fStart);
+ sal_uLong nEnd = static_cast<sal_uLong>(fEnd);
+ if (nStart == 1)
{
- bool bPayInAdvance = static_cast<bool>(fFlag);
- double fPmt = ScGetPMT(fRate, fNper, fPv, 0.0, bPayInAdvance);
- double fPpmt = 0.0;
- sal_uLong nStart = static_cast<sal_uLong>(fStart);
- sal_uLong nEnd = static_cast<sal_uLong>(fEnd);
- if (nStart == 1)
- {
- if (bPayInAdvance)
- fPpmt = fPmt;
- else
- fPpmt = fPmt + fPv * fRate;
- nStart++;
- }
- for (sal_uLong i = nStart; i <= nEnd; i++)
- {
- if (bPayInAdvance)
- fPpmt += fPmt - (ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt) * fRate;
- else
- fPpmt += fPmt - ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false) * fRate;
- }
- PushDouble(fPpmt);
+ if (bPayInAdvance)
+ fPpmt = fPmt;
+ else
+ fPpmt = fPmt + fPv * fRate;
+ nStart++;
}
+ for (sal_uLong i = nStart; i <= nEnd; i++)
+ {
+ if (bPayInAdvance)
+ fPpmt += fPmt - (ScGetFV(fRate, static_cast<double>(i-2), fPmt, fPv, true) - fPmt) * fRate;
+ else
+ fPpmt += fPmt - ScGetFV(fRate, static_cast<double>(i-1), fPmt, fPv, false) * fRate;
+ }
+ PushDouble(fPpmt);
}
}
void ScInterpreter::ScEffect()
{
nFuncFmtType = SvNumFormatType::PERCENT;
- if ( MustHaveParamCount( GetByte(), 2 ) )
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ double fPeriods = GetDouble();
+ double fNominal = GetDouble();
+ if (fPeriods < 1.0 || fNominal < 0.0)
+ PushIllegalArgument();
+ else if ( fNominal == 0.0 )
+ PushDouble( 0.0 );
+ else
{
- double fPeriods = GetDouble();
- double fNominal = GetDouble();
- if (fPeriods < 1.0 || fNominal < 0.0)
- PushIllegalArgument();
- else if ( fNominal == 0.0 )
- PushDouble( 0.0 );
- else
- {
- fPeriods = ::rtl::math::approxFloor(fPeriods);
- PushDouble(pow(1.0 + fNominal/fPeriods, fPeriods) - 1.0);
- }
+ fPeriods = ::rtl::math::approxFloor(fPeriods);
+ PushDouble(pow(1.0 + fNominal/fPeriods, fPeriods) - 1.0);
}
}
@@ -2389,23 +2389,23 @@ void ScInterpreter::ScNominal()
void ScInterpreter::ScMod()
{
- if ( MustHaveParamCount( GetByte(), 2 ) )
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ double fDenom = GetDouble(); // Denominator
+ if ( fDenom == 0.0 )
{
- double fDenom = GetDouble(); // Denominator
- if ( fDenom == 0.0 )
- {
- PushError(FormulaError::DivisionByZero);
- return;
- }
- double fNum = GetDouble(); // Numerator
- double fRes = ::rtl::math::approxSub( fNum,
- ::rtl::math::approxFloor( fNum / fDenom ) * fDenom );
- if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) ||
- ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) )
- PushDouble( fRes );
- else
- PushError( FormulaError::NoValue );
+ PushError(FormulaError::DivisionByZero);
+ return;
}
+ double fNum = GetDouble(); // Numerator
+ double fRes = ::rtl::math::approxSub( fNum,
+ ::rtl::math::approxFloor( fNum / fDenom ) * fDenom );
+ if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) ||
+ ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) )
+ PushDouble( fRes );
+ else
+ PushError( FormulaError::NoValue );
}
void ScInterpreter::ScIntersect()
@@ -2733,388 +2733,388 @@ void ScInterpreter::ScDde()
// application, Topic, Item
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 3, 4 ) )
+ if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
+ return;
+
+ sal_uInt8 nMode = SC_DDE_DEFAULT;
+ if (nParamCount == 4)
{
- sal_uInt8 nMode = SC_DDE_DEFAULT;
- if (nParamCount == 4)
+ sal_uInt32 nTmp = GetUInt32();
+ if (nGlobalError != FormulaError::NONE || nTmp > SAL_MAX_UINT8)
{
- sal_uInt32 nTmp = GetUInt32();
- if (nGlobalError != FormulaError::NONE || nTmp > SAL_MAX_UINT8)
- {
- PushIllegalArgument();
- return;
- }
- nMode = static_cast<sal_uInt8>(nTmp);
+ PushIllegalArgument();
+ return;
}
- OUString aItem = GetString().getString();
- OUString aTopic = GetString().getString();
- OUString aAppl = GetString().getString();
+ nMode = static_cast<sal_uInt8>(nTmp);
+ }
+ OUString aItem = GetString().getString();
+ OUString aTopic = GetString().getString();
+ OUString aAppl = GetString().getString();
- if (nMode > SC_DDE_TEXT)
- nMode = SC_DDE_DEFAULT;
+ if (nMode > SC_DDE_TEXT)
+ nMode = SC_DDE_DEFAULT;
- // temporary documents (ScFunctionAccess) have no DocShell
- // and no LinkManager -> abort
+ // temporary documents (ScFunctionAccess) have no DocShell
+ // and no LinkManager -> abort
- //sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager();
- if (!mpLinkManager)
- {
- PushNoValue();
- return;
- }
+ //sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager();
+ if (!mpLinkManager)
+ {
+ PushNoValue();
+ return;
+ }
- // Need to reinterpret after loading (build links)
- pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT );
+ // Need to reinterpret after loading (build links)
+ pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT );
- // while the link is not evaluated, idle must be disabled (to avoid circular references)
+ // while the link is not evaluated, idle must be disabled (to avoid circular references)
- bool bOldEnabled = pDok->IsIdleEnabled();
- pDok->EnableIdle(false);
+ bool bOldEnabled = pDok->IsIdleEnabled();
+ pDok->EnableIdle(false);
- // Get/ Create link object
+ // Get/ Create link object
- ScDdeLink* pLink = lcl_GetDdeLink( mpLinkManager, aAppl, aTopic, aItem, nMode );
+ ScDdeLink* pLink = lcl_GetDdeLink( mpLinkManager, aAppl, aTopic, aItem, nMode );
- //TODO: Save Dde-links (in addition) more efficient at document !!!!!
- // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem );
+ //TODO: Save Dde-links (in addition) more efficient at document !!!!!
+ // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem );
- bool bWasError = ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE );
+ bool bWasError = ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE );
- if (!pLink)
+ if (!pLink)
+ {
+ pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode );
+ mpLinkManager->InsertDDELink( pLink, aAppl, aTopic, aItem );
+ if ( mpLinkManager->GetLinks().size() == 1 ) // the first one?
{
- pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode );
- mpLinkManager->InsertDDELink( pLink, aAppl, aTopic, aItem );
- if ( mpLinkManager->GetLinks().size() == 1 ) // the first one?
- {
- SfxBindings* pBindings = pDok->GetViewBindings();
- if (pBindings)
- pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled
- }
-
- //if the document was just loaded, but the ScDdeLink entry was missing, then
- //don't update this link until the links are updated in response to the users
- //decision
- if (!pDok->HasLinkFormulaNeedingCheck())
- {
- //TODO: evaluate asynchron ???
- pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times
- }
+ SfxBindings* pBindings = pDok->GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled
+ }
- if (pMyFormulaCell)
- {
- // StartListening after the Update to avoid circular references
- pMyFormulaCell->StartListening( *pLink );
- }
+ //if the document was just loaded, but the ScDdeLink entry was missing, then
+ //don't update this link until the links are updated in response to the users
+ //decision
+ if (!pDok->HasLinkFormulaNeedingCheck())
+ {
+ //TODO: evaluate asynchron ???
+ pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times
}
- else
+
+ if (pMyFormulaCell)
{
- if (pMyFormulaCell)
- pMyFormulaCell->StartListening( *pLink );
+ // StartListening after the Update to avoid circular references
+ pMyFormulaCell->StartListening( *pLink );
}
+ }
+ else
+ {
+ if (pMyFormulaCell)
+ pMyFormulaCell->StartListening( *pLink );
+ }
- // If a new Error from Reschedule appears when the link is executed then reset the errorflag
+ // If a new Error from Reschedule appears when the link is executed then reset the errorflag
- if ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError )
- pMyFormulaCell->SetErrCode(FormulaError::NONE);
+ if ( pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError )
+ pMyFormulaCell->SetErrCode(FormulaError::NONE);
- // check the value
+ // check the value
- const ScMatrix* pLinkMat = pLink->GetResult();
- if (pLinkMat)
+ const ScMatrix* pLinkMat = pLink->GetResult();
+ if (pLinkMat)
+ {
+ SCSIZE nC, nR;
+ pLinkMat->GetDimensions(nC, nR);
+ ScMatrixRef pNewMat = GetNewMat( nC, nR);
+ if (pNewMat)
{
- SCSIZE nC, nR;
- pLinkMat->GetDimensions(nC, nR);
- ScMatrixRef pNewMat = GetNewMat( nC, nR);
- if (pNewMat)
- {
- pLinkMat->MatCopy(*pNewMat); // copy
- PushMatrix( pNewMat );
- }
- else
- PushIllegalArgument();
+ pLinkMat->MatCopy(*pNewMat); // copy
+ PushMatrix( pNewMat );
}
else
- PushNA();
-
- pDok->EnableIdle(bOldEnabled);
- mpLinkManager->CloseCachedComps();
+ PushIllegalArgument();
}
+ else
+ PushNA();
+
+ pDok->EnableIdle(bOldEnabled);
+ mpLinkManager->CloseCachedComps();
}
void ScInterpreter::ScBase()
{ // Value, Base [, MinLen]
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 2, 3 ) )
- {
- static const sal_Unicode pDigits[] = {
- '0','1','2','3','4','5','6','7','8','9',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M',
- 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
- 0
- };
- static const int nDigits = SAL_N_ELEMENTS(pDigits) - 1;
- sal_Int32 nMinLen;
- if ( nParamCount == 3 )
- {
- double fLen = ::rtl::math::approxFloor( GetDouble() );
- if ( 1.0 <= fLen && fLen < SAL_MAX_UINT16 )
- nMinLen = static_cast<sal_Int32>(fLen);
- else if ( fLen == 0.0 )
- nMinLen = 1;
- else
- nMinLen = 0; // Error
- }
- else
+ if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
+ return;
+
+ static const sal_Unicode pDigits[] = {
+ '0','1','2','3','4','5','6','7','8','9',
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M',
+ 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+ 0
+ };
+ static const int nDigits = SAL_N_ELEMENTS(pDigits) - 1;
+ sal_Int32 nMinLen;
+ if ( nParamCount == 3 )
+ {
+ double fLen = ::rtl::math::approxFloor( GetDouble() );
+ if ( 1.0 <= fLen && fLen < SAL_MAX_UINT16 )
+ nMinLen = static_cast<sal_Int32>(fLen);
+ else if ( fLen == 0.0 )
nMinLen = 1;
- double fBase = ::rtl::math::approxFloor( GetDouble() );
- double fVal = ::rtl::math::approxFloor( GetDouble() );
- double fChars = ((fVal > 0.0 && fBase > 0.0) ?
- (ceil( log( fVal ) / log( fBase ) ) + 2.0) :
- 2.0);
- if ( fChars >= SAL_MAX_UINT16 )
+ else
nMinLen = 0; // Error
-
- if ( nGlobalError == FormulaError::NONE && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal )
- {
- const sal_Int32 nConstBuf = 128;
- sal_Unicode aBuf[nConstBuf];
- sal_Int32 nBuf = std::max<sal_Int32>( fChars, nMinLen + 1 );
- sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]);
- for ( sal_Int32 j = 0; j < nBuf; ++j )
+ }
+ else
+ nMinLen = 1;
+ double fBase = ::rtl::math::approxFloor( GetDouble() );
+ double fVal = ::rtl::math::approxFloor( GetDouble() );
+ double fChars = ((fVal > 0.0 && fBase > 0.0) ?
+ (ceil( log( fVal ) / log( fBase ) ) + 2.0) :
+ 2.0);
+ if ( fChars >= SAL_MAX_UINT16 )
+ nMinLen = 0; // Error
+
+ if ( nGlobalError == FormulaError::NONE && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal )
+ {
+ const sal_Int32 nConstBuf = 128;
+ sal_Unicode aBuf[nConstBuf];
+ sal_Int32 nBuf = std::max<sal_Int32>( fChars, nMinLen + 1 );
+ sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]);
+ for ( sal_Int32 j = 0; j < nBuf; ++j )
+ {
+ pBuf[j] = '0';
+ }
+ sal_Unicode* p = pBuf + nBuf - 1;
+ *p = 0;
+ if ( o3tl::convertsToAtMost(fVal, sal_uLong(~0)) )
+ {
+ sal_uLong nVal = static_cast<sal_uLong>(fVal);
+ sal_uLong nBase = static_cast<sal_uLong>(fBase);
+ while ( nVal && p > pBuf )
{
- pBuf[j] = '0';
+ *--p = pDigits[ nVal % nBase ];
+ nVal /= nBase;
}
- sal_Unicode* p = pBuf + nBuf - 1;
- *p = 0;
- if ( o3tl::convertsToAtMost(fVal, sal_uLong(~0)) )
- {
- sal_uLong nVal = static_cast<sal_uLong>(fVal);
- sal_uLong nBase = static_cast<sal_uLong>(fBase);
- while ( nVal && p > pBuf )
- {
- *--p = pDigits[ nVal % nBase ];
- nVal /= nBase;
- }
- fVal = static_cast<double>(nVal);
- }
- else
+ fVal = static_cast<double>(nVal);
+ }
+ else
+ {
+ bool bDirt = false;
+ while ( fVal && p > pBuf )
{
- bool bDirt = false;
- while ( fVal && p > pBuf )
- {
//TODO: roundoff error starting with numbers greater than 2**48
// double fDig = ::rtl::math::approxFloor( fmod( fVal, fBase ) );
// a little bit better:
- double fInt = ::rtl::math::approxFloor( fVal / fBase );
- double fMult = fInt * fBase;
+ double fInt = ::rtl::math::approxFloor( fVal / fBase );
+ double fMult = fInt * fBase;
#if 0
- // =BASIS(1e308;36) => GPF with
- // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult );
- // in spite off previous test if fVal >= fMult
- double fDebug1 = fVal - fMult;
- // fVal := 7,5975311883090e+290
- // fMult := 7,5975311883090e+290
- // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error
- // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE
- double fDebug2 = ::rtl::math::approxSub( fVal, fMult );
- // and ::rtl::math::approxSub( fVal, fMult ) == 0
- double fDebug3 = ( fInt ? fVal / fInt : 0.0 );
-
- // Actual after strange fDebug1 and fVal < fMult is fDebug2 == fBase, but
- // anyway it can't be compared, then bDirt is executed an everything is good...
-
- // prevent compiler warnings
- (void)fDebug1; (void)fDebug2; (void)fDebug3;
+ // =BASIS(1e308;36) => GPF with
+ // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult );
+ // in spite off previous test if fVal >= fMult
+ double fDebug1 = fVal - fMult;
+ // fVal := 7,5975311883090e+290
+ // fMult := 7,5975311883090e+290
+ // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error
+ // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE
+ double fDebug2 = ::rtl::math::approxSub( fVal, fMult );
+ // and ::rtl::math::approxSub( fVal, fMult ) == 0
+ double fDebug3 = ( fInt ? fVal / fInt : 0.0 );
+
+ // Actual after strange fDebug1 and fVal < fMult is fDebug2 == fBase, but
+ // anyway it can't be compared, then bDirt is executed an everything is good...
+
+ // prevent compiler warnings
+ (void)fDebug1; (void)fDebug2; (void)fDebug3;
#endif
- size_t nDig;
- if ( fVal < fMult )
- { // something is wrong there
- bDirt = true;
- nDig = 0;
- }
- else
+ size_t nDig;
+ if ( fVal < fMult )
+ { // something is wrong there
+ bDirt = true;
+ nDig = 0;
+ }
+ else
+ {
+ double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) );
+ if ( bDirt )
{
- double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) );
- if ( bDirt )
- {
- bDirt = false;
- --fDig;
- }
- if ( fDig <= 0.0 )
- nDig = 0;
- else if ( fDig >= fBase )
- nDig = static_cast<size_t>(fBase) - 1;
- else
- nDig = static_cast<size_t>(fDig);
+ bDirt = false;
+ --fDig;
}
- *--p = pDigits[ nDig ];
- fVal = fInt;
+ if ( fDig <= 0.0 )
+ nDig = 0;
+ else if ( fDig >= fBase )
+ nDig = static_cast<size_t>(fBase) - 1;
+ else
+ nDig = static_cast<size_t>(fDig);
}
+ *--p = pDigits[ nDig ];
+ fVal = fInt;
}
- if ( fVal )
- PushError( FormulaError::StringOverflow );
- else
- {
- if ( nBuf - (p - pBuf) <= nMinLen )
- p = pBuf + nBuf - 1 - nMinLen;
- PushStringBuffer( p );
- }
- if ( pBuf != aBuf )
- delete [] pBuf;
}
+ if ( fVal )
+ PushError( FormulaError::StringOverflow );
else
- PushIllegalArgument();
+ {
+ if ( nBuf - (p - pBuf) <= nMinLen )
+ p = pBuf + nBuf - 1 - nMinLen;
+ PushStringBuffer( p );
+ }
+ if ( pBuf != aBuf )
+ delete [] pBuf;
}
+ else
+ PushIllegalArgument();
}
void ScInterpreter::ScDecimal()
{ // Text, Base
- if ( MustHaveParamCount( GetByte(), 2 ) )
+ if ( !MustHaveParamCount( GetByte(), 2 ) )
+ return;
+
+ double fBase = ::rtl::math::approxFloor( GetDouble() );
+ OUString aStr = GetString().getString();
+ if ( nGlobalError == FormulaError::NONE && 2 <= fBase && fBase <= 36 )
{
- double fBase = ::rtl::math::approxFloor( GetDouble() );
- OUString aStr = GetString().getString();
- if ( nGlobalError == FormulaError::NONE && 2 <= fBase && fBase <= 36 )
- {
- double fVal = 0.0;
- int nBase = static_cast<int>(fBase);
- const sal_Unicode* p = aStr.getStr();
- while ( *p == ' ' || *p == '\t' )
- p++; // strip leading white space
- if ( nBase == 16 )
- { // evtl. hex-prefix stripped
- if ( *p == 'x' || *p == 'X' )
- p++;
- else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') )
- p += 2;
- }
- while ( *p )
+ double fVal = 0.0;
+ int nBase = static_cast<int>(fBase);
+ const sal_Unicode* p = aStr.getStr();
+ while ( *p == ' ' || *p == '\t' )
+ p++; // strip leading white space
+ if ( nBase == 16 )
+ { // evtl. hex-prefix stripped
+ if ( *p == 'x' || *p == 'X' )
+ p++;
+ else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') )
+ p += 2;
+ }
+ while ( *p )
+ {
+ int n;
+ if ( '0' <= *p && *p <= '9' )
+ n = *p - '0';
+ else if ( 'A' <= *p && *p <= 'Z' )
+ n = 10 + (*p - 'A');
+ else if ( 'a' <= *p && *p <= 'z' )
+ n = 10 + (*p - 'a');
+ else
+ n = nBase;
+ if ( nBase <= n )
{
- int n;
- if ( '0' <= *p && *p <= '9' )
- n = *p - '0';
- else if ( 'A' <= *p && *p <= 'Z' )
- n = 10 + (*p - 'A');
- else if ( 'a' <= *p && *p <= 'z' )
- n = 10 + (*p - 'a');
+ if ( *(p+1) == 0 &&
+ ( (nBase == 2 && (*p == 'b' || *p == 'B'))
+ ||(nBase == 16 && (*p == 'h' || *p == 'H')) )
+ )
+ ; // 101b and F00Dh are ok
else
- n = nBase;
- if ( nBase <= n )
{
- if ( *(p+1) == 0 &&
- ( (nBase == 2 && (*p == 'b' || *p == 'B'))
- ||(nBase == 16 && (*p == 'h' || *p == 'H')) )
- )
- ; // 101b and F00Dh are ok
- else
- {
- PushIllegalArgument();
- return ;
- }
+ PushIllegalArgument();
+ return ;
}
- else
- fVal = fVal * fBase + n;
- p++;
-
}
- PushDouble( fVal );
+ else
+ fVal = fVal * fBase + n;
+ p++;
+
}
- else
- PushIllegalArgument();
+ PushDouble( fVal );
}
+ else
+ PushIllegalArgument();
}
void ScInterpreter::ScConvertOOo()
{ // Value, FromUnit, ToUnit
- if ( MustHaveParamCount( GetByte(), 3 ) )
+ if ( !MustHaveParamCount( GetByte(), 3 ) )
+ return;
+
+ OUString aToUnit = GetString().getString();
+ OUString aFromUnit = GetString().getString();
+ double fVal = GetDouble();
+ if ( nGlobalError != FormulaError::NONE )
+ PushError( nGlobalError);
+ else
{
- OUString aToUnit = GetString().getString();
- OUString aFromUnit = GetString().getString();
- double fVal = GetDouble();
- if ( nGlobalError != FormulaError::NONE )
- PushError( nGlobalError);
+ // first of all search for the given order; if it can't be found then search for the inverse
+ double fConv;
+ if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) )
+ PushDouble( fVal * fConv );
+ else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) )
+ PushDouble( fVal / fConv );
else
- {
- // first of all search for the given order; if it can't be found then search for the inverse
- double fConv;
- if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) )
- PushDouble( fVal * fConv );
- else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) )
- PushDouble( fVal / fConv );
- else
- PushNA();
- }
+ PushNA();
}
}
void ScInterpreter::ScRoman()
{ // Value [Mode]
sal_uInt8 nParamCount = GetByte();
- if( MustHaveParamCount( nParamCount, 1, 2 ) )
+ if( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0;
+ double fVal = ::rtl::math::approxFloor( GetDouble() );
+ if( nGlobalError != FormulaError::NONE )
+ PushError( nGlobalError);
+ else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) )
{
- double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0;
- double fVal = ::rtl::math::approxFloor( GetDouble() );
- if( nGlobalError != FormulaError::NONE )
- PushError( nGlobalError);
- else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) )
- {
- static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
- static const sal_uInt16 pValues[] = { 1000, 500, 100, 50, 10, 5, 1 };
- static const sal_uInt16 nMaxIndex = sal_uInt16(SAL_N_ELEMENTS(pValues) - 1);
+ static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
+ static const sal_uInt16 pValues[] = { 1000, 500, 100, 50, 10, 5, 1 };
+ static const sal_uInt16 nMaxIndex = sal_uInt16(SAL_N_ELEMENTS(pValues) - 1);
+
+ OUStringBuffer aRoman;
+ sal_uInt16 nVal = static_cast<sal_uInt16>(fVal);
+ sal_uInt16 nMode = static_cast<sal_uInt16>(fMode);
- OUStringBuffer aRoman;
- sal_uInt16 nVal = static_cast<sal_uInt16>(fVal);
- sal_uInt16 nMode = static_cast<sal_uInt16>(fMode);
+ for( sal_uInt16 i = 0; i <= nMaxIndex / 2; i++ )
+ {
+ sal_uInt16 nIndex = 2 * i;
+ sal_uInt16 nDigit = nVal / pValues[ nIndex ];
- for( sal_uInt16 i = 0; i <= nMaxIndex / 2; i++ )
+ if( (nDigit % 5) == 4 )
{
- sal_uInt16 nIndex = 2 * i;
- sal_uInt16 nDigit = nVal / pValues[ nIndex ];
+ // assert can't happen with nVal<4000 precondition
+ assert( ((nDigit == 4) ? (nIndex >= 1) : (nIndex >= 2)));
- if( (nDigit % 5) == 4 )
+ sal_uInt16 nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2;
+ sal_uInt16 nSteps = 0;
+ while( (nSteps < nMode) && (nIndex < nMaxIndex) )
+ {
+ nSteps++;
+ if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal )
+ nIndex++;
+ else
+ nSteps = nMode;
+ }
+ aRoman.append( pChars[ nIndex ] ).append( pChars[ nIndex2 ] );
+ nVal = sal::static_int_cast<sal_uInt16>( nVal + pValues[ nIndex ] );
+ nVal = sal::static_int_cast<sal_uInt16>( nVal - pValues[ nIndex2 ] );
+ }
+ else
+ {
+ if( nDigit > 4 )
{
// assert can't happen with nVal<4000 precondition
- assert( ((nDigit == 4) ? (nIndex >= 1) : (nIndex >= 2)));
-
- sal_uInt16 nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2;
- sal_uInt16 nSteps = 0;
- while( (nSteps < nMode) && (nIndex < nMaxIndex) )
- {
- nSteps++;
- if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal )
- nIndex++;
- else
- nSteps = nMode;
- }
- aRoman.append( pChars[ nIndex ] ).append( pChars[ nIndex2 ] );
- nVal = sal::static_int_cast<sal_uInt16>( nVal + pValues[ nIndex ] );
- nVal = sal::static_int_cast<sal_uInt16>( nVal - pValues[ nIndex2 ] );
+ assert( nIndex >= 1 );
+ aRoman.append( pChars[ nIndex - 1 ] );
}
- else
+ sal_Int32 nPad = nDigit % 5;
+ if (nPad)
{
- if( nDigit > 4 )
- {
- // assert can't happen with nVal<4000 precondition
- assert( nIndex >= 1 );
- aRoman.append( pChars[ nIndex - 1 ] );
- }
- sal_Int32 nPad = nDigit % 5;
- if (nPad)
- {
- OUStringBuffer aBuf(aRoman);
- comphelper::string::padToLength(aBuf, aBuf.getLength() + nPad,
- pChars[nIndex]);
- aRoman = aBuf.makeStringAndClear();
- }
- nVal %= pValues[ nIndex ];
+ OUStringBuffer aBuf(aRoman);
+ comphelper::string::padToLength(aBuf, aBuf.getLength() + nPad,
+ pChars[nIndex]);
+ aRoman = aBuf.makeStringAndClear();
}
+ nVal %= pValues[ nIndex ];
}
-
- PushString( aRoman.makeStringAndClear() );
}
- else
- PushIllegalArgument();
+
+ PushString( aRoman.makeStringAndClear() );
}
+ else
+ PushIllegalArgument();
}
static bool lcl_GetArabicValue( sal_Unicode cChar, sal_uInt16& rnValue, bool& rbIsDec )
@@ -3193,85 +3193,85 @@ void ScInterpreter::ScArabic()
void ScInterpreter::ScHyperLink()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1, 2 ) )
- {
- double fVal = 0.0;
- svl::SharedString aStr;
- ScMatValType nResultType = ScMatValType::String;
+ if ( !MustHaveParamCount( nParamCount, 1, 2 ) )
+ return;
+
+ double fVal = 0.0;
+ svl::SharedString aStr;
+ ScMatValType nResultType = ScMatValType::String;
- if ( nParamCount == 2 )
+ if ( nParamCount == 2 )
+ {
+ switch ( GetStackType() )
{
- switch ( GetStackType() )
+ case svDouble:
+ fVal = GetDouble();
+ nResultType = ScMatValType::Value;
+ break;
+ case svString:
+ aStr = GetString();
+ break;
+ case svSingleRef:
+ case svDoubleRef:
{
- case svDouble:
- fVal = GetDouble();
- nResultType = ScMatValType::Value;
- break;
- case svString:
- aStr = GetString();
- break;
- case svSingleRef:
- case svDoubleRef:
- {
- ScAddress aAdr;
- if ( !PopDoubleRefOrSingleRef( aAdr ) )
- break;
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
- ScRefCellValue aCell(*pDok, aAdr);
- if (aCell.hasEmptyValue())
- nResultType = ScMatValType::Empty;
- else
+ ScRefCellValue aCell(*pDok, aAdr);
+ if (aCell.hasEmptyValue())
+ nResultType = ScMatValType::Empty;
+ else
+ {
+ FormulaError nErr = GetCellErrCode(aCell);
+ if (nErr != FormulaError::NONE)
+ SetError( nErr);
+ else if (aCell.hasNumeric())
{
- FormulaError nErr = GetCellErrCode(aCell);
- if (nErr != FormulaError::NONE)
- SetError( nErr);
- else if (aCell.hasNumeric())
- {
- fVal = GetCellValue(aAdr, aCell);
- nResultType = ScMatValType::Value;
- }
- else
- GetCellString(aStr, aCell);
+ fVal = GetCellValue(aAdr, aCell);
+ nResultType = ScMatValType::Value;
}
+ else
+ GetCellString(aStr, aCell);
}
- break;
- case svMatrix:
- nResultType = GetDoubleOrStringFromMatrix( fVal, aStr);
- break;
- case svMissing:
- case svEmptyCell:
- Pop();
- // mimic xcl
- fVal = 0.0;
- nResultType = ScMatValType::Value;
- break;
- default:
- PopError();
- SetError( FormulaError::IllegalArgument);
}
+ break;
+ case svMatrix:
+ nResultType = GetDoubleOrStringFromMatrix( fVal, aStr);
+ break;
+ case svMissing:
+ case svEmptyCell:
+ Pop();
+ // mimic xcl
+ fVal = 0.0;
+ nResultType = ScMatValType::Value;
+ break;
+ default:
+ PopError();
+ SetError( FormulaError::IllegalArgument);
}
- svl::SharedString aUrl = GetString();
- ScMatrixRef pResMat = GetNewMat( 1, 2);
- if (nGlobalError != FormulaError::NONE)
- {
- fVal = CreateDoubleError( nGlobalError);
- nResultType = ScMatValType::Value;
- }
- if (nParamCount == 2 || nGlobalError != FormulaError::NONE)
- {
- if (ScMatrix::IsValueType( nResultType))
- pResMat->PutDouble( fVal, 0);
- else if (ScMatrix::IsRealStringType( nResultType))
- pResMat->PutString(aStr, 0);
- else // EmptyType, EmptyPathType, mimic xcl
- pResMat->PutDouble( 0.0, 0 );
- }
- else
- pResMat->PutString(aUrl, 0);
- pResMat->PutString(aUrl, 1);
- bMatrixFormula = true;
- PushMatrix(pResMat);
}
+ svl::SharedString aUrl = GetString();
+ ScMatrixRef pResMat = GetNewMat( 1, 2);
+ if (nGlobalError != FormulaError::NONE)
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nResultType = ScMatValType::Value;
+ }
+ if (nParamCount == 2 || nGlobalError != FormulaError::NONE)
+ {
+ if (ScMatrix::IsValueType( nResultType))
+ pResMat->PutDouble( fVal, 0);
+ else if (ScMatrix::IsRealStringType( nResultType))
+ pResMat->PutString(aStr, 0);
+ else // EmptyType, EmptyPathType, mimic xcl
+ pResMat->PutDouble( 0.0, 0 );
+ }
+ else
+ pResMat->PutString(aUrl, 0);
+ pResMat->PutString(aUrl, 1);
+ bMatrixFormula = true;
+ PushMatrix(pResMat);
}
/** Resources at the website of the European Commission:
@@ -3322,58 +3322,58 @@ static bool lclConvertMoney( const OUString& aSearchUnit, double& rfRate, int& r
void ScInterpreter::ScEuroConvert()
{ //Value, FromUnit, ToUnit[, FullPrecision, [TriangulationPrecision]]
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 3, 5 ) )
+ if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
+ return;
+
+ double fPrecision = 0.0;
+ if ( nParamCount == 5 )
{
- double fPrecision = 0.0;
- if ( nParamCount == 5 )
+ fPrecision = ::rtl::math::approxFloor(GetDouble());
+ if ( fPrecision < 3 )
{
- fPrecision = ::rtl::math::approxFloor(GetDouble());
- if ( fPrecision < 3 )
- {
- PushIllegalArgument();
- return;
- }
+ PushIllegalArgument();
+ return;
}
- bool bFullPrecision = false;
- if ( nParamCount >= 4 )
- bFullPrecision = GetBool();
- OUString aToUnit = GetString().getString();
- OUString aFromUnit = GetString().getString();
- double fVal = GetDouble();
- if ( nGlobalError != FormulaError::NONE )
- PushError( nGlobalError);
- else
+ }
+ bool bFullPrecision = false;
+ if ( nParamCount >= 4 )
+ bFullPrecision = GetBool();
+ OUString aToUnit = GetString().getString();
+ OUString aFromUnit = GetString().getString();
+ double fVal = GetDouble();
+ if ( nGlobalError != FormulaError::NONE )
+ PushError( nGlobalError);
+ else
+ {
+ double fFromRate;
+ double fToRate;
+ int nFromDec;
+ int nToDec;
+ if ( lclConvertMoney( aFromUnit, fFromRate, nFromDec )
+ && lclConvertMoney( aToUnit, fToRate, nToDec ) )
{
- double fFromRate;
- double fToRate;
- int nFromDec;
- int nToDec;
- if ( lclConvertMoney( aFromUnit, fFromRate, nFromDec )
- && lclConvertMoney( aToUnit, fToRate, nToDec ) )
+ double fRes;
+ if ( aFromUnit.equalsIgnoreAsciiCase( aToUnit ) )
+ fRes = fVal;
+ else
{
- double fRes;
- if ( aFromUnit.equalsIgnoreAsciiCase( aToUnit ) )
- fRes = fVal;
+ if ( aFromUnit.equalsIgnoreAsciiCase( "EUR" ) )
+ fRes = fVal * fToRate;
else
{
- if ( aFromUnit.equalsIgnoreAsciiCase( "EUR" ) )
- fRes = fVal * fToRate;
- else
- {
- double fIntermediate = fVal / fFromRate;
- if ( fPrecision )
- fIntermediate = ::rtl::math::round( fIntermediate,
- static_cast<int>(fPrecision) );
- fRes = fIntermediate * fToRate;
- }
- if ( !bFullPrecision )
- fRes = ::rtl::math::round( fRes, nToDec );
+ double fIntermediate = fVal / fFromRate;
+ if ( fPrecision )
+ fIntermediate = ::rtl::math::round( fIntermediate,
+ static_cast<int>(fPrecision) );
+ fRes = fIntermediate * fToRate;
}
- PushDouble( fRes );
+ if ( !bFullPrecision )
+ fRes = ::rtl::math::round( fRes, nToDec );
}
- else
- PushIllegalArgument();
+ PushDouble( fRes );
}
+ else
+ PushIllegalArgument();
}
}
@@ -3470,23 +3470,23 @@ void lclAppendBlock( OStringBuffer& rText, sal_Int32 nValue )
lclAppendPow10( rText, nValue / 100, 2 );
nValue %= 100;
}
- if( nValue > 0 )
+ if( nValue <= 0 )
+ return;
+
+ sal_Int32 nTen = nValue / 10;
+ sal_Int32 nOne = nValue % 10;
+ if( nTen >= 1 )
{
- sal_Int32 nTen = nValue / 10;
- sal_Int32 nOne = nValue % 10;
- if( nTen >= 1 )
- {
- if( nTen >= 3 )
- lclAppendDigit( rText, nTen );
- else if( nTen == 2 )
- rText.append( UTF8_TH_20 );
- rText.append( UTF8_TH_10 );
- }
- if( (nTen > 0) && (nOne == 1) )
- rText.append( UTF8_TH_11 );
- else if( nOne > 0 )
- lclAppendDigit( rText, nOne );
+ if( nTen >= 3 )
+ lclAppendDigit( rText, nTen );
+ else if( nTen == 2 )
+ rText.append( UTF8_TH_20 );
+ rText.append( UTF8_TH_10 );
}
+ if( (nTen > 0) && (nOne == 1) )
+ rText.append( UTF8_TH_11 );
+ else if( nOne > 0 )
+ lclAppendDigit( rText, nOne );
}
} // namespace
@@ -3494,68 +3494,68 @@ void lclAppendBlock( OStringBuffer& rText, sal_Int32 nValue )
void ScInterpreter::ScBahtText()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCount( nParamCount, 1 ) )
- {
- double fValue = GetDouble();
- if( nGlobalError != FormulaError::NONE )
- {
- PushError( nGlobalError);
- return;
- }
-
- // sign
- bool bMinus = fValue < 0.0;
- fValue = fabs( fValue );
+ if ( !MustHaveParamCount( nParamCount, 1 ) )
+ return;
- // round to 2 digits after decimal point, fValue contains Satang as integer
- fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 );
+ double fValue = GetDouble();
+ if( nGlobalError != FormulaError::NONE )
+ {
+ PushError( nGlobalError);
+ return;
+ }
- // split Baht and Satang
- double fBaht = 0.0;
- sal_Int32 nSatang = 0;
- lclSplitBlock( fBaht, nSatang, fValue, 100.0 );
+ // sign
+ bool bMinus = fValue < 0.0;
+ fValue = fabs( fValue );
- OStringBuffer aText;
+ // round to 2 digits after decimal point, fValue contains Satang as integer
+ fValue = ::rtl::math::approxFloor( fValue * 100.0 + 0.5 );
- // generate text for Baht value
- if( fBaht == 0.0 )
- {
- if( nSatang == 0 )
- aText.append( UTF8_TH_0 );
- }
- else while( fBaht > 0.0 )
- {
- OStringBuffer aBlock;
- sal_Int32 nBlock = 0;
- lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 );
- if( nBlock > 0 )
- lclAppendBlock( aBlock, nBlock );
- // add leading "million", if there will come more blocks
- if( fBaht > 0.0 )
- aBlock.insert( 0, UTF8_TH_1E6 );
+ // split Baht and Satang
+ double fBaht = 0.0;
+ sal_Int32 nSatang = 0;
+ lclSplitBlock( fBaht, nSatang, fValue, 100.0 );
- aText.insert(0, aBlock.makeStringAndClear());
- }
- if (!aText.isEmpty())
- aText.append( UTF8_TH_BAHT );
+ OStringBuffer aText;
- // generate text for Satang value
+ // generate text for Baht value
+ if( fBaht == 0.0 )
+ {
if( nSatang == 0 )
- {
- aText.append( UTF8_TH_DOT0 );
- }
- else
- {
- lclAppendBlock( aText, nSatang );
- aText.append( UTF8_TH_SATANG );
- }
+ aText.append( UTF8_TH_0 );
+ }
+ else while( fBaht > 0.0 )
+ {
+ OStringBuffer aBlock;
+ sal_Int32 nBlock = 0;
+ lclSplitBlock( fBaht, nBlock, fBaht, 1.0e6 );
+ if( nBlock > 0 )
+ lclAppendBlock( aBlock, nBlock );
+ // add leading "million", if there will come more blocks
+ if( fBaht > 0.0 )
+ aBlock.insert( 0, UTF8_TH_1E6 );
- // add the minus sign
- if( bMinus )
- aText.insert( 0, UTF8_TH_MINUS );
+ aText.insert(0, aBlock.makeStringAndClear());
+ }
+ if (!aText.isEmpty())
+ aText.append( UTF8_TH_BAHT );
- PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) );
+ // generate text for Satang value
+ if( nSatang == 0 )
+ {
+ aText.append( UTF8_TH_DOT0 );
+ }
+ else
+ {
+ lclAppendBlock( aText, nSatang );
+ aText.append( UTF8_TH_SATANG );
}
+
+ // add the minus sign
+ if( bMinus )
+ aText.insert( 0, UTF8_TH_MINUS );
+
+ PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) );
}
void ScInterpreter::ScGetPivotData()