public static SybaseBoolean operator <=(SybaseDecimal x, SybaseDecimal y) { if (x.IsNull || y.IsNull) { return(SybaseBoolean.Null); } if (x.Scale > y.Scale) { x = SybaseDecimal.AdjustScale(x, y.Scale - x.Scale, true); } else if (y.Scale > x.Scale) { y = SybaseDecimal.AdjustScale(y, x.Scale - y.Scale, true); } for (int i = 3; i >= 0; i -= 1) { if (x.Data[i] == 0 && y.Data[i] == 0) { continue; } else { return(new SybaseBoolean(x.Data[i] <= y.Data[i])); } } return(new SybaseBoolean(true)); }
public static SybaseBoolean operator !=(SybaseDecimal x, SybaseDecimal y) { if (x.IsNull || y.IsNull) { return(SybaseBoolean.Null); } if (x.Scale > y.Scale) { x = SybaseDecimal.AdjustScale(x, y.Scale - x.Scale, true); } else if (y.Scale > x.Scale) { y = SybaseDecimal.AdjustScale(y, x.Scale - y.Scale, true); } for (int i = 0; i < 4; i += 1) { if (x.Data[i] != y.Data[i]) { return(new SybaseBoolean(true)); } } return(new SybaseBoolean(false)); }
public static SybaseDecimal Power(SybaseDecimal n, double exp) { if (n.IsNull) { return(SybaseDecimal.Null); } return(new SybaseDecimal(System.Math.Pow(n.ToDouble(), exp))); }
public static SybaseDecimal Round(SybaseDecimal n, int position) { if (n.IsNull) { throw new SybaseNullValueException(); } SybaseDecimal result = new SybaseDecimal(System.Math.Round((double)(n.ToDouble() * System.Math.Pow(10, position)))); result = result / new SybaseDecimal(System.Math.Pow(10, position)); return(result); }
public static SybaseDecimal operator *(SybaseDecimal x, SybaseDecimal y) { // adjust the scale to the smaller of the two beforehand if (x.Scale > y.Scale) { x = SybaseDecimal.AdjustScale(x, y.Scale - x.Scale, true); } else if (y.Scale > x.Scale) { y = SybaseDecimal.AdjustScale(y, x.Scale - y.Scale, true); } // set the precision to the greater of the two byte resultPrecision; if (x.Precision > y.Precision) { resultPrecision = x.Precision; } else { resultPrecision = y.Precision; } int[] xData = x.Data; int[] yData = y.Data; int[] resultBits = new int[4]; ulong res; ulong carry = 0; // multiply one at a time, and carry the results over to the next for (int i = 0; i < 4; i += 1) { carry = 0; res = (ulong)(xData[i]) * (ulong)(yData[i]) + carry; if (res > Int32.MaxValue) { carry = res - Int32.MaxValue; res = Int32.MaxValue; } resultBits [i] = (int)res; } // if we have carry left, then throw an exception if (carry > 0) { throw new OverflowException(); } else { return(new SybaseDecimal(resultPrecision, x.Scale, (x.IsPositive == y.IsPositive), resultBits)); } }
public static SybaseInt32 Sign(SybaseDecimal n) { SybaseInt32 result = 0; if (n >= new SybaseDecimal(0)) { result = 1; } else { result = -1; } return(result); }
private static SybaseDecimal DecimalDiv(SybaseDecimal x, SybaseDecimal y) { ulong lo = 0; ulong hi = 0; int sc = 0; // scale int texp = 0; byte prec = 0; prec = x.Precision >= y.Precision ? x.Precision : y.Precision; DecimalDivSub(ref x, ref y, ref lo, ref hi, ref texp); sc = x.Scale - y.Scale; Rescale128(ref lo, ref hi, ref sc, texp, 0, 38, 1); uint r = 0; while (prec < sc) { Div128By32(ref hi, ref lo, 10, ref r); sc -= 1; } if (r >= 5) { lo += 1; } while ((((double)hi) * System.Math.Pow(2, 64) + lo) - System.Math.Pow(10, prec) > 0) { prec += 1; } while ((prec + sc) > MaxScale) { Div128By32(ref hi, ref lo, 10, ref r); sc -= 1; if (r >= 5) { lo += 1; } } int resultLo = (int)lo; int resultMi = (int)(lo >> 32); int resultMi2 = (int)hi; int resultHi = (int)(hi >> 32); return(new SybaseDecimal(prec, (byte)sc, true, resultLo, resultMi, resultMi2, resultHi)); }
public static SybaseDecimal AdjustScale(SybaseDecimal n, int digits, bool fRound) { byte prec = n.Precision; if (n.IsNull) { throw new SybaseNullValueException(); } if (digits > 0) { prec = (byte)(prec + digits); } if (fRound) { n = Round(n, digits + n.Scale); } return(new SybaseDecimal(prec, (byte)(n.Scale + digits), n.IsPositive, n.Data)); }
public static SybaseDecimal operator -(SybaseDecimal x, SybaseDecimal y) { if (x.IsPositive && !y.IsPositive) { return(x + y); } if (!x.IsPositive && y.IsPositive) { return(-(x + y)); } if (!x.IsPositive && !y.IsPositive) { return(y - x); } // otherwise, x is positive and y is positive bool resultPositive = (bool)(x > y); int[] yData = y.Data; for (int i = 0; i < 4; i += 1) { yData[i] = -yData[i]; } SybaseDecimal yInverse = new SybaseDecimal(y.Precision, y.Scale, y.IsPositive, yData); if (resultPositive) { return(x + yInverse); } else { return(-(x + yInverse)); } }
public static SybaseBoolean GreaterThan (SybaseDecimal x, SybaseDecimal y) { return (x > y); }
public static SybaseBoolean LessThan(SybaseDecimal x, SybaseDecimal y) { return(x < y); }
public static SybaseBoolean GreaterThan(SybaseDecimal x, SybaseDecimal y) { return(x > y); }
public static SybaseDecimal Divide(SybaseDecimal x, SybaseDecimal y) { return(x / y); }
public static SybaseDecimal Ceiling(SybaseDecimal n) { return(AdjustScale(n, -(n.Scale), true)); }
public static SybaseDecimal Add(SybaseDecimal x, SybaseDecimal y) { return(x + y); }
public static SybaseDecimal Round (SybaseDecimal n, int position) { if (n.IsNull) throw new SybaseNullValueException (); SybaseDecimal result = new SybaseDecimal (System.Math.Round ((double) (n.ToDouble () * System.Math.Pow (10, position)))); result = result / new SybaseDecimal (System.Math.Pow (10, position)); return result; }
public static SybaseDecimal Power (SybaseDecimal n, double exp) { if (n.IsNull) return SybaseDecimal.Null; return new SybaseDecimal (System.Math.Pow (n.ToDouble (), exp)); }
public static SybaseBoolean NotEquals (SybaseDecimal x, SybaseDecimal y) { return (x != y); }
public static SybaseDecimal Multiply (SybaseDecimal x, SybaseDecimal y) { return (x * y); }
public static SybaseBoolean LessThanOrEqual (SybaseDecimal x, SybaseDecimal y) { return (x <= y); }
public static SybaseBoolean LessThan (SybaseDecimal x, SybaseDecimal y) { return (x < y); }
public static SybaseBoolean GreaterThanOrEqual (SybaseDecimal x, SybaseDecimal y) { return (x >= y); }
public static SybaseDecimal AdjustScale (SybaseDecimal n, int digits, bool fRound) { byte prec = n.Precision; if (n.IsNull) throw new SybaseNullValueException (); if (digits > 0) prec = (byte) (prec + digits); if (fRound) n = Round (n, digits + n.Scale); return new SybaseDecimal (prec, (byte) (n.Scale + digits), n.IsPositive, n.Data); }
public static SybaseDecimal Divide (SybaseDecimal x, SybaseDecimal y) { return (x / y); }
public static SybaseInt32 Sign (SybaseDecimal n) { SybaseInt32 result = 0; if (n >= new SybaseDecimal (0)) result = 1; else result = -1; return result; }
public static SybaseDecimal Abs(SybaseDecimal n) { return(new SybaseDecimal(n.Precision, n.Scale, true, n.BinData [0], n.BinData [1], n.BinData [2], n.BinData [3])); }
public static SybaseDecimal Subtract (SybaseDecimal x, SybaseDecimal y) { return (x - y); }
private static SybaseDecimal DecimalDiv (SybaseDecimal x, SybaseDecimal y) { ulong lo = 0; ulong hi = 0; int sc = 0; // scale int texp = 0; byte prec = 0; prec = x.Precision >= y.Precision ? x.Precision : y.Precision; DecimalDivSub (ref x, ref y, ref lo, ref hi, ref texp); sc = x.Scale - y.Scale; Rescale128 (ref lo, ref hi, ref sc, texp, 0, 38, 1); uint r = 0; while (prec < sc) { Div128By32 (ref hi, ref lo, 10, ref r); sc -= 1; } if (r >= 5) lo += 1; while ((((double) hi) * System.Math.Pow (2, 64) + lo) - System.Math.Pow (10, prec) > 0) prec += 1; while ((prec + sc) > MaxScale) { Div128By32 (ref hi, ref lo, 10, ref r); sc -= 1; if (r >= 5) lo += 1; } int resultLo = (int) lo; int resultMi = (int) (lo >> 32); int resultMi2 = (int) hi; int resultHi = (int) (hi >> 32); return new SybaseDecimal (prec, (byte) sc, true, resultLo, resultMi, resultMi2, resultHi); }
// from decimal.c private static void DecimalDivSub (ref SybaseDecimal x, ref SybaseDecimal y, ref ulong clo, ref ulong chi, ref int exp) { ulong xlo, xmi, xhi; ulong tlo = 0; ulong tmi = 0; ulong thi = 0; uint ylo = 0; uint ymi = 0; uint ymi2 = 0; uint yhi = 0; int ashift = 0; int bshift = 0; int extraBit = 0; xhi = (ulong) ((ulong) x.Data [3] << 32) | (ulong) x.Data [2]; xmi = (ulong) ((ulong) x.Data [1] << 32) | (ulong) x.Data [0]; xlo = (uint) 0; ylo = (uint) y.Data [0]; ymi = (uint) y.Data [1]; ymi2 = (uint) y.Data [2]; yhi = (uint) y.Data [3]; if (ylo == 0 && ymi == 0 && ymi2 == 0 && yhi == 0) throw new DivideByZeroException (); if (xmi == 0 && xhi == 0) { clo = chi = 0; return; } // enlarge dividend to get maximal precision for (ashift = 0; (xhi & LIT_GUINT64_HIGHBIT) == 0; ++ashift) LShift128 (ref xmi, ref xhi); // ensure that divisor is at least 2^95 for (bshift = 0; (yhi & LIT_GUINT32_HIGHBIT) == 0; ++bshift) LShift128 (ref ylo, ref ymi, ref ymi2, ref yhi); thi = ((ulong) yhi) << 32 | (ulong) ymi2; tmi = ((ulong) ymi) << 32 | (ulong) ylo; tlo = 0; if (xhi > thi || (xhi == thi && xmi >= tmi)) { Sub192 (xlo, xmi, xhi, tlo, tmi, thi, ref xlo, ref xmi, ref xhi); extraBit = 1; } else { extraBit = 0; } Div192By128To128 (xlo, xmi, xhi, ylo, ymi, ymi2, yhi, ref clo, ref chi); exp = 128 + ashift - bshift; if (extraBit != 0) { RShift128 (ref clo, ref chi); chi += LIT_GUINT64_HIGHBIT; exp -= 1; } // try loss free right shift while (exp > 0 && (clo & 1) == 0) { RShift128 (ref clo, ref chi); exp -= 1; } }
public static SybaseDecimal ConvertToPrecScale(SybaseDecimal n, int precision, int scale) { return(new SybaseDecimal((byte)precision, (byte)scale, n.IsPositive, n.Data)); }
public static SybaseDecimal Multiply(SybaseDecimal x, SybaseDecimal y) { return(x * y); }
public static SybaseDecimal Floor(SybaseDecimal n) { return(AdjustScale(n, -(n.Scale), false)); }
public static SybaseDecimal Add (SybaseDecimal x, SybaseDecimal y) { return (x + y); }
public static SybaseBoolean GreaterThanOrEqual(SybaseDecimal x, SybaseDecimal y) { return(x >= y); }
public static SybaseDecimal ConvertToPrecScale (SybaseDecimal n, int precision, int scale) { return new SybaseDecimal ((byte) precision, (byte) scale, n.IsPositive, n.Data); }
public static SybaseBoolean LessThanOrEqual(SybaseDecimal x, SybaseDecimal y) { return(x <= y); }
public static SybaseDecimal Floor (SybaseDecimal n) { return AdjustScale (n, -(n.Scale), false); }
public static SybaseBoolean NotEquals(SybaseDecimal x, SybaseDecimal y) { return(x != y); }
public static SybaseDecimal Abs (SybaseDecimal n) { return new SybaseDecimal (n.Precision, n.Scale, true, n.BinData [0], n.BinData [1], n.BinData [2], n.BinData [3]); }
public static SybaseDecimal Truncate (SybaseDecimal n, int position) { return new SybaseDecimal ((byte) n.Precision, (byte) position, n.IsPositive, n.Data); }
public static SybaseDecimal Ceiling (SybaseDecimal n) { return AdjustScale (n, -(n.Scale), true); }
public static SybaseDecimal Subtract(SybaseDecimal x, SybaseDecimal y) { return(x - y); }
public static SybaseDecimal Truncate(SybaseDecimal n, int position) { return(new SybaseDecimal((byte)n.Precision, (byte)position, n.IsPositive, n.Data)); }
// from decimal.c private static void DecimalDivSub(ref SybaseDecimal x, ref SybaseDecimal y, ref ulong clo, ref ulong chi, ref int exp) { ulong xlo, xmi, xhi; ulong tlo = 0; ulong tmi = 0; ulong thi = 0; uint ylo = 0; uint ymi = 0; uint ymi2 = 0; uint yhi = 0; int ashift = 0; int bshift = 0; int extraBit = 0; xhi = (ulong)((ulong)x.Data [3] << 32) | (ulong)x.Data [2]; xmi = (ulong)((ulong)x.Data [1] << 32) | (ulong)x.Data [0]; xlo = (uint)0; ylo = (uint)y.Data [0]; ymi = (uint)y.Data [1]; ymi2 = (uint)y.Data [2]; yhi = (uint)y.Data [3]; if (ylo == 0 && ymi == 0 && ymi2 == 0 && yhi == 0) { throw new DivideByZeroException(); } if (xmi == 0 && xhi == 0) { clo = chi = 0; return; } // enlarge dividend to get maximal precision for (ashift = 0; (xhi & LIT_GUINT64_HIGHBIT) == 0; ++ashift) { LShift128(ref xmi, ref xhi); } // ensure that divisor is at least 2^95 for (bshift = 0; (yhi & LIT_GUINT32_HIGHBIT) == 0; ++bshift) { LShift128(ref ylo, ref ymi, ref ymi2, ref yhi); } thi = ((ulong)yhi) << 32 | (ulong)ymi2; tmi = ((ulong)ymi) << 32 | (ulong)ylo; tlo = 0; if (xhi > thi || (xhi == thi && xmi >= tmi)) { Sub192(xlo, xmi, xhi, tlo, tmi, thi, ref xlo, ref xmi, ref xhi); extraBit = 1; } else { extraBit = 0; } Div192By128To128(xlo, xmi, xhi, ylo, ymi, ymi2, yhi, ref clo, ref chi); exp = 128 + ashift - bshift; if (extraBit != 0) { RShift128(ref clo, ref chi); chi += LIT_GUINT64_HIGHBIT; exp -= 1; } // try loss free right shift while (exp > 0 && (clo & 1) == 0) { RShift128(ref clo, ref chi); exp -= 1; } }
public static SybaseDecimal operator - (SybaseDecimal x, SybaseDecimal y) { if (x.IsPositive && !y.IsPositive) return x + y; if (!x.IsPositive && y.IsPositive) return -(x + y); if (!x.IsPositive && !y.IsPositive) return y - x; // otherwise, x is positive and y is positive bool resultPositive = (bool)(x > y); int[] yData = y.Data; for (int i = 0; i < 4; i += 1) yData[i] = -yData[i]; SybaseDecimal yInverse = new SybaseDecimal (y.Precision, y.Scale, y.IsPositive, yData); if (resultPositive) return x + yInverse; else return -(x + yInverse); }