Stack-allocate all _numbers internally

This commit is contained in:
fwcd 2019-04-09 21:26:45 +02:00
commit ceb4b3c9b9
16 changed files with 505 additions and 585 deletions

View file

@ -17,22 +17,22 @@ namespace CalcEngine
m_mantissa{ mantissa } m_mantissa{ mantissa }
{} {}
Number::Number(PNUMBER p) noexcept : Number::Number(NUMBER p) noexcept :
m_sign{ p->sign }, m_sign{ p.sign },
m_exp{ p->exp }, m_exp{ p.exp },
m_mantissa{} m_mantissa{}
{ {
m_mantissa.reserve(p->cdigit); m_mantissa.reserve(p.cdigit);
copy(p->mant.begin(), p->mant.begin() + p->cdigit, back_inserter(m_mantissa)); copy(p.mant.begin(), p.mant.begin() + p.cdigit, back_inserter(m_mantissa));
} }
PNUMBER Number::ToPNUMBER() const NUMBER Number::ToNUMBER() const
{ {
PNUMBER ret = _createnum(static_cast<uint32_t>(this->Mantissa().size()) + 1); NUMBER ret = _createnum(static_cast<uint32_t>(this->Mantissa().size()) + 1);
ret->sign = this->Sign(); ret.sign = this->Sign();
ret->exp = this->Exp(); ret.exp = this->Exp();
ret->cdigit = static_cast<int32_t>(this->Mantissa().size()); ret.cdigit = static_cast<int32_t>(this->Mantissa().size());
ret->mant = this->Mantissa(); ret.mant = this->Mantissa();
return ret; return ret;
} }

View file

@ -69,8 +69,8 @@ namespace CalcEngine
{ {
PRAT ret = _createrat(); PRAT ret = _createrat();
ret->pp = this->P().ToPNUMBER(); ret->pp = this->P().ToNUMBER();
ret->pq = this->Q().ToPNUMBER(); ret->pq = this->Q().ToNUMBER();
return ret; return ret;
} }

View file

@ -13,8 +13,8 @@ namespace CalcEngine
Number() noexcept; Number() noexcept;
Number(int32_t sign, int32_t exp, std::vector<uint32_t> const& mantissa) noexcept; Number(int32_t sign, int32_t exp, std::vector<uint32_t> const& mantissa) noexcept;
explicit Number(PNUMBER p) noexcept; explicit Number(NUMBER p) noexcept;
PNUMBER ToPNUMBER() const; NUMBER ToNUMBER() const;
int32_t const& Sign() const; int32_t const& Sign() const;
int32_t const& Exp() const; int32_t const& Exp() const;

View file

@ -19,7 +19,7 @@
using namespace std; using namespace std;
void _mulnumx( PNUMBER *pa, PNUMBER b ); void _mulnumx( NUMBER *pa, NUMBER b );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
@ -36,13 +36,13 @@ void _mulnumx( PNUMBER *pa, PNUMBER b );
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void __inline mulnumx( PNUMBER *pa, PNUMBER b ) void __inline mulnumx( NUMBER *pa, NUMBER b )
{ {
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b.cdigit > 1 || b.mant[0] != 1 || b.exp != 0 )
{ {
// If b is not one we multiply // If b is not one we multiply
if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 ) if ( (*pa).cdigit > 1 || (*pa).mant[0] != 1 || (*pa).exp != 0 )
{ {
// pa and b are both non-one. // pa and b are both non-one.
_mulnumx( pa, b ); _mulnumx( pa, b );
@ -50,15 +50,15 @@ void __inline mulnumx( PNUMBER *pa, PNUMBER b )
else else
{ {
// if pa is one and b isn't just copy b. and adjust the sign. // if pa is one and b isn't just copy b. and adjust the sign.
int32_t sign = (*pa)->sign; int32_t sign = (*pa).sign;
DUPNUM(*pa,b); DUPNUM(*pa,b);
(*pa)->sign *= sign; (*pa).sign *= sign;
} }
} }
else else
{ {
// B is +/- 1, But we do have to set the sign. // B is +/- 1, But we do have to set the sign.
(*pa)->sign *= b->sign; (*pa).sign *= b.sign;
} }
} }
@ -78,11 +78,11 @@ void __inline mulnumx( PNUMBER *pa, PNUMBER b )
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void _mulnumx( PNUMBER *pa, PNUMBER b ) void _mulnumx( NUMBER *pa, NUMBER b )
{ {
PNUMBER c= nullptr; // c will contain the result. NUMBER c; // c will contain the result.
PNUMBER a= nullptr; // a is the dereferenced number pointer from *pa NUMBER a; // a is the dereferenced number pointer from *pa
vector<MANTTYPE>::iterator ptra; // ptra is an iterator pointing to the mantissa of a. vector<MANTTYPE>::iterator ptra; // ptra is an iterator pointing to the mantissa of a.
vector<MANTTYPE>::iterator ptrb; // ptrb is an iterator pointing to the mantissa of b. vector<MANTTYPE>::iterator ptrb; // ptrb is an iterator pointing to the mantissa of b.
vector<MANTTYPE>::iterator ptrc; // ptrc is an iterator pointing to the mantissa of c. vector<MANTTYPE>::iterator ptrc; // ptrc is an iterator pointing to the mantissa of c.
@ -99,24 +99,24 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
a=*pa; a=*pa;
ibdigit = a->cdigit + b->cdigit - 1; ibdigit = a.cdigit + b.cdigit - 1;
createnum( c, ibdigit + 1 ); createnum( c, ibdigit + 1 );
c->cdigit = ibdigit; c.cdigit = ibdigit;
c->sign = a->sign * b->sign; c.sign = a.sign * b.sign;
c->exp = a->exp + b->exp; c.exp = a.exp + b.exp;
ptra = a->mant.begin(); ptra = a.mant.begin();
ptrcoffset = c->mant.begin(); ptrcoffset = c.mant.begin();
for ( iadigit = a->cdigit; iadigit > 0; iadigit-- ) for ( iadigit = a.cdigit; iadigit > 0; iadigit-- )
{ {
da = *ptra++; da = *ptra++;
ptrb = b->mant.begin(); ptrb = b.mant.begin();
// Shift ptrc, and ptrcoffset, one for each digit // Shift ptrc, and ptrcoffset, one for each digit
ptrc = ptrcoffset++; ptrc = ptrcoffset++;
for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) for ( ibdigit = b.cdigit; ibdigit > 0; ibdigit-- )
{ {
cy = 0; cy = 0;
mcy = (uint64_t)da * (*ptrb); mcy = (uint64_t)da * (*ptrb);
@ -125,7 +125,7 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
icdigit = 0; icdigit = 0;
if ( ibdigit == 1 && iadigit == 1 ) if ( ibdigit == 1 && iadigit == 1 )
{ {
c->cdigit++; c.cdigit++;
} }
} }
@ -152,12 +152,11 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
// prevent different kinds of zeros, by stripping leading duplicate zeros. // prevent different kinds of zeros, by stripping leading duplicate zeros.
// digits are in order of increasing significance. // digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c.cdigit > 1 && c.mant[c.cdigit-1] == 0 )
{ {
c->cdigit--; c.cdigit--;
} }
destroynum( *pa );
*pa=c; *pa=c;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -176,10 +175,10 @@ void _mulnumx( PNUMBER *pa, PNUMBER b )
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void numpowi32x( _Inout_ PNUMBER *proot, _In_ int32_t power ) void numpowi32x( _Inout_ NUMBER *proot, _In_ int32_t power )
{ {
PNUMBER lret = i32tonum( 1, BASEX ); NUMBER lret = i32tonum( 1, BASEX );
// Once the power remaining is zero we are done. // Once the power remaining is zero we are done.
while ( power > 0 ) while ( power > 0 )
@ -198,12 +197,11 @@ void numpowi32x( _Inout_ PNUMBER *proot, _In_ int32_t power )
// move the next bit of the power into place. // move the next bit of the power into place.
power >>= 1; power >>= 1;
} }
destroynum( *proot );
*proot=lret; *proot=lret;
} }
void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision); void _divnumx( NUMBER *pa, NUMBER b, int32_t precision);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
@ -220,13 +218,13 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision);
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void __inline divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) void __inline divnumx( NUMBER *pa, NUMBER b, int32_t precision)
{ {
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b.cdigit > 1 || b.mant[0] != 1 || b.exp != 0 )
{ {
// b is not one. // b is not one.
if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 ) if ( (*pa).cdigit > 1 || (*pa).mant[0] != 1 || (*pa).exp != 0 )
{ {
// pa and b are both not one. // pa and b are both not one.
_divnumx( pa, b, precision); _divnumx( pa, b, precision);
@ -234,15 +232,15 @@ void __inline divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
else else
{ {
// if pa is one and b is not one, just copy b, and adjust the sign. // if pa is one and b is not one, just copy b, and adjust the sign.
int32_t sign = (*pa)->sign; int32_t sign = (*pa).sign;
DUPNUM(*pa,b); DUPNUM(*pa,b);
(*pa)->sign *= sign; (*pa).sign *= sign;
} }
} }
else else
{ {
// b is one so don't divide, but set the sign. // b is one so don't divide, but set the sign.
(*pa)->sign *= b->sign; (*pa).sign *= b.sign;
} }
} }
@ -259,15 +257,15 @@ void __inline divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision) void _divnumx( NUMBER *pa, NUMBER b, int32_t precision)
{ {
PNUMBER a= nullptr; // a is the dereferenced number pointer from *pa NUMBER a; // a is the dereferenced number pointer from *pa
PNUMBER c= nullptr; // c will contain the result. NUMBER c; // c will contain the result.
PNUMBER lasttmp = nullptr; // lasttmp allows a backup when the algorithm NUMBER lasttmp; // lasttmp allows a backup when the algorithm
// guesses one bit too far. // guesses one bit too far.
PNUMBER tmp = nullptr; // current guess being worked on for divide. NUMBER tmp; // current guess being worked on for divide.
PNUMBER rem = nullptr; // remainder after applying guess. NUMBER rem; // remainder after applying guess.
int32_t cdigits; // count of digits for answer. int32_t cdigits; // count of digits for answer.
vector<MANTTYPE>::iterator ptrc; // ptrc is an iterator pointing to the mantissa of c. vector<MANTTYPE>::iterator ptrc; // ptrc is an iterator pointing to the mantissa of c.
@ -275,31 +273,31 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
// to shoot for in the divide. // to shoot for in the divide.
a=*pa; a=*pa;
if ( thismax < a->cdigit ) if ( thismax < a.cdigit )
{ {
// a has more digits than precision specified, bump up digits to shoot // a has more digits than precision specified, bump up digits to shoot
// for. // for.
thismax = a->cdigit; thismax = a.cdigit;
} }
if ( thismax < b->cdigit ) if ( thismax < b.cdigit )
{ {
// b has more digits than precision specified, bump up digits to shoot // b has more digits than precision specified, bump up digits to shoot
// for. // for.
thismax = b->cdigit; thismax = b.cdigit;
} }
// Create c (the divide answer) and set up exponent and sign. // Create c (the divide answer) and set up exponent and sign.
createnum( c, thismax + 1 ); createnum( c, thismax + 1 );
c->exp = (a->cdigit+a->exp) - (b->cdigit+b->exp) + 1; c.exp = (a.cdigit+a.exp) - (b.cdigit+b.exp) + 1;
c->sign = a->sign * b->sign; c.sign = a.sign * b.sign;
ptrc = c->mant.begin() + thismax; ptrc = c.mant.begin() + thismax;
cdigits = 0; cdigits = 0;
DUPNUM( rem, a ); DUPNUM( rem, a );
rem->sign = b->sign; rem.sign = b.sign;
rem->exp = b->cdigit + b->exp - rem->cdigit; rem.exp = b.cdigit + b.exp - rem.cdigit;
while ( cdigits++ < thismax && !zernum(rem) ) while ( cdigits++ < thismax && !zernum(rem) )
{ {
@ -309,11 +307,9 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
{ {
digit = 1; digit = 1;
DUPNUM( tmp, b ); DUPNUM( tmp, b );
destroynum( lasttmp );
lasttmp=i32tonum( 0, BASEX ); lasttmp=i32tonum( 0, BASEX );
while ( lessnum( tmp, rem ) ) while ( lessnum( tmp, rem ) )
{ {
destroynum( lasttmp );
DUPNUM(lasttmp,tmp); DUPNUM(lasttmp,tmp);
addnum( &tmp, tmp, BASEX ); addnum( &tmp, tmp, BASEX );
digit *= 2; digit *= 2;
@ -321,48 +317,43 @@ void _divnumx( PNUMBER *pa, PNUMBER b, int32_t precision)
if ( lessnum( rem, tmp ) ) if ( lessnum( rem, tmp ) )
{ {
// too far, back up... // too far, back up...
destroynum( tmp );
digit /= 2; digit /= 2;
tmp=lasttmp; tmp=lasttmp;
lasttmp= nullptr; lasttmp= nullptr;
} }
tmp->sign *= -1; tmp.sign *= -1;
addnum( &rem, tmp, BASEX ); addnum( &rem, tmp, BASEX );
destroynum( tmp );
destroynum( lasttmp );
*ptrc |= digit; *ptrc |= digit;
} }
rem->exp++; rem.exp++;
ptrc--; ptrc--;
} }
cdigits--; cdigits--;
if ( c->mant.begin() != ++ptrc ) if ( c.mant.begin() != ++ptrc )
{ {
copy(ptrc, ptrc + cdigits, c->mant.begin()); copy(ptrc, ptrc + cdigits, c.mant.begin());
} }
if ( !cdigits ) if ( !cdigits )
{ {
// A zero, make sure no weird exponents creep in // A zero, make sure no weird exponents creep in
c->exp = 0; c.exp = 0;
c->cdigit = 1; c.cdigit = 1;
} }
else else
{ {
c->cdigit = cdigits; c.cdigit = cdigits;
c->exp -= cdigits; c.exp -= cdigits;
// prevent different kinds of zeros, by stripping leading duplicate // prevent different kinds of zeros, by stripping leading duplicate
// zeros. digits are in order of increasing significance. // zeros. digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c.cdigit > 1 && c.mant[c.cdigit-1] == 0 )
{ {
c->cdigit--; c.cdigit--;
} }
} }
destroynum( rem );
destroynum( *pa );
*pa=c; *pa=c;
} }

View file

@ -109,7 +109,7 @@ namespace {
} }
// Used to strip trailing zeros, and prevent combinatorial explosions // Used to strip trailing zeros, and prevent combinatorial explosions
bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting); bool stripzeroesnum(_Inout_ NUMBER pnum, int32_t starting);
void SetDecimalSeparator(wchar_t decimalSeparator) void SetDecimalSeparator(wchar_t decimalSeparator)
{ {
@ -136,33 +136,12 @@ void* zmalloc(size_t a)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src) void _dupnum(_In_ NUMBER dest, _In_ const NUMBER * const src)
{ {
dest->sign = src->sign; dest.sign = src->sign;
dest->exp = src->exp; dest.exp = src->exp;
dest->cdigit = src->cdigit; dest.cdigit = src->cdigit;
dest->mant = src->mant; dest.mant = src->mant;
}
//-----------------------------------------------------------------------------
//
// FUNCTION: _destroynum
//
// ARGUMENTS: pointer to a number
//
// RETURN: None
//
// DESCRIPTION: Deletes the number and associated allocation
//
//-----------------------------------------------------------------------------
void _destroynum( _In_ PNUMBER pnum )
{
if ( pnum != nullptr)
{
delete pnum;
}
} }
@ -184,8 +163,6 @@ void _destroyrat( _In_ PRAT prat )
{ {
if ( prat != nullptr) if ( prat != nullptr)
{ {
destroynum( prat->pp );
destroynum( prat->pq );
delete prat; delete prat;
} }
} }
@ -197,27 +174,19 @@ void _destroyrat( _In_ PRAT prat )
// //
// ARGUMENTS: size of number in 'digits' // ARGUMENTS: size of number in 'digits'
// //
// RETURN: pointer to a number // RETURN: a number
// //
// DESCRIPTION: allocates and zeros out number type. // DESCRIPTION: initializes and zeros out number type.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER _createnum( _In_ uint32_t size ) NUMBER _createnum( _In_ uint32_t size )
{ {
PNUMBER pnumret= nullptr; NUMBER num = NUMBER();
try
{
pnumret = new NUMBER();
}
catch (const bad_alloc&)
{
throw( CALC_E_OUTOFMEMORY );
}
// Fill mantissa vector with zeros // Fill mantissa vector with zeros
pnumret->mant.insert(pnumret->mant.end(), size, 0); num.mant.insert(num.mant.end(), size, 0);
return( pnumret ); return( num );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -247,8 +216,6 @@ PRAT _createrat( void )
{ {
throw( CALC_E_OUTOFMEMORY ); throw( CALC_E_OUTOFMEMORY );
} }
prat->pp = nullptr;
prat->pq = nullptr;
return( prat ); return( prat );
} }
@ -269,19 +236,19 @@ PRAT _createrat( void )
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PRAT numtorat( _In_ PNUMBER pin, uint32_t radix) PRAT numtorat( _In_ NUMBER pin, uint32_t radix)
{ {
PNUMBER pnRadixn= nullptr; NUMBER pnRadixn;
DUPNUM( pnRadixn, pin ); DUPNUM( pnRadixn, pin );
PNUMBER qnRadixn=i32tonum( 1, radix); NUMBER qnRadixn=i32tonum( 1, radix);
// Ensure p and q start out as integers. // Ensure p and q start out as integers.
if ( pnRadixn->exp < 0 ) if ( pnRadixn.exp < 0 )
{ {
qnRadixn->exp -= pnRadixn->exp; qnRadixn.exp -= pnRadixn.exp;
pnRadixn->exp = 0; pnRadixn.exp = 0;
} }
PRAT pout= nullptr; PRAT pout= nullptr;
@ -292,8 +259,6 @@ PRAT numtorat( _In_ PNUMBER pin, uint32_t radix)
pout->pq = numtonRadixx(qnRadixn, radix); pout->pq = numtonRadixx(qnRadixn, radix);
destroynum( pnRadixn );
destroynum( qnRadixn );
return( pout ); return( pout );
} }
@ -314,30 +279,30 @@ PRAT numtorat( _In_ PNUMBER pin, uint32_t radix)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision) NUMBER nRadixxtonum( _In_ NUMBER a, uint32_t radix, int32_t precision)
{ {
uint32_t bitmask; uint32_t bitmask;
uint32_t cdigits; uint32_t cdigits;
MANTTYPE *ptr; MANTTYPE *ptr;
PNUMBER sum = i32tonum( 0, radix ); NUMBER sum = i32tonum( 0, radix );
PNUMBER powofnRadix = i32tonum( BASEX, radix ); NUMBER powofnRadix = i32tonum( BASEX, radix );
// A large penalty is paid for conversion of digits no one will see anyway. // A large penalty is paid for conversion of digits no one will see anyway.
// limit the digits to the minimum of the existing precision or the // limit the digits to the minimum of the existing precision or the
// requested precision. // requested precision.
cdigits = precision + 1; cdigits = precision + 1;
if ( cdigits > (uint32_t)a->cdigit ) if ( cdigits > (uint32_t)a.cdigit )
{ {
cdigits = (uint32_t)a->cdigit; cdigits = (uint32_t)a.cdigit;
} }
// scale by the internal base to the internal exponent offset of the LSD // scale by the internal base to the internal exponent offset of the LSD
numpowi32( &powofnRadix, a->exp + (a->cdigit - cdigits), radix, precision); numpowi32( &powofnRadix, a.exp + (a.cdigit - cdigits), radix, precision);
// Loop over all the relative digits from MSD to LSD // Loop over all the relative digits from MSD to LSD
for ( ptr = &(a->mant[a->cdigit-1]); cdigits > 0; for ( ptr = &(a.mant[a.cdigit-1]); cdigits > 0;
ptr--, cdigits-- ) ptr--, cdigits-- )
{ {
// Loop over all the bits from MSB to LSB // Loop over all the bits from MSB to LSB
@ -346,7 +311,7 @@ PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision)
addnum( &sum, sum, radix ); addnum( &sum, sum, radix );
if ( *ptr & bitmask ) if ( *ptr & bitmask )
{ {
sum->mant[0] |= 1; sum.mant[0] |= 1;
} }
} }
} }
@ -354,8 +319,7 @@ PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision)
// Scale answer by power of internal exponent. // Scale answer by power of internal exponent.
mulnum( &sum, powofnRadix, radix ); mulnum( &sum, powofnRadix, radix );
destroynum( powofnRadix ); sum.sign = a.sign;
sum->sign = a->sign;
return( sum ); return( sum );
} }
@ -373,18 +337,18 @@ PNUMBER nRadixxtonum( _In_ PNUMBER a, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix) NUMBER numtonRadixx(_In_ NUMBER a, uint32_t radix)
{ {
PNUMBER pnumret = i32tonum(0, BASEX); // pnumret is the number in internal form. NUMBER pnumret = i32tonum(0, BASEX); // pnumret is the number in internal form.
PNUMBER num_radix = i32tonum(radix, BASEX); NUMBER num_radix = i32tonum(radix, BASEX);
// Digits are in reverse order, back over them LSD first. // Digits are in reverse order, back over them LSD first.
vector<MANTTYPE>::iterator ptrdigit = a->mant.begin() + a->cdigit; // iterator pointing to digit being worked on. vector<MANTTYPE>::iterator ptrdigit = a.mant.begin() + a.cdigit; // iterator pointing to digit being worked on.
PNUMBER thisdigit = nullptr; // thisdigit holds the current digit of a NUMBER thisdigit; // thisdigit holds the current digit of a
// being summed into result. // being summed into result.
int32_t idigit; // idigit is the iterate of digits in a. int32_t idigit; // idigit is the iterate of digits in a.
for ( idigit = 0; idigit < a->cdigit; idigit++ ) for ( idigit = 0; idigit < a.cdigit; idigit++ )
{ {
mulnumx( &pnumret, num_radix); mulnumx( &pnumret, num_radix);
// WARNING: // WARNING:
@ -392,19 +356,17 @@ PNUMBER numtonRadixx(_In_ PNUMBER a, uint32_t radix)
// and not do the overhead of recreating the number type each time. // and not do the overhead of recreating the number type each time.
thisdigit = i32tonum( *(--ptrdigit), BASEX ); thisdigit = i32tonum( *(--ptrdigit), BASEX );
addnum( &pnumret, thisdigit, BASEX ); addnum( &pnumret, thisdigit, BASEX );
destroynum( thisdigit );
} }
// Calculate the exponent of the external base for scaling. // Calculate the exponent of the external base for scaling.
numpowi32x( &num_radix, a->exp ); numpowi32x( &num_radix, a.exp );
// ... and scale the result. // ... and scale the result.
mulnumx( &pnumret, num_radix); mulnumx( &pnumret, num_radix);
destroynum(num_radix);
// And propagate the sign. // And propagate the sign.
pnumret->sign = a->sign; pnumret.sign = a.sign;
return( pnumret ); return( pnumret );
} }
@ -450,7 +412,7 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
else else
{ {
// Mantissa specified, convert to number form. // Mantissa specified, convert to number form.
PNUMBER pnummant = StringToNumber(mantissa, radix, precision); NUMBER pnummant = StringToNumber(mantissa, radix, precision);
if (pnummant == nullptr) if (pnummant == nullptr)
{ {
return nullptr; return nullptr;
@ -458,7 +420,6 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
resultRat = numtorat(pnummant, radix); resultRat = numtorat(pnummant, radix);
// convert to rational form, and cleanup. // convert to rational form, and cleanup.
destroynum(pnummant);
} }
// Deal with exponent // Deal with exponent
@ -468,7 +429,7 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
// Exponent specified, convert to number form. // Exponent specified, convert to number form.
// Don't use native stuff, as it is restricted in the bases it can // Don't use native stuff, as it is restricted in the bases it can
// handle. // handle.
PNUMBER numExp = StringToNumber(exponent, radix, precision); NUMBER numExp = StringToNumber(exponent, radix, precision);
if (numExp == nullptr) if (numExp == nullptr)
{ {
return nullptr; return nullptr;
@ -476,18 +437,16 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
// Convert exponent number form to native integral form, and cleanup. // Convert exponent number form to native integral form, and cleanup.
expt = numtoi32(numExp, radix); expt = numtoi32(numExp, radix);
destroynum(numExp);
} }
// Convert native integral exponent form to rational multiplier form. // Convert native integral exponent form to rational multiplier form.
PNUMBER pnumexp = i32tonum(radix, BASEX); NUMBER pnumexp = i32tonum(radix, BASEX);
numpowi32x(&pnumexp, abs(expt)); numpowi32x(&pnumexp, abs(expt));
PRAT pratexp = nullptr; PRAT pratexp = nullptr;
createrat(pratexp); createrat(pratexp);
DUPNUM(pratexp->pp, pnumexp); DUPNUM(pratexp->pp, pnumexp);
pratexp->pq = i32tonum(1, BASEX); pratexp->pq = i32tonum(1, BASEX);
destroynum(pnumexp);
if (exponentIsNegative) if (exponentIsNegative)
{ {
@ -506,7 +465,7 @@ PRAT StringToRat(bool mantissaIsNegative, wstring_view mantissa, bool exponentIs
if (mantissaIsNegative) if (mantissaIsNegative)
{ {
// A negative number was used, adjust the sign. // A negative number was used, adjust the sign.
resultRat->pp->sign *= -1; resultRat->pp.sign *= -1;
} }
return resultRat; return resultRat;
@ -643,16 +602,16 @@ wchar_t NormalizeCharDigit(wchar_t c, uint32_t radix)
return c; return c;
} }
PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision) NUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precision)
{ {
int32_t expSign = 1L; // expSign is exponent sign ( +/- 1 ) int32_t expSign = 1L; // expSign is exponent sign ( +/- 1 )
int32_t expValue = 0L; // expValue is exponent mantissa, should be unsigned int32_t expValue = 0L; // expValue is exponent mantissa, should be unsigned
PNUMBER pnumret = nullptr; NUMBER pnumret;
createnum(pnumret, static_cast<uint32_t>(numberString.length())); createnum(pnumret, static_cast<uint32_t>(numberString.length()));
pnumret->sign = 1L; pnumret.sign = 1L;
pnumret->cdigit = 0; pnumret.cdigit = 0;
pnumret->exp = 0; pnumret.exp = 0;
int32_t imant = static_cast<int32_t>(numberString.length() - 1); int32_t imant = static_cast<int32_t>(numberString.length() - 1);
uint8_t state = START; // state is the state of the input state machine. uint8_t state = START; // state is the state of the input state machine.
@ -693,7 +652,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
switch (state) switch (state)
{ {
case MANTS: case MANTS:
pnumret->sign = (curChar == L'-') ? -1 : 1; pnumret.sign = (curChar == L'-') ? -1 : 1;
break; break;
case EXPSZ: case EXPSZ:
case EXPS: case EXPS:
@ -717,7 +676,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
} }
break; break;
case LD: case LD:
pnumret->exp++; pnumret.exp++;
[[fallthrough]]; [[fallthrough]];
case DD: case DD:
{ {
@ -726,9 +685,9 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
size_t pos = DIGITS.find(curChar); size_t pos = DIGITS.find(curChar);
if (pos != wstring_view::npos && pos < static_cast<size_t>(radix)) if (pos != wstring_view::npos && pos < static_cast<size_t>(radix))
{ {
pnumret->mant[imant--] = static_cast<MANTTYPE>(pos); pnumret.mant[imant--] = static_cast<MANTTYPE>(pos);
pnumret->exp--; pnumret.exp--;
pnumret->cdigit++; pnumret.cdigit++;
} }
else else
{ {
@ -737,7 +696,7 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
} }
break; break;
case DZ: case DZ:
pnumret->exp--; pnumret.exp--;
break; break;
case LZ: case LZ:
case LZDP: case LZDP:
@ -748,25 +707,24 @@ PNUMBER StringToNumber(wstring_view numberString, uint32_t radix, int32_t precis
if (state == DZ || state == EXPDZ) if (state == DZ || state == EXPDZ)
{ {
pnumret->cdigit = 1; pnumret.cdigit = 1;
pnumret->exp = 0; pnumret.exp = 0;
pnumret->sign = 1; pnumret.sign = 1;
} }
else else
{ {
while (pnumret->cdigit < static_cast<int32_t>(numberString.length())) while (pnumret.cdigit < static_cast<int32_t>(numberString.length()))
{ {
pnumret->cdigit++; pnumret.cdigit++;
pnumret->exp--; pnumret.exp--;
} }
pnumret->exp += expSign * expValue; pnumret.exp += expSign * expValue;
} }
// If we don't have a number, clear our result. // If we don't have a number, clear our result.
if (pnumret->cdigit == 0) if (pnumret.cdigit == 0)
{ {
destroynum(pnumret);
pnumret = nullptr; pnumret = nullptr;
} }
@ -835,31 +793,31 @@ PRAT Ui32torat( _In_ uint32_t inui32 )
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER i32tonum( int32_t ini32, uint32_t radix) NUMBER i32tonum( int32_t ini32, uint32_t radix)
{ {
vector<MANTTYPE>::iterator pmant; vector<MANTTYPE>::iterator pmant;
PNUMBER pnumret= nullptr; NUMBER pnumret;
createnum( pnumret, MAX_LONG_SIZE ); createnum( pnumret, MAX_LONG_SIZE );
pmant = pnumret->mant.begin(); pmant = pnumret.mant.begin();
pnumret->cdigit = 0; pnumret.cdigit = 0;
pnumret->exp = 0; pnumret.exp = 0;
if ( ini32 < 0 ) if ( ini32 < 0 )
{ {
pnumret->sign = -1; pnumret.sign = -1;
ini32 *= -1; ini32 *= -1;
} }
else else
{ {
pnumret->sign = 1; pnumret.sign = 1;
} }
do { do {
*pmant = (MANTTYPE)(ini32 % radix); *pmant = (MANTTYPE)(ini32 % radix);
++pmant; ++pmant;
ini32 /= radix; ini32 /= radix;
pnumret->cdigit++; pnumret.cdigit++;
} while ( ini32 ); } while ( ini32 );
return( pnumret ); return( pnumret );
@ -880,21 +838,21 @@ PNUMBER i32tonum( int32_t ini32, uint32_t radix)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix) NUMBER Ui32tonum(uint32_t ini32, uint32_t radix)
{ {
vector<MANTTYPE>::iterator pmant; vector<MANTTYPE>::iterator pmant;
PNUMBER pnumret= nullptr; NUMBER pnumret;
createnum( pnumret, MAX_LONG_SIZE ); createnum( pnumret, MAX_LONG_SIZE );
pmant = pnumret->mant.begin(); pmant = pnumret.mant.begin();
pnumret->cdigit = 0; pnumret.cdigit = 0;
pnumret->exp = 0; pnumret.exp = 0;
pnumret->sign = 1; pnumret.sign = 1;
do { do {
*pmant++ = (MANTTYPE)(ini32 % radix); *pmant++ = (MANTTYPE)(ini32 % radix);
ini32 /= radix; ini32 /= radix;
pnumret->cdigit++; pnumret.cdigit++;
} while ( ini32 ); } while ( ini32 );
return( pnumret ); return( pnumret );
@ -1023,24 +981,24 @@ uint64_t rattoUi64( _In_ PRAT prat, uint32_t radix, int32_t precision)
// base claimed. // base claimed.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int32_t numtoi32( _In_ PNUMBER pnum, uint32_t radix ) int32_t numtoi32( _In_ NUMBER pnum, uint32_t radix )
{ {
int32_t lret = 0; int32_t lret = 0;
int32_t imant = pnum->cdigit - 1; int32_t imant = pnum.cdigit - 1;
int32_t expt = pnum->exp; int32_t expt = pnum.exp;
for (int32_t length = pnum->cdigit; length > 0 && length + expt > 0; length--) for (int32_t length = pnum.cdigit; length > 0 && length + expt > 0; length--)
{ {
lret *= radix; lret *= radix;
lret += pnum->mant[imant--]; lret += pnum.mant[imant--];
} }
while (expt-- > 0) while (expt-- > 0)
{ {
lret *= radix; lret *= radix;
} }
lret *= pnum->sign; lret *= pnum.sign;
return lret; return lret;
} }
@ -1057,15 +1015,15 @@ int32_t numtoi32( _In_ PNUMBER pnum, uint32_t radix )
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting) bool stripzeroesnum(_Inout_ NUMBER pnum, int32_t starting)
{ {
vector<MANTTYPE>::iterator pmant; vector<MANTTYPE>::iterator pmant;
int32_t cdigits; int32_t cdigits;
bool fstrip = false; bool fstrip = false;
// point pmant to the LeastCalculatedDigit // point pmant to the LeastCalculatedDigit
pmant=pnum->mant.begin(); pmant=pnum.mant.begin();
cdigits=pnum->cdigit; cdigits=pnum.cdigit;
// point pmant to the LSD // point pmant to the LSD
if ( cdigits > starting ) if ( cdigits > starting )
{ {
@ -1087,10 +1045,10 @@ bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting)
if ( fstrip ) if ( fstrip )
{ {
// Remove them. // Remove them.
copy(pmant, pmant + cdigits, pnum->mant.begin()); copy(pmant, pmant + cdigits, pnum.mant.begin());
// And adjust exponent and digit count accordingly. // And adjust exponent and digit count accordingly.
pnum->exp += ( pnum->cdigit - cdigits ); pnum.exp += ( pnum.cdigit - cdigits );
pnum->cdigit = cdigits; pnum.cdigit = cdigits;
} }
return( fstrip ); return( fstrip );
} }
@ -1110,11 +1068,11 @@ bool stripzeroesnum(_Inout_ PNUMBER pnum, int32_t starting)
// representation. // representation.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_t precision) wstring NumberToString(_Inout_ NUMBER& pnum, int format, uint32_t radix, int32_t precision)
{ {
stripzeroesnum(pnum, precision + 2); stripzeroesnum(pnum, precision + 2);
int32_t length = pnum->cdigit; int32_t length = pnum.cdigit;
int32_t exponent = pnum->exp + length; // Actual number of digits to the left of decimal int32_t exponent = pnum.exp + length; // Actual number of digits to the left of decimal
int32_t oldFormat = format; int32_t oldFormat = format;
if (exponent > precision && format == FMT_FLOAT) if (exponent > precision && format == FMT_FLOAT)
@ -1132,8 +1090,8 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
// If there is a chance a round has to occur, round. // If there is a chance a round has to occur, round.
// - if number is zero no rounding // - if number is zero no rounding
// - if number of digits is less than the maximum output no rounding // - if number of digits is less than the maximum output no rounding
PNUMBER round = nullptr; NUMBER round;
if (!zernum(pnum) && (pnum->cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL))) if (!zernum(pnum) && (pnum.cdigit >= precision || (length - exponent > precision && exponent >= -MAX_ZEROS_AFTER_DECIMAL)))
{ {
// Otherwise round. // Otherwise round.
round = i32tonum(radix, radix); round = i32tonum(radix, radix);
@ -1142,15 +1100,15 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
// Make round number exponent one below the LSD for the number. // Make round number exponent one below the LSD for the number.
if (exponent > 0 || format == FMT_FLOAT) if (exponent > 0 || format == FMT_FLOAT)
{ {
round->exp = pnum->exp + pnum->cdigit - round->cdigit - precision; round.exp = pnum.exp + pnum.cdigit - round.cdigit - precision;
} }
else else
{ {
round->exp = pnum->exp + pnum->cdigit - round->cdigit - precision - exponent; round.exp = pnum.exp + pnum.cdigit - round.cdigit - precision - exponent;
length = precision + exponent; length = precision + exponent;
} }
round->sign = pnum->sign; round.sign = pnum.sign;
} }
if (format == FMT_FLOAT) if (format == FMT_FLOAT)
@ -1160,7 +1118,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
{ {
if (exponent >= -MAX_ZEROS_AFTER_DECIMAL) if (exponent >= -MAX_ZEROS_AFTER_DECIMAL)
{ {
round->exp -= exponent; round.exp -= exponent;
length = precision + exponent; length = precision + exponent;
} }
else else
@ -1174,15 +1132,14 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
{ {
// Minimum loss of precision occurs with listing leading zeros // Minimum loss of precision occurs with listing leading zeros
// if we need to make room for zeros sacrifice some digits. // if we need to make room for zeros sacrifice some digits.
round->exp -= exponent; round.exp -= exponent;
} }
} }
if (round != nullptr) if (round != nullptr)
{ {
addnum(&pnum, round, radix); addnum(&pnum, round, radix);
int32_t offset = (pnum->cdigit + pnum->exp) - (round->cdigit + round->exp); int32_t offset = (pnum.cdigit + pnum.exp) - (round.cdigit + round.exp);
destroynum(round);
if (stripzeroesnum(pnum, offset)) if (stripzeroesnum(pnum, offset))
{ {
// WARNING: nesting/recursion, too much has been changed, need to // WARNING: nesting/recursion, too much has been changed, need to
@ -1198,7 +1155,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
// Set up all the post rounding stuff. // Set up all the post rounding stuff.
bool useSciForm = false; bool useSciForm = false;
int32_t eout = exponent - 1; // Displayed exponent. int32_t eout = exponent - 1; // Displayed exponent.
int32_t imant = pnum->cdigit - 1; int32_t imant = pnum.cdigit - 1;
// Case where too many digits are to the left of the decimal or // Case where too many digits are to the left of the decimal or
// FMT_SCIENTIFIC or FMT_ENGINEERING was specified. // FMT_SCIENTIFIC or FMT_ENGINEERING was specified.
if ((format == FMT_SCIENTIFIC) || (format == FMT_ENGINEERING)) if ((format == FMT_SCIENTIFIC) || (format == FMT_ENGINEERING))
@ -1234,7 +1191,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
wstringstream resultStream{}; wstringstream resultStream{};
// Make sure negative zeros aren't allowed. // Make sure negative zeros aren't allowed.
if ((pnum->sign == -1) && (length > 0)) if ((pnum.sign == -1) && (length > 0))
{ {
resultStream << L'-'; resultStream << L'-';
} }
@ -1255,7 +1212,7 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
while (length > 0) while (length > 0)
{ {
exponent--; exponent--;
resultStream << DIGITS[pnum->mant[imant--]]; resultStream << DIGITS[pnum.mant[imant--]];
length--; length--;
// Be more regular in using a decimal point. // Be more regular in using a decimal point.
@ -1327,46 +1284,43 @@ wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision) wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision)
{ {
PNUMBER p = RatToNumber(prat, radix, precision); NUMBER p = RatToNumber(prat, radix, precision);
wstring result = NumberToString(p, format, radix, precision); wstring result = NumberToString(p, format, radix, precision);
destroynum(p);
return result; return result;
} }
PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision) NUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision)
{ {
PRAT temprat = nullptr; PRAT temprat = nullptr;
DUPRAT(temprat, prat); DUPRAT(temprat, prat);
// Convert p and q of rational form from internal base to requested base. // Convert p and q of rational form from internal base to requested base.
// Scale by largest power of BASEX possible. // Scale by largest power of BASEX possible.
int32_t scaleby = min(temprat->pp->exp, temprat->pq->exp); int32_t scaleby = min(temprat->pp.exp, temprat->pq.exp);
scaleby = max<int32_t>(scaleby, 0); scaleby = max<int32_t>(scaleby, 0);
temprat->pp->exp -= scaleby; temprat->pp.exp -= scaleby;
temprat->pq->exp -= scaleby; temprat->pq.exp -= scaleby;
PNUMBER p = nRadixxtonum(temprat->pp, radix, precision); NUMBER p = nRadixxtonum(temprat->pp, radix, precision);
PNUMBER q = nRadixxtonum(temprat->pq, radix, precision); NUMBER q = nRadixxtonum(temprat->pq, radix, precision);
destroyrat(temprat); destroyrat(temprat);
// finally take the time hit to actually divide. // finally take the time hit to actually divide.
divnum(&p, q, radix, precision); divnum(&p, q, radix, precision);
destroynum(q);
return p; return p;
} }
// Converts a PRAT to a PNUMBER and back to a PRAT, flattening/simplifying the rational in the process // Converts a PRAT to a NUMBER and back to a PRAT, flattening/simplifying the rational in the process
void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision) void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision)
{ {
PNUMBER pnum = RatToNumber(prat, radix, precision); NUMBER pnum = RatToNumber(prat, radix, precision);
destroyrat(prat); destroyrat(prat);
prat = numtorat(pnum, radix); prat = numtorat(pnum, radix);
destroynum(pnum);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1374,11 +1328,11 @@ void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision)
// FUNCTION: gcd // FUNCTION: gcd
// //
// ARGUMENTS: // ARGUMENTS:
// PNUMBER representation of a number. // NUMBER representation of a number.
// PNUMBER representation of a number. // NUMBER representation of a number.
// int for Radix // int for Radix
// //
// RETURN: Greatest common divisor in internal BASEX PNUMBER form. // RETURN: Greatest common divisor in internal BASEX NUMBER form.
// //
// DESCRIPTION: gcd uses remainders to find the greatest common divisor. // DESCRIPTION: gcd uses remainders to find the greatest common divisor.
// //
@ -1390,11 +1344,11 @@ void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER gcd( _In_ PNUMBER a, _In_ PNUMBER b) NUMBER gcd( _In_ NUMBER a, _In_ NUMBER b)
{ {
PNUMBER r= nullptr; NUMBER r;
PNUMBER larger= nullptr; NUMBER larger;
PNUMBER smaller= nullptr; NUMBER smaller;
if (zernum(a)) if (zernum(a))
{ {
@ -1424,7 +1378,6 @@ PNUMBER gcd( _In_ PNUMBER a, _In_ PNUMBER b)
larger = smaller; larger = smaller;
smaller = r; smaller = r;
} }
destroynum(smaller);
return larger; return larger;
} }
@ -1437,17 +1390,17 @@ PNUMBER gcd( _In_ PNUMBER a, _In_ PNUMBER b)
// int32_t integer representing base of answer. // int32_t integer representing base of answer.
// uint32_t integer for radix // uint32_t integer for radix
// //
// RETURN: Factorial of input in radix PNUMBER form. // RETURN: Factorial of input in radix NUMBER form.
// //
// NOTE: Not currently used. // NOTE: Not currently used.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER i32factnum(int32_t ini32, uint32_t radix) NUMBER i32factnum(int32_t ini32, uint32_t radix)
{ {
PNUMBER lret= nullptr; NUMBER lret;
PNUMBER tmp= nullptr; NUMBER tmp;
lret = i32tonum( 1, radix); lret = i32tonum( 1, radix);
@ -1455,7 +1408,6 @@ PNUMBER i32factnum(int32_t ini32, uint32_t radix)
{ {
tmp = i32tonum( ini32--, radix); tmp = i32tonum( ini32--, radix);
mulnum( &lret, tmp, radix); mulnum( &lret, tmp, radix);
destroynum( tmp );
} }
return( lret ); return( lret );
} }
@ -1469,15 +1421,15 @@ PNUMBER i32factnum(int32_t ini32, uint32_t radix)
// int32_t integer representing base of answer. // int32_t integer representing base of answer.
// uint32_t integer for radix // uint32_t integer for radix
// //
// RETURN: Factorial of input in base PNUMBER form. // RETURN: Factorial of input in base NUMBER form.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix) NUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix)
{ {
PNUMBER lret= nullptr; NUMBER lret;
PNUMBER tmp= nullptr; NUMBER tmp;
lret = i32tonum( 1, radix); lret = i32tonum( 1, radix);
@ -1487,7 +1439,6 @@ PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix)
{ {
tmp = i32tonum( start, radix); tmp = i32tonum( start, radix);
mulnum( &lret, tmp, radix); mulnum( &lret, tmp, radix);
destroynum( tmp );
} }
start++; start++;
} }
@ -1508,9 +1459,9 @@ PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix)
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void numpowi32( _Inout_ PNUMBER *proot, int32_t power, uint32_t radix, int32_t precision) void numpowi32( _Inout_ NUMBER *proot, int32_t power, uint32_t radix, int32_t precision)
{ {
PNUMBER lret = i32tonum( 1, radix ); NUMBER lret = i32tonum( 1, radix );
while ( power > 0 ) while ( power > 0 )
{ {
@ -1522,7 +1473,6 @@ void numpowi32( _Inout_ PNUMBER *proot, int32_t power, uint32_t radix, int32_t p
TRIMNUM(*proot, precision); TRIMNUM(*proot, precision);
power >>= 1; power >>= 1;
} }
destroynum( *proot );
*proot=lret; *proot=lret;
} }
@ -1546,7 +1496,7 @@ void ratpowi32( _Inout_ PRAT *proot, int32_t power, int32_t precision)
if ( power < 0 ) if ( power < 0 )
{ {
// Take the positive power and invert answer. // Take the positive power and invert answer.
PNUMBER pnumtemp = nullptr; NUMBER pnumtemp;
ratpowi32( proot, -power, precision); ratpowi32( proot, -power, precision);
pnumtemp = (*proot)->pp; pnumtemp = (*proot)->pp;
(*proot)->pp = (*proot)->pq; (*proot)->pp = (*proot)->pq;

View file

@ -133,15 +133,15 @@ void _lograt( PRAT *px, int32_t precision)
createrat(thisterm); createrat(thisterm);
// sub one from x // sub one from x
(*px)->pq->sign *= -1; (*px)->pq.sign *= -1;
addnum(&((*px)->pp),(*px)->pq, BASEX); addnum(&((*px)->pp),(*px)->pq, BASEX);
(*px)->pq->sign *= -1; (*px)->pq.sign *= -1;
DUPRAT(pret,*px); DUPRAT(pret,*px);
DUPRAT(thisterm,*px); DUPRAT(thisterm,*px);
n2=i32tonum(1L, BASEX); n2=i32tonum(1L, BASEX);
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
do { do {
NEXTTERM(*px, MULNUM(n2) INC(n2) DIVNUM(n2), precision); NEXTTERM(*px, MULNUM(n2) INC(n2) DIVNUM(n2), precision);
@ -171,7 +171,7 @@ void lograt( PRAT *px, int32_t precision)
if ( fneglog ) if ( fneglog )
{ {
// WARNING: This is equivalent to doing *px = 1 / *px // WARNING: This is equivalent to doing *px = 1 / *px
PNUMBER pnumtemp= nullptr; NUMBER pnumtemp;
pnumtemp = (*px)->pp; pnumtemp = (*px)->pp;
(*px)->pp = (*px)->pq; (*px)->pp = (*px)->pq;
(*px)->pq = pnumtemp; (*px)->pq = pnumtemp;
@ -185,7 +185,7 @@ void lograt( PRAT *px, int32_t precision)
// a reasonable range. // a reasonable range.
int32_t intpwr; int32_t intpwr;
intpwr=LOGRAT2(*px)-1; intpwr=LOGRAT2(*px)-1;
(*px)->pq->exp += intpwr; (*px)->pq.exp += intpwr;
pwr=i32torat(intpwr*BASEXPWR); pwr=i32torat(intpwr*BASEXPWR);
mulrat(&pwr, ln_two, precision); mulrat(&pwr, ln_two, precision);
// ln(x+e)-ln(x) looks close to e when x is close to one using some // ln(x+e)-ln(x) looks close to e when x is close to one using some
@ -220,7 +220,7 @@ void lograt( PRAT *px, int32_t precision)
// If number started out < 1 rescale answer to negative. // If number started out < 1 rescale answer to negative.
if ( fneglog ) if ( fneglog )
{ {
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
} }
destroyrat(offset); destroyrat(offset);
@ -347,7 +347,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
// ################################## // ##################################
PRAT roundedResult = nullptr; PRAT roundedResult = nullptr;
DUPRAT(roundedResult, originalResult); DUPRAT(roundedResult, originalResult);
if (roundedResult->pp->sign == -1) if (roundedResult->pp.sign == -1)
{ {
subrat(&roundedResult, rat_half, precision); subrat(&roundedResult, rat_half, precision);
} }
@ -408,11 +408,11 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
{ {
int32_t sign = ((*px)->pp->sign * (*px)->pq->sign); int32_t sign = ((*px)->pp.sign * (*px)->pq.sign);
// Take the absolute value // Take the absolute value
(*px)->pp->sign = 1; (*px)->pp.sign = 1;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
if ( zerrat( *px ) ) if ( zerrat( *px ) )
{ {
@ -497,9 +497,9 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
DUPRAT(pDenominator, rat_zero); // pDenominator->pq is 1 one DUPRAT(pDenominator, rat_zero); // pDenominator->pq is 1 one
DUPNUM(pNumerator->pp, y->pp); DUPNUM(pNumerator->pp, y->pp);
pNumerator->pp->sign = 1; pNumerator->pp.sign = 1;
DUPNUM(pDenominator->pp, y->pq); DUPNUM(pDenominator->pp, y->pq);
pDenominator->pp->sign = 1; pDenominator->pp.sign = 1;
while (IsEven(pNumerator, radix, precision) && IsEven(pDenominator, radix, precision)) // both Numerator & denominator is even while (IsEven(pNumerator, radix, precision) && IsEven(pDenominator, radix, precision)) // both Numerator & denominator is even
{ {
@ -536,5 +536,5 @@ void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
} }
destroyrat(pxint); destroyrat(pxint);
} }
(*px)->pp->sign *= sign; (*px)->pp.sign *= sign;
} }

View file

@ -17,8 +17,8 @@
#include "ratpak.h" #include "ratpak.h"
#define ABSRAT(x) (((x)->pp->sign=1),((x)->pq->sign=1)) #define ABSRAT(x) (((x)->pp.sign=1),((x)->pq.sign=1))
#define NEGATE(x) ((x)->pp->sign *= -1) #define NEGATE(x) ((x)->pp.sign *= -1)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -61,7 +61,7 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
{ {
PRAT factorial= nullptr; PRAT factorial= nullptr;
PNUMBER count= nullptr; NUMBER count;
PRAT tmp= nullptr; PRAT tmp= nullptr;
PRAT one_pt_five= nullptr; PRAT one_pt_five= nullptr;
PRAT a= nullptr; PRAT a= nullptr;
@ -185,7 +185,6 @@ void _gamma( PRAT *pn, uint32_t radix, int32_t precision)
destroyrat(tmp); destroyrat(tmp);
destroyrat(one_pt_five); destroyrat(one_pt_five);
destroynum(count);
destroyrat(factorial); destroyrat(factorial);
destroyrat(*pn); destroyrat(*pn);
@ -209,14 +208,14 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision)
DUPRAT(fact,rat_one); DUPRAT(fact,rat_one);
DUPRAT(neg_rat_one,rat_one); DUPRAT(neg_rat_one,rat_one);
neg_rat_one->pp->sign *= -1; neg_rat_one->pp.sign *= -1;
DUPRAT( frac, *px ); DUPRAT( frac, *px );
fracrat( &frac, radix, precision); fracrat( &frac, radix, precision);
// Check for negative integers and throw an error. // Check for negative integers and throw an error.
if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) && if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) &&
( (*px)->pp->sign * (*px)->pq->sign == -1 ) ) ( (*px)->pp.sign * (*px)->pq.sign == -1 ) )
{ {
throw CALC_E_DOMAIN; throw CALC_E_DOMAIN;
} }

View file

@ -96,10 +96,10 @@ void asinrat( PRAT *px, uint32_t radix, int32_t precision)
PRAT pret= nullptr; PRAT pret= nullptr;
PRAT phack= nullptr; PRAT phack= nullptr;
sgn = (*px)->pp->sign* (*px)->pq->sign; sgn = (*px)->pp.sign* (*px)->pq.sign;
(*px)->pp->sign = 1; (*px)->pp.sign = 1;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
// Avoid the really bad part of the asin curve near +/-1. // Avoid the really bad part of the asin curve near +/-1.
DUPRAT(phack,*px); DUPRAT(phack,*px);
@ -129,11 +129,11 @@ void asinrat( PRAT *px, uint32_t radix, int32_t precision)
} }
DUPRAT(pret,*px); DUPRAT(pret,*px);
mulrat( px, pret, precision); mulrat( px, pret, precision);
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
addrat( px, rat_one, precision); addrat( px, rat_one, precision);
rootrat( px, rat_two, radix, precision); rootrat( px, rat_two, radix, precision);
_asinrat( px, precision); _asinrat( px, precision);
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
addrat( px, pi_over_two, precision); addrat( px, pi_over_two, precision);
destroyrat(pret); destroyrat(pret);
} }
@ -142,8 +142,8 @@ void asinrat( PRAT *px, uint32_t radix, int32_t precision)
_asinrat( px, precision); _asinrat( px, precision);
} }
} }
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
} }
@ -206,10 +206,10 @@ void acosrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn; int32_t sgn;
sgn = (*px)->pp->sign*(*px)->pq->sign; sgn = (*px)->pp.sign*(*px)->pq.sign;
(*px)->pp->sign = 1; (*px)->pp.sign = 1;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
if ( rat_equ( *px, rat_one, precision) ) if ( rat_equ( *px, rat_one, precision) )
{ {
@ -224,9 +224,9 @@ void acosrat( PRAT *px, uint32_t radix, int32_t precision)
} }
else else
{ {
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
asinrat( px, radix, precision); asinrat( px, radix, precision);
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
addrat(px, pi_over_two, precision); addrat(px, pi_over_two, precision);
} }
} }
@ -279,7 +279,7 @@ void _atanrat( PRAT *px, int32_t precision)
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
xx->pp->sign *= -1; xx->pp.sign *= -1;
do { do {
NEXTTERM(xx,MULNUM(n2) INC(n2) INC(n2) DIVNUM(n2), precision); NEXTTERM(xx,MULNUM(n2) INC(n2) INC(n2) DIVNUM(n2), precision);
@ -294,29 +294,29 @@ void atanrat( PRAT *px, uint32_t radix, int32_t precision)
int32_t sgn; int32_t sgn;
PRAT tmpx= nullptr; PRAT tmpx= nullptr;
sgn = (*px)->pp->sign * (*px)->pq->sign; sgn = (*px)->pp.sign * (*px)->pq.sign;
(*px)->pp->sign = 1; (*px)->pp.sign = 1;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
if ( rat_gt( (*px), pt_eight_five, precision) ) if ( rat_gt( (*px), pt_eight_five, precision) )
{ {
if ( rat_gt( (*px), rat_two, precision) ) if ( rat_gt( (*px), rat_two, precision) )
{ {
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
DUPRAT(tmpx,rat_one); DUPRAT(tmpx,rat_one);
divrat(&tmpx, (*px), precision); divrat(&tmpx, (*px), precision);
_atanrat(&tmpx, precision); _atanrat(&tmpx, precision);
tmpx->pp->sign = sgn; tmpx->pp.sign = sgn;
tmpx->pq->sign = 1; tmpx->pq.sign = 1;
DUPRAT(*px,pi_over_two); DUPRAT(*px,pi_over_two);
subrat(px, tmpx, precision); subrat(px, tmpx, precision);
destroyrat( tmpx ); destroyrat( tmpx );
} }
else else
{ {
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
DUPRAT(tmpx,*px); DUPRAT(tmpx,*px);
mulrat( &tmpx, *px, precision); mulrat( &tmpx, *px, precision);
addrat( &tmpx, rat_one, precision); addrat( &tmpx, rat_one, precision);
@ -324,14 +324,14 @@ void atanrat( PRAT *px, uint32_t radix, int32_t precision)
divrat( px, tmpx, precision); divrat( px, tmpx, precision);
destroyrat( tmpx ); destroyrat( tmpx );
asinrat( px, radix, precision); asinrat( px, radix, precision);
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
} }
} }
else else
{ {
(*px)->pp->sign = sgn; (*px)->pp.sign = sgn;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
_atanrat( px, precision); _atanrat( px, precision);
} }
if ( rat_gt( *px, pi_over_two, precision) ) if ( rat_gt( *px, pi_over_two, precision) )

View file

@ -56,7 +56,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision)
PRAT neg_pt_eight_five = nullptr; PRAT neg_pt_eight_five = nullptr;
DUPRAT(neg_pt_eight_five,pt_eight_five); DUPRAT(neg_pt_eight_five,pt_eight_five);
neg_pt_eight_five->pp->sign *= -1; neg_pt_eight_five->pp.sign *= -1;
if ( rat_gt( *px, pt_eight_five, precision) || rat_lt( *px, neg_pt_eight_five, precision) ) if ( rat_gt( *px, pt_eight_five, precision) || rat_lt( *px, neg_pt_eight_five, precision) )
{ {
PRAT ptmp = nullptr; PRAT ptmp = nullptr;
@ -71,7 +71,7 @@ void asinhrat( PRAT *px, uint32_t radix, int32_t precision)
else else
{ {
CREATETAYLOR(); CREATETAYLOR();
xx->pp->sign *= -1; xx->pp.sign *= -1;
DUPRAT(pret,(*px)); DUPRAT(pret,(*px));
DUPRAT(thisterm,(*px)); DUPRAT(thisterm,(*px));
@ -152,7 +152,7 @@ void atanhrat( PRAT *px, int32_t precision)
subrat(&ptmp, rat_one, precision); subrat(&ptmp, rat_one, precision);
addrat(px, rat_one, precision); addrat(px, rat_one, precision);
divrat(px, ptmp, precision); divrat(px, ptmp, precision);
(*px)->pp->sign *= -1; (*px)->pp.sign *= -1;
lograt(px, precision); lograt(px, precision);
divrat(px, rat_two, precision); divrat(px, rat_two, precision);
destroyrat(ptmp); destroyrat(ptmp);

View file

@ -65,7 +65,7 @@ void rshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
} }
void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision); void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision);
void boolnum( PNUMBER *pa, PNUMBER b, int func ); void boolnum( NUMBER *pa, NUMBER b, int func );
enum { enum {
@ -130,11 +130,11 @@ void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void boolnum( PNUMBER *pa, PNUMBER b, int func ) void boolnum( NUMBER *pa, NUMBER b, int func )
{ {
PNUMBER c= nullptr; NUMBER c;
PNUMBER a= nullptr; NUMBER a;
vector<MANTTYPE>::iterator pcha; vector<MANTTYPE>::iterator pcha;
vector<MANTTYPE>::iterator pchb; vector<MANTTYPE>::iterator pchb;
vector<MANTTYPE>::iterator pchc; vector<MANTTYPE>::iterator pchc;
@ -144,22 +144,22 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
MANTTYPE db; MANTTYPE db;
a=*pa; a=*pa;
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - cdigits = max( a.cdigit+a.exp, b.cdigit+b.exp ) -
min( a->exp, b->exp ); min( a.exp, b.exp );
createnum( c, cdigits ); createnum( c, cdigits );
c->exp = min( a->exp, b->exp ); c.exp = min( a.exp, b.exp );
mexp = c->exp; mexp = c.exp;
c->cdigit = cdigits; c.cdigit = cdigits;
pcha = a->mant.begin(); pcha = a.mant.begin();
pchb = b->mant.begin(); pchb = b.mant.begin();
pchc = c->mant.begin(); pchc = c.mant.begin();
for ( ;cdigits > 0; cdigits--, mexp++ ) for ( ;cdigits > 0; cdigits--, mexp++ )
{ {
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > da = ( ( ( mexp >= a.exp ) && ( cdigits + a.exp - c.exp >
(c->cdigit - a->cdigit) ) ) ? (c.cdigit - a.cdigit) ) ) ?
*pcha++ : 0 ); *pcha++ : 0 );
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > db = ( ( ( mexp >= b.exp ) && ( cdigits + b.exp - c.exp >
(c->cdigit - b->cdigit) ) ) ? (c.cdigit - b.cdigit) ) ) ?
*pchb++ : 0 ); *pchb++ : 0 );
switch ( func ) switch ( func )
{ {
@ -174,12 +174,11 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
break; break;
} }
} }
c->sign = a->sign; c.sign = a.sign;
while ( c->cdigit > 1 && *(--pchc) == 0 ) while ( c.cdigit > 1 && *(--pchc) == 0 )
{ {
c->cdigit--; c.cdigit--;
} }
destroynum( *pa );
*pa=c; *pa=c;
} }

View file

@ -40,14 +40,14 @@ using namespace std;
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix); void _addnum( NUMBER *pa, NUMBER b, uint32_t radix);
void __inline addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) void __inline addnum( NUMBER *pa, NUMBER b, uint32_t radix)
{ {
if ( b->cdigit > 1 || b->mant[0] != 0 ) if ( b.cdigit > 1 || b.mant[0] != 0 )
{ // If b is zero we are done. { // If b is zero we are done.
if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 0 ) if ( (*pa).cdigit > 1 || (*pa).mant[0] != 0 )
{ // pa and b are both nonzero. { // pa and b are both nonzero.
_addnum( pa, b, radix); _addnum( pa, b, radix);
} }
@ -58,11 +58,11 @@ void __inline addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
} }
} }
void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix) void _addnum( NUMBER *pa, NUMBER b, uint32_t radix)
{ {
PNUMBER c= nullptr; // c will contain the result. NUMBER c; // c will contain the result.
PNUMBER a= nullptr; // a is the dereferenced number pointer from *pa NUMBER a; // a is the dereferenced number pointer from *pa
vector<MANTTYPE>::iterator pcha; // pcha is an iterator pointing to the mantissa of a. vector<MANTTYPE>::iterator pcha; // pcha is an iterator pointing to the mantissa of a.
vector<MANTTYPE>::iterator pchb; // pchb is an iterator pointing to the mantissa of b. vector<MANTTYPE>::iterator pchb; // pchb is an iterator pointing to the mantissa of b.
vector<MANTTYPE>::iterator pchc; // pchc is an iterator pointing to the mantissa of c. vector<MANTTYPE>::iterator pchc; // pchc is an iterator pointing to the mantissa of c.
@ -80,23 +80,23 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// Calculate the overlap of the numbers after alignment, this includes // Calculate the overlap of the numbers after alignment, this includes
// necessary padding 0's // necessary padding 0's
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - cdigits = max( a.cdigit+a.exp, b.cdigit+b.exp ) -
min( a->exp, b->exp ); min( a.exp, b.exp );
createnum( c, cdigits + 1 ); createnum( c, cdigits + 1 );
c->exp = min( a->exp, b->exp ); c.exp = min( a.exp, b.exp );
mexp = c->exp; mexp = c.exp;
c->cdigit = cdigits; c.cdigit = cdigits;
pcha = a->mant.begin(); pcha = a.mant.begin();
pchb = b->mant.begin(); pchb = b.mant.begin();
pchc = c->mant.begin(); pchc = c.mant.begin();
// Figure out the sign of the numbers // Figure out the sign of the numbers
if ( a->sign != b->sign ) if ( a.sign != b.sign )
{ {
cy = 1; cy = 1;
fcompla = ( a->sign == -1 ); fcompla = ( a.sign == -1 );
fcomplb = ( b->sign == -1 ); fcomplb = ( b.sign == -1 );
} }
// Loop over all the digits, real and 0 padded. Here we know a and b are // Loop over all the digits, real and 0 padded. Here we know a and b are
@ -105,12 +105,12 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
{ {
// Get digit from a, taking padding into account. // Get digit from a, taking padding into account.
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp > da = ( ( ( mexp >= a.exp ) && ( cdigits + a.exp - c.exp >
(c->cdigit - a->cdigit) ) ) ? (c.cdigit - a.cdigit) ) ) ?
*pcha++ : 0 ); *pcha++ : 0 );
// Get digit from b, taking padding into account. // Get digit from b, taking padding into account.
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp > db = ( ( ( mexp >= b.exp ) && ( cdigits + b.exp - c.exp >
(c->cdigit - b->cdigit) ) ) ? (c.cdigit - b.cdigit) ) ) ?
*pchb++ : 0 ); *pchb++ : 0 );
// Handle complementing for a and b digit. Might be a better way, but // Handle complementing for a and b digit. Might be a better way, but
@ -134,19 +134,19 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
if ( cy && !(fcompla || fcomplb) ) if ( cy && !(fcompla || fcomplb) )
{ {
*pchc++ = cy; *pchc++ = cy;
c->cdigit++; c.cdigit++;
} }
// Compute sign of result // Compute sign of result
if ( !(fcompla || fcomplb) ) if ( !(fcompla || fcomplb) )
{ {
c->sign = a->sign; c.sign = a.sign;
} }
else else
{ {
if ( cy ) if ( cy )
{ {
c->sign = 1; c.sign = 1;
} }
else else
{ {
@ -154,9 +154,9 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// and all the digits need to be complemented, at one time an // and all the digits need to be complemented, at one time an
// attempt to handle this above was made, it turned out to be much // attempt to handle this above was made, it turned out to be much
// slower on average. // slower on average.
c->sign = -1; c.sign = -1;
cy = 1; cy = 1;
for ( ( cdigits = c->cdigit ), (pchc = c->mant.begin()); for ( ( cdigits = c.cdigit ), (pchc = c.mant.begin());
cdigits > 0; cdigits > 0;
cdigits-- ) cdigits-- )
{ {
@ -169,11 +169,10 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// Remove leading zeros, remember digits are in order of // Remove leading zeros, remember digits are in order of
// increasing significance. i.e. 100 would be 0,0,1 // increasing significance. i.e. 100 would be 0,0,1
while ( c->cdigit > 1 && *(--pchc) == 0 ) while ( c.cdigit > 1 && *(--pchc) == 0 )
{ {
c->cdigit--; c.cdigit--;
} }
destroynum( *pa );
*pa=c; *pa=c;
} }
@ -192,35 +191,35 @@ void _addnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix); void _mulnum( NUMBER *pa, NUMBER b, uint32_t radix);
void __inline mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) void __inline mulnum( NUMBER *pa, NUMBER b, uint32_t radix)
{ {
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b.cdigit > 1 || b.mant[0] != 1 || b.exp != 0 )
{ // If b is one we don't multiply exactly. { // If b is one we don't multiply exactly.
if ( (*pa)->cdigit > 1 || (*pa)->mant[0] != 1 || (*pa)->exp != 0 ) if ( (*pa).cdigit > 1 || (*pa).mant[0] != 1 || (*pa).exp != 0 )
{ // pa and b are both non-one. { // pa and b are both non-one.
_mulnum( pa, b, radix); _mulnum( pa, b, radix);
} }
else else
{ // if pa is one and b isn't just copy b, and adjust the sign. { // if pa is one and b isn't just copy b, and adjust the sign.
int32_t sign = (*pa)->sign; int32_t sign = (*pa).sign;
DUPNUM(*pa,b); DUPNUM(*pa,b);
(*pa)->sign *= sign; (*pa).sign *= sign;
} }
} }
else else
{ // But we do have to set the sign. { // But we do have to set the sign.
(*pa)->sign *= b->sign; (*pa).sign *= b.sign;
} }
} }
void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix) void _mulnum( NUMBER *pa, NUMBER b, uint32_t radix)
{ {
PNUMBER c= nullptr; // c will contain the result. NUMBER c; // c will contain the result.
PNUMBER a= nullptr; // a is the dereferenced number pointer from *pa NUMBER a; // a is the dereferenced number pointer from *pa
vector<MANTTYPE>::iterator pcha; // pcha is an iterator pointing to the mantissa of a. vector<MANTTYPE>::iterator pcha; // pcha is an iterator pointing to the mantissa of a.
vector<MANTTYPE>::iterator pchb; // pchb is an iterator pointing to the mantissa of b. vector<MANTTYPE>::iterator pchb; // pchb is an iterator pointing to the mantissa of b.
vector<MANTTYPE>::iterator pchc; // pchc is an iterator pointing to the mantissa of c. vector<MANTTYPE>::iterator pchc; // pchc is an iterator pointing to the mantissa of c.
@ -236,24 +235,24 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
int32_t icdigit = 0; // Index of digit being calculated in final result. int32_t icdigit = 0; // Index of digit being calculated in final result.
a=*pa; a=*pa;
ibdigit = a->cdigit + b->cdigit - 1; ibdigit = a.cdigit + b.cdigit - 1;
createnum( c, ibdigit + 1 ); createnum( c, ibdigit + 1 );
c->cdigit = ibdigit; c.cdigit = ibdigit;
c->sign = a->sign * b->sign; c.sign = a.sign * b.sign;
c->exp = a->exp + b->exp; c.exp = a.exp + b.exp;
pcha = a->mant.begin(); pcha = a.mant.begin();
pchcoffset = c->mant.begin(); pchcoffset = c.mant.begin();
for ( iadigit = a->cdigit; iadigit > 0; iadigit-- ) for ( iadigit = a.cdigit; iadigit > 0; iadigit-- )
{ {
da = *pcha++; da = *pcha++;
pchb = b->mant.begin(); pchb = b.mant.begin();
// Shift pchc, and pchcoffset, one for each digit // Shift pchc, and pchcoffset, one for each digit
pchc = pchcoffset++; pchc = pchcoffset++;
for ( ibdigit = b->cdigit; ibdigit > 0; ibdigit-- ) for ( ibdigit = b.cdigit; ibdigit > 0; ibdigit-- )
{ {
cy = 0; cy = 0;
mcy = (TWO_MANTTYPE)da * *pchb; mcy = (TWO_MANTTYPE)da * *pchb;
@ -262,7 +261,7 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
icdigit = 0; icdigit = 0;
if ( ibdigit == 1 && iadigit == 1 ) if ( ibdigit == 1 && iadigit == 1 )
{ {
c->cdigit++; c.cdigit++;
} }
} }
// If result is nonzero, or while result of carry is nonzero... // If result is nonzero, or while result of carry is nonzero...
@ -287,12 +286,11 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// prevent different kinds of zeros, by stripping leading duplicate zeros. // prevent different kinds of zeros, by stripping leading duplicate zeros.
// digits are in order of increasing significance. // digits are in order of increasing significance.
while ( c->cdigit > 1 && c->mant[c->cdigit-1] == 0 ) while ( c.cdigit > 1 && c.mant[c.cdigit-1] == 0 )
{ {
c->cdigit--; c.cdigit--;
} }
destroynum( *pa );
*pa=c; *pa=c;
} }
@ -312,11 +310,11 @@ void _mulnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix) void remnum( NUMBER *pa, NUMBER b, uint32_t radix)
{ {
PNUMBER tmp = nullptr; // tmp is the working remainder. NUMBER tmp; // tmp is the working remainder.
PNUMBER lasttmp = nullptr; // lasttmp is the last remainder which worked. NUMBER lasttmp; // lasttmp is the last remainder which worked.
// Once *pa is less than b, *pa is the remainder. // Once *pa is less than b, *pa is the remainder.
while ( !lessnum( *pa, b ) ) while ( !lessnum( *pa, b ) )
@ -325,15 +323,14 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
if ( lessnum( tmp, *pa ) ) if ( lessnum( tmp, *pa ) )
{ {
// Start off close to the right answer for subtraction. // Start off close to the right answer for subtraction.
tmp->exp = (*pa)->cdigit+(*pa)->exp - tmp->cdigit; tmp.exp = (*pa).cdigit+(*pa).exp - tmp.cdigit;
if ( MSD(*pa) <= MSD(tmp) ) if ( MSD(*pa) <= MSD(tmp) )
{ {
// Don't take the chance that the numbers are equal. // Don't take the chance that the numbers are equal.
tmp->exp--; tmp.exp--;
} }
} }
destroynum( lasttmp );
lasttmp=i32tonum( 0, radix); lasttmp=i32tonum( 0, radix);
while ( lessnum( tmp, *pa ) ) while ( lessnum( tmp, *pa ) )
@ -345,17 +342,14 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
if ( lessnum( *pa, tmp ) ) if ( lessnum( *pa, tmp ) )
{ {
// too far, back up... // too far, back up...
destroynum( tmp );
tmp=lasttmp; tmp=lasttmp;
lasttmp= nullptr; lasttmp= nullptr;
} }
// Subtract the working remainder from the remainder holder. // Subtract the working remainder from the remainder holder.
tmp->sign = -1*(*pa)->sign; tmp.sign = -1*(*pa).sign;
addnum( pa, tmp, radix); addnum( pa, tmp, radix);
destroynum( tmp );
destroynum( lasttmp );
} }
} }
@ -375,68 +369,67 @@ void remnum( PNUMBER *pa, PNUMBER b, uint32_t radix)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision); void _divnum( NUMBER *pa, NUMBER b, uint32_t radix, int32_t precision);
void __inline divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) void __inline divnum( NUMBER *pa, NUMBER b, uint32_t radix, int32_t precision)
{ {
if ( b->cdigit > 1 || b->mant[0] != 1 || b->exp != 0 ) if ( b.cdigit > 1 || b.mant[0] != 1 || b.exp != 0 )
{ {
// b is not one // b is not one
_divnum( pa, b, radix, precision); _divnum( pa, b, radix, precision);
} }
else else
{ // But we do have to set the sign. { // But we do have to set the sign.
(*pa)->sign *= b->sign; (*pa).sign *= b.sign;
} }
} }
void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision) void _divnum( NUMBER *pa, NUMBER b, uint32_t radix, int32_t precision)
{ {
PNUMBER a = *pa; NUMBER a = *pa;
int32_t thismax = precision + 2; int32_t thismax = precision + 2;
if (thismax < a->cdigit) if (thismax < a.cdigit)
{ {
thismax = a->cdigit; thismax = a.cdigit;
} }
if (thismax < b->cdigit) if (thismax < b.cdigit)
{ {
thismax = b->cdigit; thismax = b.cdigit;
} }
PNUMBER c = nullptr; NUMBER c;
createnum(c, thismax + 1); createnum(c, thismax + 1);
c->exp = (a->cdigit + a->exp) - (b->cdigit + b->exp) + 1; c.exp = (a.cdigit + a.exp) - (b.cdigit + b.exp) + 1;
c->sign = a->sign * b->sign; c.sign = a.sign * b.sign;
vector<MANTTYPE>::iterator ptrc = c->mant.begin() + thismax; vector<MANTTYPE>::iterator ptrc = c.mant.begin() + thismax;
PNUMBER rem = nullptr; NUMBER rem;
PNUMBER tmp = nullptr; NUMBER tmp;
DUPNUM(rem, a); DUPNUM(rem, a);
DUPNUM(tmp, b); DUPNUM(tmp, b);
tmp->sign = a->sign; tmp.sign = a.sign;
rem->exp = b->cdigit + b->exp - rem->cdigit; rem.exp = b.cdigit + b.exp - rem.cdigit;
// Build a table of multiplications of the divisor, this is quicker for // Build a table of multiplications of the divisor, this is quicker for
// more than radix 'digits' // more than radix 'digits'
list<PNUMBER> numberList{ i32tonum(0L, radix) }; list<NUMBER> numberList{ i32tonum(0L, radix) };
for (uint32_t i = 1; i < radix; i++) for (uint32_t i = 1; i < radix; i++)
{ {
PNUMBER newValue = nullptr; NUMBER newValue;
DUPNUM(newValue, numberList.front()); DUPNUM(newValue, numberList.front());
addnum(&newValue, tmp, radix); addnum(&newValue, tmp, radix);
numberList.emplace_front(newValue); numberList.emplace_front(newValue);
} }
destroynum(tmp);
int32_t digit; int32_t digit;
int32_t cdigits = 0; int32_t cdigits = 0;
while (cdigits++ < thismax && !zernum(rem)) while (cdigits++ < thismax && !zernum(rem))
{ {
digit = radix - 1; digit = radix - 1;
PNUMBER multiple = nullptr; NUMBER multiple;
for (const auto& num : numberList) for (const auto& num : numberList)
{ {
if (!lessnum(rem, num) || !--digit) if (!lessnum(rem, num) || !--digit)
@ -448,43 +441,40 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision)
if (digit) if (digit)
{ {
multiple->sign *= -1; multiple.sign *= -1;
addnum(&rem, multiple, radix); addnum(&rem, multiple, radix);
multiple->sign *= -1; multiple.sign *= -1;
} }
rem->exp++; rem.exp++;
*ptrc-- = (MANTTYPE)digit; *ptrc-- = (MANTTYPE)digit;
} }
cdigits--; cdigits--;
if (c->mant.begin() != ++ptrc) if (c.mant.begin() != ++ptrc)
{ {
copy(ptrc, ptrc + cdigits, c->mant.begin()); copy(ptrc, ptrc + cdigits, c.mant.begin());
} }
// Cleanup table structure // Cleanup table structure
for (auto& num : numberList) for (auto& num : numberList)
{ {
destroynum(num);
} }
if (!cdigits) if (!cdigits)
{ {
c->cdigit = 1; c.cdigit = 1;
c->exp = 0; c.exp = 0;
} }
else else
{ {
c->cdigit = cdigits; c.cdigit = cdigits;
c->exp -= cdigits; c.exp -= cdigits;
while (c->cdigit > 1 && c->mant[c->cdigit - 1] == 0) while (c.cdigit > 1 && c.mant[c.cdigit - 1] == 0)
{ {
c->cdigit--; c.cdigit--;
} }
} }
destroynum(rem);
destroynum(*pa);
*pa = c; *pa = c;
} }
@ -502,7 +492,7 @@ void _divnum( PNUMBER *pa, PNUMBER b, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool equnum( PNUMBER a, PNUMBER b ) bool equnum( NUMBER a, NUMBER b )
{ {
int32_t diff; int32_t diff;
@ -513,7 +503,7 @@ bool equnum( PNUMBER a, PNUMBER b )
MANTTYPE da; MANTTYPE da;
MANTTYPE db; MANTTYPE db;
diff = ( a->cdigit + a->exp ) - ( b->cdigit + b->exp ); diff = ( a.cdigit + a.exp ) - ( b.cdigit + b.exp );
if ( diff < 0 ) if ( diff < 0 )
{ {
// If the exponents are different, these are different numbers. // If the exponents are different, these are different numbers.
@ -529,19 +519,19 @@ bool equnum( PNUMBER a, PNUMBER b )
else else
{ {
// OK the exponents match. // OK the exponents match.
ia = a->cdigit - 1; ia = a.cdigit - 1;
ib = b->cdigit - 1; ib = b.cdigit - 1;
cdigits = max( a->cdigit, b->cdigit ); cdigits = max( a.cdigit, b.cdigit );
ccdigits = cdigits; ccdigits = cdigits;
// Loop over all digits until we run out of digits or there is a // Loop over all digits until we run out of digits or there is a
// difference in the digits. // difference in the digits.
for ( ;cdigits > 0; cdigits-- ) for ( ;cdigits > 0; cdigits-- )
{ {
da = ( (cdigits > (ccdigits - a->cdigit) ) ? da = ( (cdigits > (ccdigits - a.cdigit) ) ?
a->mant[ia--] : 0 ); a.mant[ia--] : 0 );
db = ( (cdigits > (ccdigits - b->cdigit) ) ? db = ( (cdigits > (ccdigits - b.cdigit) ) ?
b->mant[ib--] : 0 ); b.mant[ib--] : 0 );
if ( da != db ) if ( da != db )
{ {
return false; return false;
@ -568,7 +558,7 @@ bool equnum( PNUMBER a, PNUMBER b )
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool lessnum( PNUMBER a, PNUMBER b ) bool lessnum( NUMBER a, NUMBER b )
{ {
int32_t diff; int32_t diff;
@ -580,7 +570,7 @@ bool lessnum( PNUMBER a, PNUMBER b )
MANTTYPE db; MANTTYPE db;
diff = ( a->cdigit + a->exp ) - ( b->cdigit + b->exp ); diff = ( a.cdigit + a.exp ) - ( b.cdigit + b.exp );
if ( diff < 0 ) if ( diff < 0 )
{ {
// The exponent of a is less than b // The exponent of a is less than b
@ -594,16 +584,16 @@ bool lessnum( PNUMBER a, PNUMBER b )
} }
else else
{ {
ia = a->cdigit - 1; ia = a.cdigit - 1;
ib = b->cdigit - 1; ib = b.cdigit - 1;
cdigits = max( a->cdigit, b->cdigit ); cdigits = max( a.cdigit, b.cdigit );
ccdigits = cdigits; ccdigits = cdigits;
for ( ;cdigits > 0; cdigits-- ) for ( ;cdigits > 0; cdigits-- )
{ {
da = ( (cdigits > (ccdigits - a->cdigit) ) ? da = ( (cdigits > (ccdigits - a.cdigit) ) ?
a->mant[ia--] : 0 ); a.mant[ia--] : 0 );
db = ( (cdigits > (ccdigits - b->cdigit) ) ? db = ( (cdigits > (ccdigits - b.cdigit) ) ?
b->mant[ib--] : 0 ); b.mant[ib--] : 0 );
diff = da-db; diff = da-db;
if ( diff ) if ( diff )
{ {
@ -628,17 +618,17 @@ bool lessnum( PNUMBER a, PNUMBER b )
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool zernum( PNUMBER a ) bool zernum( NUMBER a )
{ {
int32_t length = a->cdigit; int32_t length = a.cdigit;
int32_t index = 0; int32_t index = 0;
// loop over all the digits until you find a nonzero or until you run // loop over all the digits until you find a nonzero or until you run
// out of digits // out of digits
while ( length-- > 0 ) while ( length-- > 0 )
{ {
if ( a->mant[index++] ) if ( a.mant[index++] )
{ {
// One of the digits isn't zero, therefore the number isn't zero // One of the digits isn't zero, therefore the number isn't zero
return false; return false;

View file

@ -41,7 +41,7 @@ using namespace std;
void gcdrat( PRAT *pa, int32_t precision) void gcdrat( PRAT *pa, int32_t precision)
{ {
PNUMBER pgcd= nullptr; NUMBER pgcd;
PRAT a= nullptr; PRAT a= nullptr;
a=*pa; a=*pa;
@ -53,7 +53,6 @@ void gcdrat( PRAT *pa, int32_t precision)
divnumx( &(a->pq), pgcd, precision); divnumx( &(a->pq), pgcd, precision);
} }
destroynum( pgcd );
*pa=a; *pa=a;
RENORMALIZE(*pa); RENORMALIZE(*pa);
@ -190,9 +189,9 @@ void divrat( PRAT *pa, PRAT b, int32_t precision)
void subrat( PRAT *pa, PRAT b, int32_t precision) void subrat( PRAT *pa, PRAT b, int32_t precision)
{ {
b->pp->sign *= -1; b->pp.sign *= -1;
addrat( pa, b, precision); addrat( pa, b, precision);
b->pp->sign *= -1; b->pp.sign *= -1;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -211,7 +210,7 @@ void subrat( PRAT *pa, PRAT b, int32_t precision)
void addrat( PRAT *pa, PRAT b, int32_t precision) void addrat( PRAT *pa, PRAT b, int32_t precision)
{ {
PNUMBER bot= nullptr; NUMBER bot;
if ( equnum( (*pa)->pq, b->pq ) ) if ( equnum( (*pa)->pq, b->pq ) )
{ {
@ -219,10 +218,10 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
// make sure signs are involved in the calculation // make sure signs are involved in the calculation
// we have to do this since the optimization here is only // we have to do this since the optimization here is only
// working with the top half of the rationals. // working with the top half of the rationals.
(*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pp.sign *= (*pa)->pq.sign;
(*pa)->pq->sign = 1; (*pa)->pq.sign = 1;
b->pp->sign *= b->pq->sign; b->pp.sign *= b->pq.sign;
b->pq->sign = 1; b->pq.sign = 1;
addnum( &((*pa)->pp), b->pp, BASEX ); addnum( &((*pa)->pp), b->pp, BASEX );
} }
else else
@ -233,13 +232,12 @@ void addrat( PRAT *pa, PRAT b, int32_t precision)
mulnumx( &((*pa)->pp), b->pq ); mulnumx( &((*pa)->pp), b->pq );
mulnumx( &((*pa)->pq), b->pp ); mulnumx( &((*pa)->pq), b->pp );
addnum( &((*pa)->pp), (*pa)->pq, BASEX ); addnum( &((*pa)->pp), (*pa)->pq, BASEX );
destroynum( (*pa)->pq );
(*pa)->pq = bot; (*pa)->pq = bot;
trimit(pa, precision); trimit(pa, precision);
// Get rid of negative zeros here. // Get rid of negative zeros here.
(*pa)->pp->sign *= (*pa)->pq->sign; (*pa)->pp.sign *= (*pa)->pq.sign;
(*pa)->pq->sign = 1; (*pa)->pq.sign = 1;
} }
#ifdef ADDGCD #ifdef ADDGCD

View file

@ -62,7 +62,7 @@ typedef struct _number
int32_t exp; // The offset of digits from the radix point int32_t exp; // The offset of digits from the radix point
// (decimal point in radix 10) // (decimal point in radix 10)
std::vector<MANTTYPE> mant; std::vector<MANTTYPE> mant;
} NUMBER, *PNUMBER, **PPNUMBER; } NUMBER;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -74,8 +74,8 @@ typedef struct _number
typedef struct _rat typedef struct _rat
{ {
PNUMBER pp; NUMBER pp;
PNUMBER pq; NUMBER pq;
} RAT, *PRAT; } RAT, *PRAT;
static constexpr uint32_t MAX_LONG_SIZE = 33; // Base 2 requires 32 'digits' static constexpr uint32_t MAX_LONG_SIZE = 33; // Base 2 requires 32 'digits'
@ -87,11 +87,11 @@ static constexpr uint32_t MAX_LONG_SIZE = 33; // Base 2 requires 32 'digits'
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
extern PNUMBER num_one; extern NUMBER num_one;
extern PNUMBER num_two; extern NUMBER num_two;
extern PNUMBER num_five; extern NUMBER num_five;
extern PNUMBER num_six; extern NUMBER num_six;
extern PNUMBER num_ten; extern NUMBER num_ten;
extern PRAT ln_ten; extern PRAT ln_ten;
extern PRAT ln_two; extern PRAT ln_two;
@ -130,7 +130,7 @@ extern PRAT rat_max_i32;
extern PRAT rat_min_i32; extern PRAT rat_min_i32;
// DUPNUM Duplicates a number taking care of allocation and internals // DUPNUM Duplicates a number taking care of allocation and internals
#define DUPNUM(a,b) destroynum(a);createnum( a, (b)->cdigit );_dupnum(a, b); #define DUPNUM(a,b) createnum( a, (b).cdigit );_dupnum(a, &b);
// DUPRAT Duplicates a rational taking care of allocation and internals // DUPRAT Duplicates a rational taking care of allocation and internals
#define DUPRAT(a,b) destroyrat(a);createrat(a);DUPNUM((a)->pp,(b)->pp);DUPNUM((a)->pq,(b)->pq); #define DUPRAT(a,b) destroyrat(a);createrat(a);DUPNUM((a)->pp,(b)->pp);DUPNUM((a)->pq,(b)->pq);
@ -138,13 +138,13 @@ extern PRAT rat_min_i32;
// LOG*RADIX calculates the integral portion of the log of a number in // LOG*RADIX calculates the integral portion of the log of a number in
// the base currently being used, only accurate to within g_ratio // the base currently being used, only accurate to within g_ratio
#define LOGNUMRADIX(pnum) (((pnum)->cdigit+(pnum)->exp)*g_ratio) #define LOGNUMRADIX(pnum) (((pnum).cdigit+(pnum).exp)*g_ratio)
#define LOGRATRADIX(prat) (LOGNUMRADIX((prat)->pp)-LOGNUMRADIX((prat)->pq)) #define LOGRATRADIX(prat) (LOGNUMRADIX((prat)->pp)-LOGNUMRADIX((prat)->pq))
// LOG*2 calculates the integral portion of the log of a number in // LOG*2 calculates the integral portion of the log of a number in
// the internal base being used, only accurate to within g_ratio // the internal base being used, only accurate to within g_ratio
#define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp) #define LOGNUM2(pnum) ((pnum).cdigit+(pnum).exp)
#define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq)) #define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq))
#if defined( DEBUG_RATPAK ) #if defined( DEBUG_RATPAK )
@ -174,18 +174,14 @@ _destroyrat(x),(x)=nullptr
outputString << "createnum " << y << " " << # y << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \ outputString << "createnum " << y << " " << # y << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
OutputDebugString(outputString.str().c_str()); \ OutputDebugString(outputString.str().c_str()); \
} }
#define destroynum(x) \
{ \ { \
std::wstringstream outputString; \ std::wstringstream outputString; \
outputString << "destroynum " << x << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
OutputDebugString(outputString.str().c_str()); \ OutputDebugString(outputString.str().c_str()); \
} \ }
_destroynum(x),(x)=nullptr
#else #else
#define createrat(y) (y)=_createrat() #define createrat(y) (y)=_createrat()
#define destroyrat(x) _destroyrat(x),(x)=nullptr #define destroyrat(x) _destroyrat(x),(x)=nullptr
#define createnum(y,x) (y)=_createnum(x) #define createnum(y,x) (y)=_createnum(x)
#define destroynum(x) _destroynum(x),(x)=nullptr
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -196,40 +192,40 @@ _destroynum(x),(x)=nullptr
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RENORMALIZE, gets the exponents non-negative. // RENORMALIZE, gets the exponents non-negative.
#define RENORMALIZE(x) if ( (x)->pp->exp < 0 ) { \ #define RENORMALIZE(x) if ( (x)->pp.exp < 0 ) { \
(x)->pq->exp -= (x)->pp->exp; \ (x)->pq.exp -= (x)->pp.exp; \
(x)->pp->exp = 0; \ (x)->pp.exp = 0; \
} \ } \
if ( (x)->pq->exp < 0 ) { \ if ( (x)->pq.exp < 0 ) { \
(x)->pp->exp -= (x)->pq->exp; \ (x)->pp.exp -= (x)->pq.exp; \
(x)->pq->exp = 0; \ (x)->pq.exp = 0; \
} }
// TRIMNUM ASSUMES the number is in radix form NOT INTERNAL BASEX!!! // TRIMNUM ASSUMES the number is in radix form NOT INTERNAL BASEX!!!
#define TRIMNUM(x, precision) if ( !g_ftrueinfinite ) { \ #define TRIMNUM(x, precision) if ( !g_ftrueinfinite ) { \
int32_t trim = (x)->cdigit - precision-g_ratio;\ int32_t trim = (x).cdigit - precision-g_ratio;\
if ( trim > 1 ) \ if ( trim > 1 ) \
{ \ { \
std::copy((x)->mant.begin() + trim, (x)->mant.begin() + (x)->cdigit, (x)->mant.begin());\ std::copy((x).mant.begin() + trim, (x).mant.begin() + (x).cdigit, (x).mant.begin());\
(x)->cdigit -= trim; \ (x).cdigit -= trim; \
(x)->exp += trim; \ (x).exp += trim; \
} \ } \
} }
// TRIMTOP ASSUMES the number is in INTERNAL BASEX!!! // TRIMTOP ASSUMES the number is in INTERNAL BASEX!!!
#define TRIMTOP(x, precision) if ( !g_ftrueinfinite ) { \ #define TRIMTOP(x, precision) if ( !g_ftrueinfinite ) { \
int32_t trim = (x)->pp->cdigit - (precision/g_ratio) - 2;\ int32_t trim = (x)->pp.cdigit - (precision/g_ratio) - 2;\
if ( trim > 1 ) \ if ( trim > 1 ) \
{ \ { \
std::copy((x)->pp->mant.begin() + trim, (x)->pp->mant.begin() + (x)->pp->cdigit, (x)->pp->mant.begin()); \ std::copy((x)->pp.mant.begin() + trim, (x)->pp.mant.begin() + (x)->pp.cdigit, (x)->pp.mant.begin()); \
(x)->pp->cdigit -= trim; \ (x)->pp.cdigit -= trim; \
(x)->pp->exp += trim; \ (x)->pp.exp += trim; \
} \ } \
trim = std::min((x)->pp->exp,(x)->pq->exp);\ trim = std::min((x)->pp.exp,(x)->pq.exp);\
(x)->pp->exp -= trim;\ (x)->pp.exp -= trim;\
(x)->pq->exp -= trim;\ (x)->pq.exp -= trim;\
} }
#define SMALL_ENOUGH_RAT(a, precision) (zernum((a)->pp) || ( ( ( (a)->pq->cdigit + (a)->pq->exp ) - ( (a)->pp->cdigit + (a)->pp->exp ) - 1 ) * g_ratio > precision ) ) #define SMALL_ENOUGH_RAT(a, precision) (zernum((a)->pp) || ( ( ( (a)->pq.cdigit + (a)->pq.exp ) - ( (a)->pp.cdigit + (a)->pp.exp ) - 1 ) * g_ratio > precision ) )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -239,7 +235,7 @@ std::copy((x)->pp->mant.begin() + trim, (x)->pp->mant.begin() + (x)->pp->cdigit,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define CREATETAYLOR() PRAT xx=nullptr;\ #define CREATETAYLOR() PRAT xx=nullptr;\
PNUMBER n2=nullptr; \ NUMBER n2; \
PRAT pret=nullptr; \ PRAT pret=nullptr; \
PRAT thisterm=nullptr; \ PRAT thisterm=nullptr; \
DUPRAT(xx,*px); \ DUPRAT(xx,*px); \
@ -257,16 +253,16 @@ std::copy((x)->pp->mant.begin() + trim, (x)->pp->mant.begin() + (x)->pp->cdigit,
// INC(a) is the rational equivalent of a++ // INC(a) is the rational equivalent of a++
// Check to see if we can avoid doing this the hard way. // Check to see if we can avoid doing this the hard way.
#define INC(a) if ( (a)->mant[0] < BASEX - 1 ) \ #define INC(a) if ( (a).mant[0] < BASEX - 1 ) \
{ \ { \
(a)->mant[0]++; \ (a).mant[0]++; \
} \ } \
else \ else \
{ \ { \
addnum( &(a), num_one, BASEX); \ addnum( &(a), num_one, BASEX); \
} }
#define MSD(x) ((x)->mant[(x)->cdigit-1]) #define MSD(x) ((x).mant[(x).cdigit-1])
// MULNUM(b) is the rational equivalent of thisterm *= b where thisterm is // MULNUM(b) is the rational equivalent of thisterm *= b where thisterm is
// a rational and b is a number, NOTE this is a mixed type operation for // a rational and b is a number, NOTE this is a mixed type operation for
// efficiency reasons. // efficiency reasons.
@ -307,35 +303,35 @@ extern void SetDecimalSeparator(wchar_t decimalSeparator);
// Call whenever either radix or precision changes, is smarter about recalculating constants. // Call whenever either radix or precision changes, is smarter about recalculating constants.
extern void ChangeConstants(uint32_t radix, int32_t precision); extern void ChangeConstants(uint32_t radix, int32_t precision);
extern bool equnum(_In_ PNUMBER a, _In_ PNUMBER b ); // returns true of a == b extern bool equnum(_In_ NUMBER a, _In_ NUMBER b ); // returns true of a == b
extern bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b ); // returns true of a < b extern bool lessnum(_In_ NUMBER a, _In_ NUMBER b ); // returns true of a < b
extern bool zernum(_In_ PNUMBER a ); // returns true of a == 0 extern bool zernum(_In_ NUMBER a ); // returns true of a == 0
extern bool zerrat(_In_ PRAT a ); // returns true if a == 0/q extern bool zerrat(_In_ PRAT a ); // returns true if a == 0/q
extern std::wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_t precision); extern std::wstring NumberToString(_Inout_ NUMBER& pnum, int format, uint32_t radix, int32_t precision);
// returns a text representation of a PRAT // returns a text representation of a PRAT
extern std::wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision); extern std::wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision);
// converts a PRAT into a PNUMBER // converts a PRAT into a NUMBER
extern PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision); extern NUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision);
// flattens a PRAT by converting it to a PNUMBER and back to a PRAT // flattens a PRAT by converting it to a NUMBER and back to a PRAT
extern void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision); extern void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision);
extern int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix ); extern int32_t numtoi32(_In_ NUMBER pnum, uint32_t radix );
extern int32_t rattoi32(_In_ PRAT prat, uint32_t radix, int32_t precision); extern int32_t rattoi32(_In_ PRAT prat, uint32_t radix, int32_t precision);
uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision); uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision);
extern PNUMBER _createnum(_In_ uint32_t size ); // returns an empty number structure with size digits extern NUMBER _createnum(_In_ uint32_t size ); // returns an empty number structure with size digits
extern PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision); extern NUMBER nRadixxtonum(_In_ NUMBER a, uint32_t radix, int32_t precision);
extern PNUMBER gcd(_In_ PNUMBER a, _In_ PNUMBER b ); extern NUMBER gcd(_In_ NUMBER a, _In_ NUMBER b );
extern PNUMBER StringToNumber(std::wstring_view numberString, uint32_t radix, int32_t precision); // takes a text representation of a number and returns a number. extern NUMBER StringToNumber(std::wstring_view numberString, uint32_t radix, int32_t precision); // takes a text representation of a number and returns a number.
// takes a text representation of a number as a mantissa with sign and an exponent with sign. // takes a text representation of a number as a mantissa with sign and an exponent with sign.
extern PRAT StringToRat(bool mantissaIsNegative, std::wstring_view mantissa, bool exponentIsNegative, std::wstring_view exponent, uint32_t radix, int32_t precision); extern PRAT StringToRat(bool mantissaIsNegative, std::wstring_view mantissa, bool exponentIsNegative, std::wstring_view exponent, uint32_t radix, int32_t precision);
extern PNUMBER i32factnum(int32_t ini32, uint32_t radix); extern NUMBER i32factnum(int32_t ini32, uint32_t radix);
extern PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix); extern NUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix);
extern PNUMBER i32tonum(int32_t ini32, uint32_t radix); extern NUMBER i32tonum(int32_t ini32, uint32_t radix);
extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix); extern NUMBER Ui32tonum(uint32_t ini32, uint32_t radix);
extern PNUMBER numtonRadixx(PNUMBER a, uint32_t radix); extern NUMBER numtonRadixx(NUMBER a, uint32_t radix);
// creates a empty/undefined rational representation (p/q) // creates a empty/undefined rational representation (p/q)
extern PRAT _createrat( void ); extern PRAT _createrat( void );
@ -394,7 +390,7 @@ extern void lograt( _Inout_ PRAT *px, int32_t precision);
extern PRAT i32torat( int32_t ini32 ); extern PRAT i32torat( int32_t ini32 );
extern PRAT Ui32torat( uint32_t inui32 ); extern PRAT Ui32torat( uint32_t inui32 );
extern PRAT numtorat( _In_ PNUMBER pin, uint32_t radix); extern PRAT numtorat( _In_ NUMBER pin, uint32_t radix);
extern void sinhrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void sinhrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void sinrat( _Inout_ PRAT *px ); extern void sinrat( _Inout_ PRAT *px );
@ -410,32 +406,31 @@ extern void tanrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
// angle type // angle type
extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision); extern void tananglerat( _Inout_ PRAT *px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER * const src); extern void _dupnum(_In_ NUMBER dest, _In_ const NUMBER * const src);
extern void _destroynum( _In_ PNUMBER pnum );
extern void _destroyrat( _In_ PRAT prat ); extern void _destroyrat( _In_ PRAT prat );
extern void addnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void addnum( _Inout_ NUMBER *pa, _In_ NUMBER b, uint32_t radix);
extern void addrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); extern void addrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void andrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void andrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision);
extern void divnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix, int32_t precision); extern void divnum( _Inout_ NUMBER *pa, _In_ NUMBER b, uint32_t radix, int32_t precision);
extern void divnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b, int32_t precision); extern void divnumx( _Inout_ NUMBER *pa, _In_ NUMBER b, int32_t precision);
extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision); extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision);
extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision);
extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b ); extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b );
extern void gcdrat( _Inout_ PRAT *pa, int32_t precision); extern void gcdrat( _Inout_ PRAT *pa, int32_t precision);
extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void mulnum( _Inout_ NUMBER *pa, _In_ NUMBER b, uint32_t radix);
extern void mulnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b ); extern void mulnumx( _Inout_ NUMBER *pa, _In_ NUMBER b );
extern void mulrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); extern void mulrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void numpowi32( _Inout_ PNUMBER *proot, int32_t power, uint32_t radix, int32_t precision); extern void numpowi32( _Inout_ NUMBER *proot, int32_t power, uint32_t radix, int32_t precision);
extern void numpowi32x( _Inout_ PNUMBER *proot, int32_t power ); extern void numpowi32x( _Inout_ NUMBER *proot, int32_t power );
extern void orrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void orrat( _Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision);
extern void powrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision); extern void powrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision);
extern void powratNumeratorDenominator(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powratNumeratorDenominator(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision);
extern void powratcomp(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision); extern void powratcomp(_Inout_ PRAT *pa, _In_ PRAT b, uint32_t radix, int32_t precision);
extern void ratpowi32( _Inout_ PRAT *proot, int32_t power, int32_t precision); extern void ratpowi32( _Inout_ PRAT *proot, int32_t power, int32_t precision);
extern void remnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void remnum( _Inout_ NUMBER *pa, _In_ NUMBER b, uint32_t radix);
extern void rootrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision); extern void rootrat( _Inout_ PRAT *pa, _In_ PRAT b , uint32_t radix, int32_t precision);
extern void scale2pi( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void scale2pi( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void scale( _Inout_ PRAT *px, _In_ PRAT scalefact, uint32_t radix, int32_t precision); extern void scale( _Inout_ PRAT *px, _In_ PRAT scalefact, uint32_t radix, int32_t precision);
@ -452,4 +447,4 @@ extern bool rat_le( _In_ PRAT a, _In_ PRAT b, int32_t precision);
extern void inbetween( _In_ PRAT *px, _In_ PRAT range, int32_t precision); extern void inbetween( _In_ PRAT *px, _In_ PRAT range, int32_t precision);
extern void trimit( _Inout_ PRAT *px, int32_t precision); extern void trimit( _Inout_ PRAT *px, int32_t precision);
extern void _dumprawrat(_In_ const wchar_t *varname, _In_ PRAT rat, std::wostream& out); extern void _dumprawrat(_In_ const wchar_t *varname, _In_ PRAT rat, std::wostream& out);
extern void _dumprawnum(_In_ const wchar_t *varname, _In_ PNUMBER num, std::wostream& out); extern void _dumprawnum(_In_ const wchar_t *varname, _In_ NUMBER num, std::wostream& out);

View file

@ -62,11 +62,11 @@ bool g_ftrueinfinite = false; // Set to true if you don't want
// chopping internally // chopping internally
// precision used internally // precision used internally
PNUMBER num_one= nullptr; NUMBER num_one;
PNUMBER num_two= nullptr; NUMBER num_two;
PNUMBER num_five= nullptr; NUMBER num_five;
PNUMBER num_six= nullptr; NUMBER num_six;
PNUMBER num_ten= nullptr; NUMBER num_ten;
PRAT ln_ten= nullptr; PRAT ln_ten= nullptr;
PRAT ln_two= nullptr; PRAT ln_two= nullptr;
@ -168,7 +168,7 @@ void ChangeConstants(uint32_t radix, int32_t precision)
DUPRAT(rat_smallest, rat_nRadix); DUPRAT(rat_smallest, rat_nRadix);
ratpowi32(&rat_smallest, -precision, precision); ratpowi32(&rat_smallest, -precision, precision);
DUPRAT(rat_negsmallest, rat_smallest); DUPRAT(rat_negsmallest, rat_smallest);
rat_negsmallest->pp->sign = -1; rat_negsmallest->pp.sign = -1;
DUMPRAWRAT(rat_smallest); DUMPRAWRAT(rat_smallest);
DUMPRAWRAT(rat_negsmallest); DUMPRAWRAT(rat_negsmallest);
@ -204,11 +204,11 @@ void ChangeConstants(uint32_t radix, int32_t precision)
subrat(&rat_max_i32, rat_one, precision); // rat_max_i32 = 2^31 -1 subrat(&rat_max_i32, rat_one, precision); // rat_max_i32 = 2^31 -1
DUMPRAWRAT(rat_max_i32); DUMPRAWRAT(rat_max_i32);
rat_min_i32->pp->sign *= -1; // rat_min_i32 = -2^31 rat_min_i32->pp.sign *= -1; // rat_min_i32 = -2^31
DUMPRAWRAT(rat_min_i32); DUMPRAWRAT(rat_min_i32);
DUPRAT(rat_min_exp, rat_max_exp); DUPRAT(rat_min_exp, rat_max_exp);
rat_min_exp->pp->sign *= -1; rat_min_exp->pp.sign *= -1;
DUMPRAWRAT(rat_min_exp); DUMPRAWRAT(rat_min_exp);
cbitsofprecision = g_ratio * radix * precision; cbitsofprecision = g_ratio * radix * precision;
@ -269,7 +269,7 @@ void ChangeConstants(uint32_t radix, int32_t precision)
DUPRAT(rat_smallest, rat_nRadix); DUPRAT(rat_smallest, rat_nRadix);
ratpowi32(&rat_smallest, -precision, precision); ratpowi32(&rat_smallest, -precision, precision);
DUPRAT(rat_negsmallest, rat_smallest); DUPRAT(rat_negsmallest, rat_smallest);
rat_negsmallest->pp->sign = -1; rat_negsmallest->pp.sign = -1;
} }
} }
@ -322,7 +322,7 @@ bool rat_equ( PRAT a, PRAT b, int32_t precision)
{ {
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
rattmp->pp->sign *= -1; rattmp->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
bool bret = zernum( rattmp->pp ); bool bret = zernum( rattmp->pp );
destroyrat( rattmp ); destroyrat( rattmp );
@ -345,11 +345,11 @@ bool rat_ge( PRAT a, PRAT b, int32_t precision)
{ {
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
b->pp->sign *= -1; b->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp.sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) ||
rattmp->pp->sign * rattmp->pq->sign == 1 ); rattmp->pp.sign * rattmp->pq.sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -371,11 +371,11 @@ bool rat_gt( PRAT a, PRAT b, int32_t precision)
{ {
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
b->pp->sign *= -1; b->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp.sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) &&
rattmp->pp->sign * rattmp->pq->sign == 1 ); rattmp->pp.sign * rattmp->pq.sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -397,11 +397,11 @@ bool rat_le( PRAT a, PRAT b, int32_t precision)
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
b->pp->sign *= -1; b->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp.sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) ||
rattmp->pp->sign * rattmp->pq->sign == -1 ); rattmp->pp.sign * rattmp->pq.sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -423,11 +423,11 @@ bool rat_lt( PRAT a, PRAT b, int32_t precision)
{ {
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
b->pp->sign *= -1; b->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp.sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) &&
rattmp->pp->sign * rattmp->pq->sign == -1 ); rattmp->pp.sign * rattmp->pq.sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -450,7 +450,7 @@ bool rat_neq( PRAT a, PRAT b, int32_t precision)
{ {
PRAT rattmp= nullptr; PRAT rattmp= nullptr;
DUPRAT(rattmp,a); DUPRAT(rattmp,a);
rattmp->pp->sign *= -1; rattmp->pp.sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
bool bret = !( zernum( rattmp->pp ) ); bool bret = !( zernum( rattmp->pp ) );
destroyrat( rattmp ); destroyrat( rattmp );
@ -475,8 +475,8 @@ void scale( PRAT *px, PRAT scalefact, uint32_t radix, int32_t precision )
// Logscale is a quick way to tell how much extra precision is needed for // Logscale is a quick way to tell how much extra precision is needed for
// scaling by scalefact. // scaling by scalefact.
int32_t logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - int32_t logscale = g_ratio * ( (pret->pp.cdigit+pret->pp.exp) -
(pret->pq->cdigit+pret->pq->exp) ); (pret->pq.cdigit+pret->pq.exp) );
if ( logscale > 0 ) if ( logscale > 0 )
{ {
precision += logscale; precision += logscale;
@ -485,7 +485,7 @@ void scale( PRAT *px, PRAT scalefact, uint32_t radix, int32_t precision )
divrat( &pret, scalefact, precision); divrat( &pret, scalefact, precision);
intrat(&pret, radix, precision); intrat(&pret, radix, precision);
mulrat( &pret, scalefact, precision); mulrat( &pret, scalefact, precision);
pret->pp->sign *= -1; pret->pp.sign *= -1;
addrat( px, pret, precision); addrat( px, pret, precision);
destroyrat( pret ); destroyrat( pret );
@ -510,8 +510,8 @@ void scale2pi( PRAT *px, uint32_t radix, int32_t precision )
// Logscale is a quick way to tell how much extra precision is needed for // Logscale is a quick way to tell how much extra precision is needed for
// scaling by 2 pi. // scaling by 2 pi.
int32_t logscale = g_ratio * ( (pret->pp->cdigit+pret->pp->exp) - int32_t logscale = g_ratio * ( (pret->pp.cdigit+pret->pp.exp) -
(pret->pq->cdigit+pret->pq->exp) ); (pret->pq.cdigit+pret->pq.exp) );
if ( logscale > 0 ) if ( logscale > 0 )
{ {
precision += logscale; precision += logscale;
@ -529,7 +529,7 @@ void scale2pi( PRAT *px, uint32_t radix, int32_t precision )
divrat( &pret, my_two_pi, precision); divrat( &pret, my_two_pi, precision);
intrat(&pret, radix, precision); intrat(&pret, radix, precision);
mulrat( &pret, my_two_pi, precision); mulrat( &pret, my_two_pi, precision);
pret->pp->sign *= -1; pret->pp.sign *= -1;
addrat( px, pret, precision); addrat( px, pret, precision);
destroyrat( my_two_pi ); destroyrat( my_two_pi );
@ -555,12 +555,12 @@ void inbetween( PRAT *px, PRAT range, int32_t precision)
} }
else else
{ {
range->pp->sign *= -1; range->pp.sign *= -1;
if ( rat_lt(*px, range, precision) ) if ( rat_lt(*px, range, precision) )
{ {
DUPRAT(*px,range); DUPRAT(*px,range);
} }
range->pp->sign *= -1; range->pp.sign *= -1;
} }
} }
@ -586,27 +586,27 @@ void _dumprawrat( const wchar_t *varname, PRAT rat, wostream& out)
// //
// FUNCTION: _dumprawnum // FUNCTION: _dumprawnum
// //
// ARGUMENTS: const wchar *name of variable, PNUMBER num, output stream out // ARGUMENTS: const wchar *name of variable, NUMBER num, output stream out
// //
// RETURN: none, prints the results of a dump of the internal structures // RETURN: none, prints the results of a dump of the internal structures
// of a PNUMBER, suitable for READRAWNUM to stderr. // of a NUMBER, suitable for READRAWNUM to stderr.
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void _dumprawnum(const wchar_t *varname, PNUMBER num, wostream& out) void _dumprawnum(const wchar_t *varname, NUMBER num, wostream& out)
{ {
int i; int i;
out << L"NUMBER " << varname << L" = {\n"; out << L"NUMBER " << varname << L" = {\n";
out << L"\t"<< num->sign << L",\n"; out << L"\t"<< num.sign << L",\n";
out << L"\t" << num->cdigit << L",\n"; out << L"\t" << num.cdigit << L",\n";
out << L"\t" << num->exp << L",\n"; out << L"\t" << num.exp << L",\n";
out << L"\t{ "; out << L"\t{ ";
for ( i = 0; i < num->cdigit; i++ ) for ( i = 0; i < num.cdigit; i++ )
{ {
out << L" "<< num->mant[i] << L","; out << L" "<< num.mant[i] << L",";
} }
out << L"}\n"; out << L"}\n";
out << L"};\n"; out << L"};\n";
@ -682,37 +682,37 @@ void trimit( PRAT *px, int32_t precision)
if ( !g_ftrueinfinite ) if ( !g_ftrueinfinite )
{ {
int32_t trim; int32_t trim;
PNUMBER pp=(*px)->pp; NUMBER pp=(*px)->pp;
PNUMBER pq=(*px)->pq; NUMBER pq=(*px)->pq;
trim = g_ratio * (min((pp->cdigit+pp->exp),(pq->cdigit+pq->exp))-1) - precision; trim = g_ratio * (min((pp.cdigit+pp.exp),(pq.cdigit+pq.exp))-1) - precision;
if ( trim > g_ratio ) if ( trim > g_ratio )
{ {
trim /= g_ratio; trim /= g_ratio;
if ( trim <= pp->exp ) if ( trim <= pp.exp )
{ {
pp->exp -= trim; pp.exp -= trim;
} }
else else
{ {
copy(pp->mant.begin() + (trim-pp->exp), pp->mant.begin() + pp->cdigit, pp->mant.begin()); copy(pp.mant.begin() + (trim-pp.exp), pp.mant.begin() + pp.cdigit, pp.mant.begin());
pp->cdigit -= trim-pp->exp; pp.cdigit -= trim-pp.exp;
pp->exp = 0; pp.exp = 0;
} }
if ( trim <= pq->exp ) if ( trim <= pq.exp )
{ {
pq->exp -= trim; pq.exp -= trim;
} }
else else
{ {
copy(pq->mant.begin() + (trim-pq->exp), pq->mant.begin() + pq->cdigit, pq->mant.begin()); copy(pq.mant.begin() + (trim-pq.exp), pq.mant.begin() + pq.cdigit, pq.mant.begin());
pq->cdigit -= trim-pq->exp; pq.cdigit -= trim-pq.exp;
pq->exp = 0; pq.exp = 0;
} }
} }
trim = min(pp->exp,pq->exp); trim = min(pp.exp,pq.exp);
pp->exp -= trim; pp.exp -= trim;
pq->exp -= trim; pq.exp -= trim;
} }
} }

View file

@ -77,7 +77,7 @@ void _sinrat( PRAT *px, int32_t precision)
DUPRAT(thisterm,*px); DUPRAT(thisterm,*px);
DUPNUM(n2,num_one); DUPNUM(n2,num_one);
xx->pp->sign *= -1; xx->pp.sign *= -1;
do { do {
NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);
@ -165,8 +165,6 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
CREATETAYLOR(); CREATETAYLOR();
destroynum(pret->pp);
destroynum(pret->pq);
pret->pp=i32tonum( 1L, radix); pret->pp=i32tonum( 1L, radix);
pret->pq=i32tonum( 1L, radix); pret->pq=i32tonum( 1L, radix);
@ -174,7 +172,7 @@ void _cosrat( PRAT *px, uint32_t radix, int32_t precision)
DUPRAT(thisterm,pret) DUPRAT(thisterm,pret)
n2=i32tonum(0L, radix); n2=i32tonum(0L, radix);
xx->pp->sign *= -1; xx->pp.sign *= -1;
do { do {
NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);

View file

@ -101,7 +101,7 @@ void sinhrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
DUPRAT(tmpx,*px); DUPRAT(tmpx,*px);
exprat(px, radix, precision); exprat(px, radix, precision);
tmpx->pp->sign *= -1; tmpx->pp.sign *= -1;
exprat(&tmpx, radix, precision); exprat(&tmpx, radix, precision);
subrat( px, tmpx, precision); subrat( px, tmpx, precision);
divrat( px, rat_two, precision); divrat( px, rat_two, precision);
@ -178,13 +178,13 @@ void coshrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
PRAT tmpx= nullptr; PRAT tmpx= nullptr;
(*px)->pp->sign = 1; (*px)->pp.sign = 1;
(*px)->pq->sign = 1; (*px)->pq.sign = 1;
if ( rat_ge( *px, rat_one, precision) ) if ( rat_ge( *px, rat_one, precision) )
{ {
DUPRAT(tmpx,*px); DUPRAT(tmpx,*px);
exprat(px, radix, precision); exprat(px, radix, precision);
tmpx->pp->sign *= -1; tmpx->pp.sign *= -1;
exprat(&tmpx, radix, precision); exprat(&tmpx, radix, precision);
addrat( px, tmpx, precision); addrat( px, tmpx, precision);
divrat( px, rat_two, precision); divrat( px, rat_two, precision);