00001 using System;
00002 using System.Collections.Generic;
00003
00004
00005 namespace StephenAshley.Biostatistics
00006 {
00011 public sealed class DecMath
00012 {
00013 private DecMath() { }
00014
00020 public const Decimal PI = 3.1415926535897932384626433833m;
00021
00026 public const Decimal e = 2.71828182845904523536028747m;
00027
00033 public static Decimal Abs(Decimal value)
00034 {
00035 if (value < 0m)
00036 return -1.0m * value;
00037 else return value;
00038 }
00039
00056 public static Decimal Atan(Decimal angle)
00057 {
00058 return new Decimal(Math.Atan(Decimal.ToDouble(angle)));
00059 }
00060
00066 public static Decimal Cos(Decimal angle)
00067 {
00068 return new Decimal(Math.Cos(Decimal.ToDouble(angle)));
00069 }
00070
00071
00081 public static Decimal Exp(Decimal value)
00082 {
00083 return new Decimal(Math.Exp(Decimal.ToDouble(value)));
00084 }
00085
00091 public static double Factorial(Int32 value)
00092 {
00093
00094
00095
00096 double Result = (double)value;
00097
00098 for (Int32 i = value - 1; i > 0; i--)
00099 Result *= (double) i;
00100 return Result;
00101 }
00102
00110 public static Decimal Pow(Decimal value, Int32 power)
00111 {
00112 if (power < 1)
00113 throw new ArgumentException("power must be greater than 1.", "power");
00114 Decimal A = 1.0m;
00115 for (Int32 i = power; i > 0; i--)
00116 A = A * value;
00117 return A;
00118 }
00119
00127 public static Decimal Pow(Decimal value, Int64 power)
00128 {
00129 if (power < 1)
00130 throw new ArgumentException("power must be greater than 1.", "power");
00131 Decimal A = 1.0m;
00132 for (Int64 i = power; i > 0; i--)
00133 A = A * value;
00134 return A;
00135 }
00136
00137
00138
00139
00140
00141
00142
00155 public static bool IsDecimal(string value)
00156 {
00157 try
00158 {
00159 Decimal decTemp = Convert.ToDecimal(value);
00160 }
00161 catch (FormatException)
00162 {
00163 return false;
00164 }
00165 catch (OverflowException)
00166 {
00167 throw;
00168 }
00169 return true;
00170 }
00171
00178
00179
00180
00181
00182
00183
00184
00191 public static bool IsEven(Int32 value)
00192 {
00193 Int32 result;
00194 Math.DivRem(value, 2, out result);
00195 if (result == 0)
00196 return true;
00197 else return false;
00198 }
00199
00206
00207
00208
00209
00210
00211
00212
00219 public static bool IsOdd(Int32 value)
00220 {
00221 Int32 result;
00222 Math.DivRem(value, 2, out result);
00223 if (result != 0)
00224 return true;
00225 else return false;
00226 }
00227
00239 public static Decimal Log(Decimal value)
00240 {
00241 return new Decimal(Math.Log(Decimal.ToDouble(value)));
00242 }
00248
00249 public static Decimal Log10(Decimal value)
00250 {
00251 return new Decimal(Math.Log10(Decimal.ToDouble(value)));
00252 }
00253
00259 public static Decimal Sin(Decimal angle)
00260 {
00261 return new Decimal(Math.Sin(Decimal.ToDouble(angle)));
00262 }
00263
00271 public static Decimal Sqrt(Decimal value)
00272 {
00273 if (value == 1m)
00274 return 1m;
00275
00276 if (value == 0m)
00277 return 0m;
00278
00279 if (value < 0m)
00280 throw new ArgumentException(
00281 "Argument to Sqrt method must be greater than or equal to 0.");
00282
00283 Decimal decGuess = (Decimal)(Math.Sqrt(Decimal.ToDouble(value)));
00284 Decimal decTooBig;
00285 Decimal decTooSmall;
00286 if (value > 1m)
00287 {
00288 decTooBig = value;
00289 decTooSmall = 1m;
00290 }
00291 else
00292 {
00293 decTooBig = 1m;
00294 decTooSmall = 0m;
00295 }
00296 return SquareRoot(value, decTooSmall, decTooBig,
00297 decGuess);
00298 }
00299
00300 private static Decimal SquareRoot(Decimal decSubject,
00301 Decimal decLowEnd, Decimal decHighEnd, Decimal decNextGuess)
00302 {
00303 Int32 iCount = 0;
00304 while (iCount < 1000)
00305 {
00306 checked
00307 {
00308 Decimal decTrial = decNextGuess * decNextGuess;
00309
00310 if (decTrial == decSubject)
00311 return decNextGuess;
00312 else if (decTrial > decSubject)
00313 decHighEnd = decNextGuess;
00314 else
00315 decLowEnd = decNextGuess;
00316
00317 decNextGuess = (decLowEnd + decHighEnd) / 2m;
00318 iCount++;
00319 }
00320 }
00321 return decNextGuess;
00322 }
00323
00330 public static Decimal KahanSum(Decimal[] values)
00331 {
00332 if (values.Length == 0)
00333 return 0m;
00334 Decimal decSum = values[0];
00335 Decimal decCorrection = 0m;
00336 Decimal decCorrectedNextTerm,
00337 decNewSum;
00338
00339 for (Int32 i = 1; i < values.Length; i++)
00340 {
00341 decCorrectedNextTerm = values[i] - decCorrection;
00342 decNewSum = decSum + decCorrectedNextTerm;
00343 decCorrection = decNewSum - decSum;
00344 decCorrection = decCorrection - decCorrectedNextTerm;
00345 decSum = decNewSum;
00346 }
00347 return decSum;
00348 }
00349
00356 public static Decimal KahanSum(List<Decimal> values)
00357 {
00358 return KahanSum(values.ToArray());
00359 }
00360 }
00361 }