Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| // Copyright (c) Microsoft Corporation. All rights reserved. | |
| // Licensed under the MIT License. | |
| //----------------------------------------------------------------------------- | |
| // Package Title ratpak | |
| // File transh.c | |
| // Copyright (C) 1995-96 Microsoft | |
| // Date 01-16-95 | |
| // | |
| // | |
| // Description | |
| // | |
| // Contains hyperbolic sin, cos, and tan for rationals. | |
| // | |
| // | |
| //----------------------------------------------------------------------------- | |
| #include "pch.h" | |
| #include "ratpak.h" | |
| bool IsValidForHypFunc(PRAT px, int32_t precision) | |
| { | |
| PRAT ptmp = nullptr; | |
| bool bRet = true; | |
| DUPRAT(ptmp,rat_min_exp); | |
| divrat(&ptmp, rat_ten, precision); | |
| if ( rat_lt( px, ptmp, precision) ) | |
| { | |
| bRet = false; | |
| } | |
| destroyrat( ptmp ); | |
| return bRet; | |
| } | |
| //----------------------------------------------------------------------------- | |
| // | |
| // FUNCTION: sinhrat, _sinhrat | |
| // | |
| // ARGUMENTS: x PRAT representation of number to take the sine hyperbolic | |
| // of | |
| // RETURN: sinh of x in PRAT form. | |
| // | |
| // EXPLANATION: This uses Taylor series | |
| // | |
| // n | |
| // ___ 2j+1 | |
| // \ ] X | |
| // \ --------- | |
| // / (2j+1)! | |
| // /__] | |
| // j=0 | |
| // or, | |
| // n | |
| // ___ 2 | |
| // \ ] X | |
| // \ thisterm ; where thisterm = thisterm * --------- | |
| // / j j+1 j (2j)*(2j+1) | |
| // /__] | |
| // j=0 | |
| // | |
| // thisterm = X ; and stop when thisterm < precision used. | |
| // 0 n | |
| // | |
| // if x is bigger than 1.0 (e^x-e^-x)/2 is used. | |
| // | |
| //----------------------------------------------------------------------------- | |
| void _sinhrat( PRAT *px, int32_t precision) | |
| { | |
| if ( !IsValidForHypFunc(*px, precision)) | |
| { | |
| // Don't attempt exp of anything large or small | |
| throw( CALC_E_DOMAIN ); | |
| } | |
| CREATETAYLOR(); | |
| DUPRAT(pret,*px); | |
| DUPRAT(thisterm,pret); | |
| DUPNUM(n2,num_one); | |
| do { | |
| NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); | |
| } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); | |
| DESTROYTAYLOR(); | |
| } | |
| void sinhrat( PRAT *px, uint32_t radix, int32_t precision) | |
| { | |
| PRAT tmpx= nullptr; | |
| if ( rat_ge( *px, rat_one, precision) ) | |
| { | |
| DUPRAT(tmpx,*px); | |
| exprat(px, radix, precision); | |
| tmpx->pp->sign *= -1; | |
| exprat(&tmpx, radix, precision); | |
| subrat( px, tmpx, precision); | |
| divrat( px, rat_two, precision); | |
| destroyrat( tmpx ); | |
| } | |
| else | |
| { | |
| _sinhrat( px, precision); | |
| } | |
| } | |
| //----------------------------------------------------------------------------- | |
| // | |
| // FUNCTION: coshrat | |
| // | |
| // ARGUMENTS: x PRAT representation of number to take the cosine | |
| // hyperbolic of | |
| // | |
| // RETURN: cosh of x in PRAT form. | |
| // | |
| // EXPLANATION: This uses Taylor series | |
| // | |
| // n | |
| // ___ 2j | |
| // \ ] X | |
| // \ --------- | |
| // / (2j)! | |
| // /__] | |
| // j=0 | |
| // or, | |
| // n | |
| // ___ 2 | |
| // \ ] X | |
| // \ thisterm ; where thisterm = thisterm * --------- | |
| // / j j+1 j (2j)*(2j+1) | |
| // /__] | |
| // j=0 | |
| // | |
| // thisterm = 1 ; and stop when thisterm < precision used. | |
| // 0 n | |
| // | |
| // if x is bigger than 1.0 (e^x+e^-x)/2 is used. | |
| // | |
| //----------------------------------------------------------------------------- | |
| void _coshrat( PRAT *px, uint32_t radix, int32_t precision) | |
| { | |
| if ( !IsValidForHypFunc(*px, precision)) | |
| { | |
| // Don't attempt exp of anything large or small | |
| throw( CALC_E_DOMAIN ); | |
| } | |
| CREATETAYLOR(); | |
| pret->pp=longtonum( 1L, radix); | |
| pret->pq=longtonum( 1L, radix); | |
| DUPRAT(thisterm,pret) | |
| n2=longtonum(0L, radix); | |
| do { | |
| NEXTTERM(xx,INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision); | |
| } while ( !SMALL_ENOUGH_RAT( thisterm, precision) ); | |
| DESTROYTAYLOR(); | |
| } | |
| void coshrat( PRAT *px, uint32_t radix, int32_t precision) | |
| { | |
| PRAT tmpx= nullptr; | |
| (*px)->pp->sign = 1; | |
| (*px)->pq->sign = 1; | |
| if ( rat_ge( *px, rat_one, precision) ) | |
| { | |
| DUPRAT(tmpx,*px); | |
| exprat(px, radix, precision); | |
| tmpx->pp->sign *= -1; | |
| exprat(&tmpx, radix, precision); | |
| addrat( px, tmpx, precision); | |
| divrat( px, rat_two, precision); | |
| destroyrat( tmpx ); | |
| } | |
| else | |
| { | |
| _coshrat( px, radix, precision); | |
| } | |
| // Since *px might be epsilon below 1 due to TRIMIT | |
| // we need this trick here. | |
| if ( rat_lt(*px, rat_one, precision) ) | |
| { | |
| DUPRAT(*px,rat_one); | |
| } | |
| } | |
| //----------------------------------------------------------------------------- | |
| // | |
| // FUNCTION: tanhrat | |
| // | |
| // ARGUMENTS: x PRAT representation of number to take the tangent | |
| // hyperbolic of | |
| // | |
| // RETURN: tanh of x in PRAT form. | |
| // | |
| // EXPLANATION: This uses sinhrat and coshrat | |
| // | |
| //----------------------------------------------------------------------------- | |
| 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); | |
| } |