// C++ test program for Number Class
void DoNumTest() {
clsNumDbFld numTmp( "1.123456789" );
short shTmp;
USHORT ushTmp;
int iTmp;
UINT uiTmp;
long lTmp;
ULONG ulTmp;
double dTmp;
LPCSTR ptrTmp;
CString str;
clsStrPlus strTmp;
clsValDbFld valTmp;
/*
Following checks make sure that the comparison functions are invoked properly
by
converting the other data type to clsNumDbFld, instead of clsNumDbFld
being
converted to the other datatype, in which case the assertions would fail
because
of data truncation */
shTmp = 1;
ASSERT( shTmp == (short) (double) numTmp );
ASSERT( !(shTmp == numTmp) );
ASSERT( !(numTmp == shTmp) );
ASSERT( shTmp != numTmp );
ASSERT( numTmp != shTmp );
ASSERT( shTmp <= numTmp );
ASSERT( !(numTmp <= shTmp) );
ASSERT( numTmp >= shTmp );
ASSERT( !(shTmp >= numTmp) );
ushTmp = 1;
ASSERT( ushTmp == (USHORT) (double) numTmp );
ASSERT( !(ushTmp == numTmp) );
ASSERT( !(numTmp == ushTmp) );
ASSERT( ushTmp != numTmp );
ASSERT( numTmp != ushTmp );
ASSERT( ushTmp <= numTmp );
ASSERT( !(numTmp <= ushTmp) );
ASSERT( numTmp >= ushTmp );
ASSERT( !(ushTmp >= numTmp) );
iTmp = 1;
ASSERT( iTmp == (int) (double) numTmp );
ASSERT( !(iTmp == numTmp) );
ASSERT( !(numTmp == iTmp) );
ASSERT( iTmp != numTmp );
ASSERT( numTmp != iTmp );
ASSERT( iTmp <= numTmp );
ASSERT( !(numTmp <= iTmp) );
ASSERT( numTmp >= iTmp );
ASSERT( !(iTmp >= numTmp) );
uiTmp = 1;
ASSERT( uiTmp == (UINT) (double) numTmp );
ASSERT( !(uiTmp == numTmp) );
ASSERT( !(numTmp == uiTmp) );
ASSERT( uiTmp != numTmp );
ASSERT( numTmp != uiTmp );
ASSERT( uiTmp <= numTmp );
ASSERT( !(numTmp <= uiTmp) );
ASSERT( numTmp >= uiTmp );
ASSERT( !(uiTmp >= numTmp) );
lTmp = 1;
ASSERT( lTmp == (long) (double) numTmp );
ASSERT( !(lTmp == numTmp) );
ASSERT( !(numTmp == lTmp) );
ASSERT( lTmp != numTmp );
ASSERT( numTmp != lTmp );
ASSERT( lTmp <= numTmp );
ASSERT( !(numTmp <= lTmp) );
ASSERT( numTmp >= lTmp );
ASSERT( !(lTmp >= numTmp) );
ulTmp = 1;
ASSERT( ulTmp == (ULONG)(double)numTmp );
ASSERT( !(ulTmp == numTmp) );
ASSERT( !(numTmp == ulTmp) );
ASSERT( ulTmp != numTmp );
ASSERT( numTmp != ulTmp );
ASSERT( ulTmp <= numTmp );
ASSERT( !(numTmp <= ulTmp) );
ASSERT( numTmp >= ulTmp );
ASSERT( !(ulTmp >= numTmp) );
/*
If the double datatype is converted to clsNumDbFld, it gets rounded
properly.
On the other hand if clsNumDbFld is converted to double, it
should yield the
rounded value and hence should be different than the original
double value */
dTmp = 1.1234567891;
ASSERT( dTmp != (double) numTmp );
ASSERT( dTmp == numTmp );
ASSERT( numTmp == dTmp );
ASSERT( !(dTmp != numTmp) );
ASSERT( !(numTmp != dTmp) );
ASSERT( dTmp <= numTmp );
ASSERT( numTmp <= dTmp );
ASSERT( numTmp >= dTmp );
ASSERT( dTmp >= numTmp );
/*
Following checks make sure that the string data type is converted to
clsNumDbFld
instead of the other way in which case the leading and trailing
zeroes can cause
the string comparison to fail resulting in assert failure. */
strTmp = "01.12345679000";
ASSERT( strTmp != (clsStrPlus) numTmp );
ASSERT( strTmp == numTmp );
ASSERT( numTmp == strTmp );
ASSERT( !(strTmp != numTmp) );
ASSERT( !(numTmp != strTmp) );
ASSERT( strTmp <= numTmp );
ASSERT( numTmp <= strTmp );
ASSERT( numTmp >= strTmp );
ASSERT( strTmp >= numTmp );
ptrTmp = strTmp;
ASSERT( ptrTmp != (clsStrPlus) numTmp );
ASSERT( ptrTmp == numTmp );
ASSERT( numTmp == ptrTmp );
ASSERT( !(ptrTmp != numTmp) );
ASSERT( !(numTmp != ptrTmp) );
ASSERT( ptrTmp <= numTmp );
ASSERT( numTmp <= ptrTmp );
ASSERT( numTmp >= ptrTmp );
ASSERT( ptrTmp >= numTmp );
str = strTmp;
ASSERT( str != (CString) numTmp );
ASSERT( str == numTmp );
ASSERT( numTmp == str );
ASSERT( !(str != numTmp) );
ASSERT( !(numTmp != str) );
ASSERT( str <= numTmp );
ASSERT( numTmp <= str );
ASSERT( numTmp >= str );
ASSERT( str >= numTmp );
valTmp = strTmp;
ASSERT( valTmp != (clsValDbFld) numTmp );
ASSERT( valTmp == numTmp );
ASSERT( numTmp == valTmp );
ASSERT( !(valTmp != numTmp) );
ASSERT( !(numTmp != valTmp) );
ASSERT( valTmp <= numTmp );
ASSERT( numTmp <= valTmp );
ASSERT( numTmp >= valTmp );
ASSERT( valTmp >= numTmp );
clsStrPlus str1 = numTmp;
clsStrPlus str2( numTmp );
clsValDbFld val1 = numTmp;
clsValDbFld val2( numTmp );
// check the assignment
numTmp = shTmp;
numTmp = ushTmp;
numTmp = iTmp;
numTmp = uiTmp;
numTmp = lTmp;
numTmp = ulTmp;
numTmp = dTmp;
numTmp = "1.01"; // LPCSTR
numTmp = str;
numTmp = strTmp;
numTmp = valTmp;
// check the conversion
numTmp = 1; // initalize numTmp with
a valid signed/unsigned value
shTmp = numTmp;
ushTmp = numTmp;
iTmp = numTmp;
uiTmp = numTmp;
lTmp = numTmp;
ulTmp = numTmp;
dTmp = numTmp;
str = numTmp;
strTmp = numTmp;
valTmp = numTmp;
// check unary '-' and '+'
ASSERT( (double) -numTmp == -dTmp );
ASSERT( (double) +numTmp == +dTmp );
int i;
long lMin = -1000;
long lMax = 100000;
double dRand1, dRand2;
double d1, d2, dResult;
clsNumDbFld num1, num2;
clsNumDbFld numResult( MAX_NumDbFldLen, 8 );
clsNumDbFld numResult4( NUM_DbFldLenDefault, 4 );
for (i = 0; i < 2; i++)
{
dRand1 = gFn_RandDouble( lMin, lMax
);
dRand2 = gFn_RandDouble( lMin, lMax
);
// check addition
num1 = dRand1;
num2 = dRand2;
numResult = num1 + num2;
d1 = dRand1;
d2 = dRand2;
dResult = d1 + d2;
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) numResult -
dResult ) < 0.00000001 );
// check subtraction
num1 = dRand1;
num2 = dRand2;
numResult = num1 - num2;
d1 = dRand1;
d2 = dRand2;
dResult = d1 - d2;
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) numResult -
dResult ) < 0.00000001 );
// Assign values rounded to 8
decimal places
dRand1 = num1;
dRand2 = num2;
// check multiplication
num1 = dRand1;
num2 = dRand2;
numResult = num1 * num2;
d1 = dRand1;
d2 = dRand2;
dResult = d1 * d2;
// upto 4 decimal places the result
should be same
ASSERT( fabs( (double) numResult -
dResult ) < 0.0001 );
// check division
num1 = dRand1;
num2 = dRand2;
numResult = num1 / num2;
d1 = dRand1;
d2 = dRand2;
dResult = d1 / d2;
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) numResult -
dResult ) < 0.00000001 );
// check quotient
num1.FindQuotientAndRemainder( num2,
&numResult );
// quotient should be same
ASSERT( (double) numResult == (long)
dResult );
// check remainder
dResult = fmod(d1, d2);
numResult = num1 % num2;
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) numResult -
dResult ) < 0.00000001 );
// check exponentiation
d1 = dRand1 - (long) dRand1; // get
the decimal part
// let the number have 1 digit to
the left of decimal point
d1 += (long) dRand1 % 10;
// if abs( d1 ) < 1.0,
increment d1
if (d1 > 0.0 && d1 <
1.0)
d1++;
else if (d1 < 0.0 && d1
> -1.0)
d1--;
// get the random power to which
d1 would be raised
d2 = (long) dRand2 % 90;
numResult = d1;
numResult = numResult.pow( (long) d2
);
dResult = d1;
dResult = pow( dResult, (long) d2 );
// compare exponentiation results
if (fabs( dResult ) > 1.0)
dResult =
(double) numResult / dResult;
else
dResult =
fabs( (double) numResult - dResult ) + 1.0;
// The results should be
approximately the same
ASSERT( dResult < 1.0001
&& dResult > 0.9999 );
// initialize numResult
numResult = num1;
dResult = numResult;
// initialize dResult to the same value
// check Pre & Post increment
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) (++numResult)
- (++dResult) ) < 0.00000001 );
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) (numResult++)
- (dResult++) ) < 0.00000001 );
// check Pre & Post decrement
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) (--numResult)
- (--dResult)) < 0.00000001 );
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) (numResult--)
- (dResult--)) < 0.00000001 );
// check absolute value function
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double) (numResult.abs())
- fabs (dResult) )
< 0.00000001 );
// check Get Integer & Decimal
functions
ASSERT( (double)
numResult.GetIntegerPart() == (long) dResult );
// upto 8 decimal places the result
should be same
ASSERT( fabs( (double)
numResult.GetDecimalPart() -
(dResult - (long) dResult)
) < 0.00000001 );
// check rounding logic (using
addition)
numResult = num1 + num2;
numResult4 = num1;
numResult4 = numResult4 + num2;
// upto 4 decimal places the result
should be same
ASSERT( fabs( (double) numResult4 -
(double) numResult ) < 0.0001 );
numResult4 = num1;
numResult4 += num2;
// upto 4 decimal places the result
should be same
ASSERT( fabs( (double) numResult4 -
(double) numResult ) < 0.0001 );
// check rounding logic (using
subtraction)
numResult = num1 - num2;
numResult4 = num1;
numResult4 = numResult4 - num2;
// upto 4 decimal places the result
should be same
ASSERT( fabs( (double) numResult4 -
(double) numResult ) < 0.0001 );
numResult4 = num1;
numResult4 -= num2;
// upto 4 decimal places the result
should be same
ASSERT( fabs( (double) numResult4 -
(double) numResult ) < 0.0001 );
}
// Test using large numbers
num1.SetDbFldLenAndScale( MAX_NumDbFldLen );
num2.SetDbFldLenAndScale( MAX_NumDbFldLen );
// Store max. possible 9s to the left of decimal point
num1 = 0;
for (iTmp = 1; iTmp <= MAX_NumDbFldLen -
NUM_DbFldScaleDefault; iTmp++)
{
num1 = (num1 * 10) + 9;
}
// Divide and multiply by the same number each time and
check the result
for (iTmp = 1; iTmp <= 10; iTmp++)
{
num2 = num1 / iTmp;
num2 *= iTmp;
/*
If it is not
a perfect division, after multiplication the
result should
be same upto 5 decimal places.
*/
ASSERT( (num1 - num2) < 0.000001
);
}
// Store a large number in the form 987654321098765...
num1 = 0;
num1 *= 100000;
num1 += 98765.0;
num1 *= 100000;
num1 += 43210.0;
num1 *= 100000;
num1 += 98765.0;
num1 *= 100000;
num1 += 43210.0;
num1 *= 100000;
num1 += 98765.0;
num1 *= 100000;
num1 += 43210.0;
num1 *= 100000;
num1 += 98765.0;
num1 *= 100000;
num1 += 43210.0;
num1 *= 100000;
num1 += 98765.0;
num1 *= 100000;
num1 += 43210.0;
// Divide the number by 100 repeatedly
for (iTmp = 1; iTmp <= 10; iTmp++)
{
num2 = num1 / 100;
num2 *= 100;
/*
During
division, the result gets rounded to the default scale
specified by
NUM_DbFldScaleDefault which is 8.
After
multiplication, the result should be same up to 8 decimal
places.
*/
ASSERT( (num1 - num2) < 0.00000001
);
num1 = num2;
}
}