public static void Main()
decimal const2 = 0.6215m;
decimal const3 = 0.4275m;
BigDecimal output = BigDecimal.Pow((double)wind_speed, const5);
BigDecimal wind_chill = const1 + const2 * temp + (const3 * temp - const4) * output;
Console.WriteLine("Decimal: {0}", wind_chill);
public struct BigDecimal : IComparable, IComparable<BigDecimal>
public static bool AlwaysTruncate = false;
public static int Precision = 50;
public BigInteger Mantissa
public BigDecimal(BigInteger mantissa, int exponent): this ()
BigInteger remainder = 0;
var shortened = BigInteger.DivRem(Mantissa, 10, out remainder);
public BigDecimal Truncate(int precision)
while (NumberOfDigits(shortened.Mantissa) > precision)
shortened.Mantissa /= 10;
public BigDecimal Truncate()
return Truncate(Precision);
private static int NumberOfDigits(BigInteger value)
return (int)Math.Ceiling(BigInteger.Log10(value * value.Sign));
public static implicit operator BigDecimal(int value)
return new BigDecimal(value, 0);
public static implicit operator BigDecimal(double value)
var mantissa = (BigInteger)value;
while (Math.Abs(value * scaleFactor - (double)mantissa) > 0)
mantissa = (BigInteger)(value * scaleFactor);
return new BigDecimal(mantissa, exponent);
public static implicit operator BigDecimal(decimal value)
var mantissa = (BigInteger)value;
while ((decimal)mantissa != value * scaleFactor)
mantissa = (BigInteger)(value * scaleFactor);
return new BigDecimal(mantissa, exponent);
public static explicit operator double (BigDecimal value)
return (double)value.Mantissa * Math.Pow(10, value.Exponent);
public static explicit operator float (BigDecimal value)
return Convert.ToSingle((double)value);
public static explicit operator decimal (BigDecimal value)
return (decimal)value.Mantissa * (decimal)Math.Pow(10, value.Exponent);
public static explicit operator int (BigDecimal value)
return (int)(value.Mantissa * BigInteger.Pow(10, value.Exponent));
public static explicit operator uint (BigDecimal value)
return (uint)(value.Mantissa * BigInteger.Pow(10, value.Exponent));
public static BigDecimal operator +(BigDecimal value)
public static BigDecimal operator -(BigDecimal value)
public static BigDecimal operator ++(BigDecimal value)
public static BigDecimal operator --(BigDecimal value)
public static BigDecimal operator +(BigDecimal left, BigDecimal right)
public static BigDecimal operator -(BigDecimal left, BigDecimal right)
return Add(left, -right);
private static BigDecimal Add(BigDecimal left, BigDecimal right)
return left.Exponent > right.Exponent ? new BigDecimal(AlignExponent(left, right) + right.Mantissa, right.Exponent) : new BigDecimal(AlignExponent(right, left) + left.Mantissa, left.Exponent);
public static BigDecimal operator *(BigDecimal left, BigDecimal right)
return new BigDecimal(left.Mantissa * right.Mantissa, left.Exponent + right.Exponent);
public static BigDecimal operator /(BigDecimal dividend, BigDecimal divisor)
var exponentChange = Precision - (NumberOfDigits(dividend.Mantissa) - NumberOfDigits(divisor.Mantissa));
dividend.Mantissa *= BigInteger.Pow(10, exponentChange);
return new BigDecimal(dividend.Mantissa / divisor.Mantissa, dividend.Exponent - divisor.Exponent - exponentChange);
public static bool operator ==(BigDecimal left, BigDecimal right)
return left.Exponent == right.Exponent && left.Mantissa == right.Mantissa;
public static bool operator !=(BigDecimal left, BigDecimal right)
return left.Exponent != right.Exponent || left.Mantissa != right.Mantissa;
public static bool operator <(BigDecimal left, BigDecimal right)
return left.Exponent > right.Exponent ? AlignExponent(left, right) < right.Mantissa : left.Mantissa < AlignExponent(right, left);
public static bool operator>(BigDecimal left, BigDecimal right)
return left.Exponent > right.Exponent ? AlignExponent(left, right) > right.Mantissa : left.Mantissa > AlignExponent(right, left);
public static bool operator <=(BigDecimal left, BigDecimal right)
return left.Exponent > right.Exponent ? AlignExponent(left, right) <= right.Mantissa : left.Mantissa <= AlignExponent(right, left);
public static bool operator >=(BigDecimal left, BigDecimal right)
return left.Exponent > right.Exponent ? AlignExponent(left, right) >= right.Mantissa : left.Mantissa >= AlignExponent(right, left);
private static BigInteger AlignExponent(BigDecimal value, BigDecimal reference)
return value.Mantissa * BigInteger.Pow(10, value.Exponent - reference.Exponent);
#region Additional mathematical functions
public static BigDecimal Exp(double exponent)
while (Math.Abs(exponent) > 100)
var diff = exponent > 0 ? 100 : -100;
return tmp * Math.Exp(exponent);
public static BigDecimal Pow(double basis, double exponent)
while (Math.Abs(exponent) > 100)
var diff = exponent > 0 ? 100 : -100;
tmp *= Math.Pow(basis, diff);
return tmp * Math.Pow(basis, exponent);
public override string ToString()
return string.Concat(Mantissa.ToString(), "E", Exponent);
public bool Equals(BigDecimal other)
return other.Mantissa.Equals(Mantissa) && other.Exponent == Exponent;
public override bool Equals(object obj)
if (ReferenceEquals(null, obj))
return obj is BigDecimal && Equals((BigDecimal)obj);
public override int GetHashCode()
return (Mantissa.GetHashCode() * 397) ^ Exponent;
public int CompareTo(object obj)
if (ReferenceEquals(obj, null) || !(obj is BigDecimal))
throw new ArgumentException();
return CompareTo((BigDecimal)obj);
public int CompareTo(BigDecimal other)
return this < other ? -1 : (this > other ? 1 : 0);