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

217 lines
4.7 KiB
C

//---------------------------------------------------------------------------
// Package Title ratpak
// File num.c
// Author Timothy David Corrie Jr. (timc@microsoft.com)
// Copyright (C) 1995-99 Microsoft
// Date 01-16-95
//
//
// Description
//
// Contains routines for and, or, xor, not and other support
//
//---------------------------------------------------------------------------
#include <windows.h>
#include <ratpak.h>
void lshrat( PRAT *pa, PRAT b )
{
PRAT pwr=NULL;
long intb;
intrat(pa);
if ( !zernum( (*pa)->pp ) )
{
// If input is zero we're done.
if ( rat_gt( b, rat_max_exp ) )
{
// Don't attempt lsh of anything big
throw( CALC_E_DOMAIN );
}
intb = rattolong(b);
DUPRAT(pwr,rat_two);
ratpowlong(&pwr,intb);
mulrat(pa,pwr);
destroyrat(pwr);
}
}
void rshrat( PRAT *pa, PRAT b )
{
PRAT pwr=NULL;
long intb;
intrat(pa);
if ( !zernum( (*pa)->pp ) )
{
// If input is zero we're done.
if ( rat_lt( b, rat_min_exp ) )
{
// Don't attempt rsh of anything big and negative.
throw( CALC_E_DOMAIN );
}
intb = rattolong(b);
DUPRAT(pwr,rat_two);
ratpowlong(&pwr,intb);
divrat(pa,pwr);
destroyrat(pwr);
}
}
void boolrat( PRAT *pa, PRAT b, int func );
void boolnum( PNUMBER *pa, PNUMBER b, int func );
enum {
FUNC_AND,
FUNC_OR,
FUNC_XOR
} BOOL_FUNCS;
void andrat( PRAT *pa, PRAT b )
{
boolrat( pa, b, FUNC_AND );
}
void orrat( PRAT *pa, PRAT b )
{
boolrat( pa, b, FUNC_OR );
}
void xorrat( PRAT *pa, PRAT b )
{
boolrat( pa, b, FUNC_XOR );
}
//---------------------------------------------------------------------------
//
// FUNCTION: boolrat
//
// ARGUMENTS: pointer to a rational a second rational.
//
// RETURN: None, changes pointer.
//
// DESCRIPTION: Does the rational equivalent of *pa op= b;
//
//---------------------------------------------------------------------------
void boolrat( PRAT *pa, PRAT b, int func )
{
PRAT tmp=NULL;
intrat( pa );
DUPRAT(tmp,b);
intrat( &tmp );
boolnum( &((*pa)->pp), tmp->pp, func );
destroyrat(tmp);
}
//---------------------------------------------------------------------------
//
// FUNCTION: boolnum
//
// ARGUMENTS: pointer to a number a second number
//
// RETURN: None, changes first pointer.
//
// DESCRIPTION: Does the number equivalent of *pa &= b.
// nRadix doesn't matter for logicals.
// WARNING: Assumes numbers are unsigned.
//
//---------------------------------------------------------------------------
void boolnum( PNUMBER *pa, PNUMBER b, int func )
{
PNUMBER c=NULL;
PNUMBER a=NULL;
MANTTYPE *pcha;
MANTTYPE *pchb;
MANTTYPE *pchc;
long cdigits;
long mexp;
MANTTYPE da;
MANTTYPE db;
a=*pa;
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) -
min( a->exp, b->exp );
createnum( c, cdigits );
c->exp = min( a->exp, b->exp );
mexp = c->exp;
c->cdigit = cdigits;
pcha = MANT(a);
pchb = MANT(b);
pchc = MANT(c);
for ( ;cdigits > 0; cdigits--, mexp++ )
{
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp >
(c->cdigit - a->cdigit) ) ) ?
*pcha++ : 0 );
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp >
(c->cdigit - b->cdigit) ) ) ?
*pchb++ : 0 );
switch ( func )
{
case FUNC_AND:
*pchc++ = da & db;
break;
case FUNC_OR:
*pchc++ = da | db;
break;
case FUNC_XOR:
*pchc++ = da ^ db;
break;
}
}
c->sign = a->sign;
while ( c->cdigit > 1 && *(--pchc) == 0 )
{
c->cdigit--;
}
destroynum( *pa );
*pa=c;
}
//-----------------------------------------------------------------------------
//
// FUNCTION: modrat
//
// ARGUMENTS: pointer to a rational a second rational.
//
// RETURN: None, changes pointer.
//
// DESCRIPTION: Does the rational equivalent of frac(*pa);
//
//-----------------------------------------------------------------------------
void modrat( PRAT *pa, PRAT b )
{
PRAT tmp = NULL;
if ( zerrat( b ) )
{
throw CALC_E_INDEFINITE;
}
DUPRAT(tmp,b);
mulnumx( &((*pa)->pp), tmp->pq );
mulnumx( &(tmp->pp), (*pa)->pq );
remnum( &((*pa)->pp), tmp->pp, BASEX );
mulnumx( &((*pa)->pq), tmp->pq );
//Get *pa back in the integer over integer form.
RENORMALIZE(*pa);
destroyrat( tmp );
}