calculator/src/CalcManager/Ratpack/itransh.cpp

154 lines
3.9 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//-----------------------------------------------------------------------------
// Package Title ratpak
// File itransh.c
// Copyright (C) 1995-97 Microsoft
// Date 01-16-95
//
//
// Description
//
// Contains inverse hyperbolic sin, cos, and tan functions.
//
// Special Information
//
//
//-----------------------------------------------------------------------------
#include "ratpak.h"
//-----------------------------------------------------------------------------
//
// FUNCTION: asinhrat
//
// ARGUMENTS: x PRAT representation of number to take the inverse
// hyperbolic sine of
// RETURN: asinh of x in PRAT form.
//
// EXPLANATION: This uses Taylor series
//
// n
// ___ 2 2
// \ ] -(2j+1) X
// \ thisterm ; where thisterm = thisterm * ---------
// / j j+1 j (2j+2)*(2j+3)
// /__]
// j=0
//
// thisterm = X ; and stop when thisterm < precision used.
// 0 n
//
// For abs(x) < .85, and
//
// asinh(x) = log(x+sqrt(x^2+1))
//
// For abs(x) >= .85
//
//-----------------------------------------------------------------------------
void asinhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{
PRAT neg_pt_eight_five = nullptr;
DUPRAT(neg_pt_eight_five, pt_eight_five);
neg_pt_eight_five->pp->sign *= -1;
if (rat_gt(*px, pt_eight_five, precision) || rat_lt(*px, neg_pt_eight_five, precision))
{
PRAT ptmp = nullptr;
DUPRAT(ptmp, (*px));
mulrat(&ptmp, *px, precision);
addrat(&ptmp, rat_one, precision);
rootrat(&ptmp, rat_two, radix, precision);
addrat(px, ptmp, precision);
lograt(px, precision);
destroyrat(ptmp);
}
else
{
CREATETAYLOR();
xx->pp->sign *= -1;
DUPRAT(pret, (*px));
DUPRAT(thisterm, (*px));
DUPNUM(n2, num_one);
do
{
NEXTTERM(xx, MULNUM(n2) MULNUM(n2) INC(n2) DIVNUM(n2) INC(n2) DIVNUM(n2), precision);
} while (!SMALL_ENOUGH_RAT(thisterm, precision));
DESTROYTAYLOR();
}
destroyrat(neg_pt_eight_five);
}
//-----------------------------------------------------------------------------
//
// FUNCTION: acoshrat
//
// ARGUMENTS: x PRAT representation of number to take the inverse
// hyperbolic cose of
// RETURN: acosh of x in PRAT form.
//
// EXPLANATION: This uses
//
// acosh(x)=ln(x+sqrt(x^2-1))
//
// For x >= 1
//
//-----------------------------------------------------------------------------
void acoshrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision)
{
if (rat_lt(*px, rat_one, precision))
{
throw CALC_E_DOMAIN;
}
else
{
PRAT ptmp = nullptr;
DUPRAT(ptmp, (*px));
mulrat(&ptmp, *px, precision);
subrat(&ptmp, rat_one, precision);
rootrat(&ptmp, rat_two, radix, precision);
addrat(px, ptmp, precision);
lograt(px, precision);
destroyrat(ptmp);
}
}
//-----------------------------------------------------------------------------
//
// FUNCTION: atanhrat
//
// ARGUMENTS: x PRAT representation of number to take the inverse
// hyperbolic tangent of
//
// RETURN: atanh of x in PRAT form.
//
// EXPLANATION: This uses
//
// 1 x+1
// atanh(x) = -*ln(----)
// 2 x-1
//
//-----------------------------------------------------------------------------
void atanhrat(_Inout_ PRAT* px, int32_t precision)
{
PRAT ptmp = nullptr;
DUPRAT(ptmp, (*px));
subrat(&ptmp, rat_one, precision);
addrat(px, rat_one, precision);
divrat(px, ptmp, precision);
(*px)->pp->sign *= -1;
lograt(px, precision);
divrat(px, rat_two, precision);
destroyrat(ptmp);
}