217 lines
4.7 KiB
C
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 );
|
|
}
|
|
|