Beispiel #1
0
void tanhrat(PRAT* px, uint32_t radix, int32_t precision)

{
    PRAT ptmp = nullptr;

    DUPRAT(ptmp, *px);
    sinhrat(px, radix, precision);
    coshrat(&ptmp, radix, precision);
    mulnumx(&((*px)->pp), ptmp->pq);
    mulnumx(&((*px)->pq), ptmp->pp);

    destroyrat(ptmp);
}
Beispiel #2
0
void _gamma( PRAT *pn, uint32_t radix, int32_t precision)

{
    PRAT factorial= nullptr;
    PNUMBER count= nullptr;
    PRAT tmp= nullptr;
    PRAT one_pt_five= nullptr;
    PRAT a= nullptr;
    PRAT a2= nullptr;
    PRAT term= nullptr;
    PRAT sum= nullptr;
    PRAT err= nullptr;
    PRAT mpy= nullptr;
    PRAT ratprec = nullptr;
    PRAT ratRadix = nullptr;
    long oldprec;
    
    // Set up constants and initial conditions
    oldprec = precision;
    ratprec = longtorat( oldprec );
    
    // Find the best 'A' for convergence to the required precision.
    a=longtorat( radix );
    lograt(&a, precision);
    mulrat(&a, ratprec, precision);

    // Really is -ln(n)+1, but -ln(n) will be < 1 
    // if we scale n between 0.5 and 1.5
    addrat(&a, rat_two, precision);
    DUPRAT(tmp,a);
    lograt(&tmp, precision);
    mulrat(&tmp, *pn, precision);
    addrat(&a, tmp, precision);
    addrat(&a, rat_one, precision);
    
    // Calculate the necessary bump in precision and up the precision.
    // The following code is equivalent to 
    // precision += ln(exp(a)*pow(a,n+1.5))-ln(radix));
    DUPRAT(tmp,*pn);
    one_pt_five=longtorat( 3L );
    divrat( &one_pt_five, rat_two, precision);
    addrat( &tmp, one_pt_five, precision);
    DUPRAT(term,a);
    powratcomp( &term, tmp, radix, precision);
    DUPRAT( tmp, a );
    exprat( &tmp, radix, precision);
    mulrat( &term, tmp, precision);
    lograt( &term, precision);
    ratRadix = longtorat(radix);
    DUPRAT(tmp,ratRadix);
    lograt( &tmp, precision);
    subrat( &term, tmp, precision);
    precision += rattolong( term, radix, precision);
    
    // Set up initial terms for series, refer to series in above comment block.
    DUPRAT(factorial,rat_one); // Start factorial out with one
    count = longtonum( 0L, BASEX );

    DUPRAT(mpy,a);
    powratcomp(&mpy,*pn, radix, precision);
    // a2=a^2
    DUPRAT(a2,a);
    mulrat(&a2, a, precision);
    
    // sum=(1/n)-(a/(n+1))
    DUPRAT(sum,rat_one);
    divrat(&sum, *pn, precision);
    DUPRAT(tmp,*pn);
    addrat(&tmp, rat_one, precision);
    DUPRAT(term,a);
    divrat(&term, tmp, precision);
    subrat(&sum, term, precision);

    DUPRAT(err,ratRadix);
    NEGATE(ratprec);
    powratcomp(&err,ratprec, radix, precision);
    divrat(&err, ratRadix, precision);

    // Just get something not tiny in term
    DUPRAT(term, rat_two );    

    // Loop until precision is reached, or asked to halt.
    while ( !zerrat( term ) && rat_gt( term, err, precision) )
        {
        addrat(pn, rat_two, precision);
        
        // WARNING: mixing numbers and  rationals here.  
        // for speed and efficiency.
        INC(count);
        mulnumx(&(factorial->pp),count);
        INC(count)
        mulnumx(&(factorial->pp),count);

        divrat(&factorial, a2, precision);

        DUPRAT(tmp,*pn);
        addrat( &tmp, rat_one, precision);
        destroyrat(term);
        createrat(term);
        DUPNUM(term->pp,count);
        DUPNUM(term->pq,num_one);
        addrat( &term, rat_one, precision);
        mulrat( &term, tmp, precision);
        DUPRAT(tmp,a);
        divrat( &tmp, term, precision);

        DUPRAT(term,rat_one);
        divrat( &term, *pn, precision);
        subrat( &term, tmp, precision);
        
        divrat (&term, factorial, precision);
        addrat( &sum, term, precision);
        ABSRAT(term);
        }
    
    // Multiply by factor.
    mulrat( &sum, mpy, precision);
    
    // And cleanup
    precision = oldprec;
    destroyrat(ratprec);
    destroyrat(err);
    destroyrat(term);
    destroyrat(a);
    destroyrat(a2);
    destroyrat(tmp);
    destroyrat(one_pt_five);

    destroynum(count);

    destroyrat(factorial);
    destroyrat(*pn);
    DUPRAT(*pn,sum);
    destroyrat(sum);
}