windows-nt/Source/XPSP1/NT/shell/osshell/accesory/calc/scioper.c
2020-09-26 16:20:57 +08:00

131 lines
4.3 KiB
C

/**************************************************************************/
/*** SCICALC Scientific Calculator for Windows 3.00.12 ***/
/*** By Kraig Brockschmidt, Microsoft Co-op, Contractor, 1988-1989 ***/
/*** (c)1989 Microsoft Corporation. All Rights Reserved. ***/
/*** ***/
/*** scioper.c ***/
/*** ***/
/*** Functions contained: ***/
/*** DoOperation--Does common operations. ***/
/*** ***/
/*** Functions called: ***/
/*** DisplayError ***/
/*** ***/
/*** Last modification Thu 31-Aug-1989 ***/
/**************************************************************************/
#include "scicalc.h"
extern BOOL bInv;
extern LONG nPrecision;
/****************************************************************************\
* HNUMOBJ NEAR DoOperation (short nOperation, HNUMOBJ fpx)
*
* Routines to perform standard operations &|^~<<>>+-/*% and pwr.
*
\****************************************************************************/
void DoOperation (INT nOperation, HNUMOBJ *phnoNum, HNUMOBJ hnoX)
{
// NOTE: volatile is used here because of a compiler bug! vc 5 AND 6. This has no effect on the funcationality.
volatile PRAT hno = NULL;
try
{
switch (nOperation)
{
/* Buncha ops. Hope *this* doesn't confuse anyone <smirk>. */
case IDC_AND:
andrat( phnoNum, hnoX );
return;
case IDC_OR:
orrat( phnoNum, hnoX );
return;
case IDC_XOR:
xorrat( phnoNum, hnoX );
return;
case RSHF:
NumObjAssign( &hno, *phnoNum );
NumObjAssign( phnoNum, hnoX );
rshrat( phnoNum, hno );
break;
case IDC_LSHF:
NumObjAssign( &hno, *phnoNum );
NumObjAssign( phnoNum, hnoX );
lshrat( phnoNum, hno );
break;
case IDC_ADD:
addrat( phnoNum, hnoX );
return;
case IDC_SUB:
// in order to do ( hnoX - phnoNum ) we actually do -(phnoNum - hnoX ) cause it's quicker
subrat( phnoNum, hnoX );
NumObjNegate( phnoNum );
return;
case IDC_MUL:
mulrat( phnoNum, hnoX );
return;
case IDC_DIV:
case IDC_MOD:
{
// REVIEW: These lengthly number assignments can be replaced with some quick pointer swaps.
// the swaps cannot change the value of hnoX unless we also modify the code that calls
// the DoOperation function.
NumObjAssign( &hno, *phnoNum );
NumObjAssign( phnoNum, hnoX );
if (nOperation==IDC_DIV) {
divrat(phnoNum, hno ); /* Do division. */
} else {
modrat( phnoNum, hno );
}
break;
}
case IDC_PWR: /* Calculates hnoX to the hnoNum(th) power or root. */
{
NumObjAssign( &hno, *phnoNum );
NumObjAssign( phnoNum, hnoX );
if (bInv) /* Switch for hnoNum(th) root. Null root illegal. */
{
SetBox (IDC_INV, bInv=FALSE);
rootrat( phnoNum, hno); /* Root. */
}
else
{
powrat( phnoNum, hno ); /* Power. */
}
break;
}
}
if ( hno != NULL )
NumObjDestroy( &hno );
}
catch ( DWORD dwErrCode )
{
// if ratpak throws an error, we may need to free the memory used by hno
if ( hno != NULL )
NumObjDestroy( &hno );
DisplayError( dwErrCode );
}
return;
}