Add this to
BigNumber
#region Trig Functions
public BigNumber Acos(int places)
{
BigNumber val = ArcCosUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Asin(int places)
{
BigNumber val = ArcSinUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Atan()
{
BigNumber val = ArcTanUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Round(val, res, numDefaultPlaces);
return res;
}
public BigNumber Atan(int places)
{
BigNumber val = ArcTanUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Cos()
{
BigNumber val = CosUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Round(val, res, numDefaultPlaces);
return res;
}
public BigNumber Cos(int places)
{
BigNumber val = CosUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Cot()
{
BigNumber val = TanUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Round(val, res, numDefaultPlaces);
return res;
}
public BigNumber Cot(int places)
{
BigNumber val = CotUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Csc()
{
BigNumber sin = SinUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Div(One, sin, res, numDefaultPlaces);
return res;
}
public BigNumber Csc(int places)
{
BigNumber sin = SinUsingTaylorSeries(this, places);
BigNumber res = 0;
Div(One, sin, res, numDefaultPlaces);
return res;
}
public BigNumber Sec()
{
BigNumber cos = CosUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Div(One, cos, res, numDefaultPlaces);
return res;
}
public BigNumber Sec(int places)
{
BigNumber cos = CosUsingTaylorSeries(this, places);
BigNumber res = 0;
Div(One, cos, res, numDefaultPlaces);
return res;
}
public BigNumber Sin()
{
BigNumber val = SinUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Round(val, res, numDefaultPlaces);
return res;
}
public BigNumber Sin(int places)
{
BigNumber val = SinUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
public BigNumber Tan()
{
BigNumber val = TanUsingTaylorSeries(this, numDefaultPlaces);
BigNumber res = 0;
Round(val, res, numDefaultPlaces);
return res;
}
public BigNumber Tan(int places)
{
BigNumber val = TanUsingTaylorSeries(this, places);
BigNumber res = 0;
Round(val, res, places);
return res;
}
#endregion Trig Functions
Add this new class
namespace BigNumbers
{
public partial class BigNumber
{
private static readonly BigNumber c2Pi = BN_PI * 2.0;
private static readonly BigNumber cPiOver2 = BN_PI / 2.0;
public static BigNumber SinUsingTaylorSeries(BigNumber radian, int places)
{
radian = CorrectRadian(radian, places);
BigNumber result = radian;
BigNumber factorialResult = 3.0 * 2.0;
int factorial = 4;
BigNumber doubleRadian = radian * radian;
BigNumber multiple = radian * doubleRadian;
BigNumber prevResult = 0;
var divResult = new BigNumber();
multiple = multiple.Neg();
int counter = (int)(places * 5);
for (int i = 0; i < counter; i++)
{
Div(multiple, factorialResult, divResult, places);
result += divResult;
multiple *= doubleRadian.Neg();
int tmp = (factorial + 1) * factorial;
factorialResult *= tmp;
factorial += 2;
BigNumber tmpResult = result.Round(places);
if (prevResult == tmpResult)
break;
prevResult = tmpResult;
}
return result;
}
public static BigNumber CosUsingTaylorSeries(BigNumber radian, int places)
{
radian = CorrectRadian(radian, places);
BigNumber result = 1;
BigNumber factorialResult = 2.0;
int factorial = 3;
BigNumber doubleRadian = radian * radian;
BigNumber multiple = doubleRadian;
multiple = multiple.Neg();
var divResult = new BigNumber();
BigNumber prevResult = 0;
int counter = (int)(places * 5);
for (int i = 0; i < counter; i++)
{
Div(multiple, factorialResult, divResult, places);
result += divResult;
multiple *= doubleRadian.Neg();
int tmp = (factorial + 1) * factorial;
factorialResult *= tmp;
factorial += 2;
BigNumber tmpResult = result.Round(places);
if (prevResult == tmpResult)
break;
prevResult = tmpResult;
}
return result;
}
public static BigNumber TanUsingTaylorSeries(BigNumber radian, int places)
{
radian = CorrectRadian(radian, places);
BigNumber result = 0;
BigNumber doubleRadian = radian * radian;
BigNumber prevCosResult = 0;
BigNumber prevSinResult = 0;
BigNumber cosResult = 1;
BigNumber cosFactorialResult = 2.0;
int factorial = 3;
BigNumber cosMultiple = doubleRadian;
cosMultiple = cosMultiple.Neg();
BigNumber sinResult = radian;
BigNumber sinFactorialResult = 3.0 * 2.0;
BigNumber sinMultiple = radian * doubleRadian;
var divResult = new BigNumber();
sinMultiple = sinMultiple.Neg();
int counter = (int)(places * 5);
for (int i = 0; i < counter; i++)
{
Div(sinMultiple, sinFactorialResult, divResult, places);
sinResult += divResult;
Div(cosMultiple, cosFactorialResult, divResult, places);
cosResult += divResult;
BigNumber negDoubleRadian = doubleRadian.Neg();
sinMultiple *= negDoubleRadian;
cosMultiple *= negDoubleRadian;
int factPlusOne = factorial + 1;
int factPlusTwo = factPlusOne + 1;
int cosTmp = factPlusOne * factorial;
cosFactorialResult *= cosTmp;
int sinTmp = factPlusTwo * factPlusOne;
sinFactorialResult *= sinTmp;
factorial += 2;
BigNumber tmpCosResult = cosResult.Round(100);
BigNumber tmpSinResult = sinResult.Round(100);
if (tmpCosResult == 0)
break;
if ((prevSinResult == tmpSinResult) && (prevCosResult == tmpCosResult))
break;
prevCosResult = tmpCosResult;
prevSinResult = tmpSinResult;
}
Div(sinResult, cosResult, result, places);
return result;
}
public static BigNumber CotUsingTaylorSeries(BigNumber radian, int places)
{
radian = CorrectRadian(radian, places);
BigNumber result = 0;
BigNumber doubleRadian = radian * radian;
BigNumber prevCosResult = 0;
BigNumber prevSinResult = 0;
BigNumber cosResult = 1;
BigNumber cosFactorialResult = 2.0;
int factorial = 3;
BigNumber cosMultiple = doubleRadian;
cosMultiple = cosMultiple.Neg();
BigNumber sinResult = radian;
BigNumber sinFactorialResult = 3.0 * 2.0;
BigNumber sinMultiple = radian * doubleRadian;
var divResult = new BigNumber();
int counter = (int)(places * 5);
sinMultiple = sinMultiple.Neg();
for (int i = 0; i < counter; i++)
{
Div(sinMultiple, sinFactorialResult, divResult, places);
sinResult += divResult;
Div(cosMultiple, cosFactorialResult, divResult, places);
cosResult += divResult;
BigNumber negDoubleRadian = doubleRadian.Neg();
sinMultiple *= negDoubleRadian;
cosMultiple *= negDoubleRadian;
int factPlusOne = factorial + 1;
int factPlusTwo = factPlusOne + 1;
int cosTmp = factPlusOne * factorial;
cosFactorialResult *= cosTmp;
int sinTmp = factPlusTwo * factPlusOne;
sinFactorialResult *= sinTmp;
factorial += 2;
BigNumber tmpCosResult = cosResult.Round(100);
BigNumber tmpSinResult = sinResult.Round(100);
if (tmpCosResult == 0)
break;
if ((prevSinResult == tmpSinResult) && (prevCosResult == tmpCosResult))
break;
prevCosResult = tmpCosResult;
prevSinResult = tmpSinResult;
}
Div(cosResult, sinResult, result, places);
return result;
}
public static BigNumber ArcSinUsingTaylorSeries(BigNumber value, int places)
{
bool isNegative = value < 0;
if (isNegative)
value = value.Neg();
bool useInverseValue = value > 1;
if (useInverseValue)
{
BigNumber tmp = 0;
Div(One, value, tmp, SignificantDigits(value));
value = tmp;
}
BigNumber prevResult = 0;
int c = 1;
BigNumber abRatio = (BigNumber)0.5m;
int n = 3;
BigNumber doubleValue = value * value;
BigNumber multiple = value * doubleValue;
var tmpA = new BigNumber();
var tmpB = new BigNumber();
Mul(abRatio, multiple, tmpA);
Div(tmpA, n, tmpB, places);
BigNumber result = value + tmpB;
int counter = (int)(places * 10);
for (int i = 0; i < counter; i++)
{
c += 2;
n += 2;
var tmp1 = new BigNumber();
var tmp2 = new BigNumber();
Div(c, (1 + c), tmp1, places);
Mul(abRatio, tmp1, tmp2);
abRatio = tmp2;
var tmp3 = new BigNumber();
Mul(multiple, doubleValue, tmp3);
multiple = tmp3;
var tmp4 = new BigNumber();
var tmp5 = new BigNumber();
Mul(abRatio, multiple, tmp4);
Div(tmp4, n, tmp5, places);
result += tmp5;
result = result.Round(places);
if (result == prevResult)
break;
prevResult = result;
}
if (isNegative)
result = result.Neg();
return result;
}
public static BigNumber ArcCosUsingTaylorSeries(BigNumber value, int places)
{
return cPiOver2 - ArcSinUsingTaylorSeries(value, places);
}
public static BigNumber ArcTanUsingTaylorSeries(BigNumber value, int places)
{
bool isNegative = value < 0;
if (isNegative)
value = value.Neg();
bool useInverseValue = value > 1;
if (useInverseValue)
{
BigNumber tmp = 0;
Div(One, value, tmp, SignificantDigits(value));
value = tmp;
}
BigNumber prevResult = 0;
BigNumber result = value;
int factorial = 3;
BigNumber doubleValue = value * value;
BigNumber multiple = value.Neg() * doubleValue;
int counter = (int)(places * 5);
var divResult = new BigNumber();
for (int i = 0; i < counter; i++)
{
BigNumber factorialResult = factorial;
Div(multiple, factorialResult, divResult, places);
result += divResult;
multiple *= doubleValue.Neg();
factorial += 2;
BigNumber tmpResult = result.Round(places);
if (tmpResult == prevResult)
break;
prevResult = tmpResult;
}
if (useInverseValue)
{
Div(BN_PI, Two, divResult, places);
result = divResult - result;
}
if (isNegative)
result = result.Neg();
return result;
}
#region Private Methods
public static BigNumber CorrectRadian(BigNumber radian, int places)
{
if ((radian < 0) || (radian > c2Pi))
{
var tmp = radian / c2Pi;
var wholePart = tmp.Floor();
var fracPart = tmp - wholePart;
radian = fracPart * c2Pi;
radian = radian.Round(places);
}
return radian;
}
#endregion Private Methods
}
}
|