コード例 #1
0
        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));
        }
コード例 #2
0
        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));
        }
コード例 #3
0
 public static SybaseDecimal Power(SybaseDecimal n, double exp)
 {
     if (n.IsNull)
     {
         return(SybaseDecimal.Null);
     }
     return(new SybaseDecimal(System.Math.Pow(n.ToDouble(), exp)));
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        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));
            }
        }
コード例 #6
0
        public static SybaseInt32 Sign(SybaseDecimal n)
        {
            SybaseInt32 result = 0;

            if (n >= new SybaseDecimal(0))
            {
                result = 1;
            }
            else
            {
                result = -1;
            }
            return(result);
        }
コード例 #7
0
        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));
        }
コード例 #8
0
        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));
        }
コード例 #9
0
        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));
            }
        }
コード例 #10
0
		public static SybaseBoolean GreaterThan (SybaseDecimal x, SybaseDecimal y)
		{
			return (x > y);
		}
コード例 #11
0
 public static SybaseBoolean LessThan(SybaseDecimal x, SybaseDecimal y)
 {
     return(x < y);
 }
コード例 #12
0
 public static SybaseBoolean GreaterThan(SybaseDecimal x, SybaseDecimal y)
 {
     return(x > y);
 }
コード例 #13
0
 public static SybaseDecimal Divide(SybaseDecimal x, SybaseDecimal y)
 {
     return(x / y);
 }
コード例 #14
0
 public static SybaseDecimal Ceiling(SybaseDecimal n)
 {
     return(AdjustScale(n, -(n.Scale), true));
 }
コード例 #15
0
 public static SybaseDecimal Add(SybaseDecimal x, SybaseDecimal y)
 {
     return(x + y);
 }
コード例 #16
0
		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;
		}
コード例 #17
0
		public static SybaseDecimal Power (SybaseDecimal n, double exp)
		{
			if (n.IsNull)
				return SybaseDecimal.Null;
			return new SybaseDecimal (System.Math.Pow (n.ToDouble (), exp));
		}
コード例 #18
0
		public static SybaseBoolean NotEquals (SybaseDecimal x, SybaseDecimal y)
		{
			return (x != y);
		}
コード例 #19
0
		public static SybaseDecimal Multiply (SybaseDecimal x, SybaseDecimal y)
		{
			return (x * y);
		}
コード例 #20
0
		public static SybaseBoolean LessThanOrEqual (SybaseDecimal x, SybaseDecimal y)
		{
			return (x <= y);
		}
コード例 #21
0
		public static SybaseBoolean LessThan (SybaseDecimal x, SybaseDecimal y)
		{
			return (x < y);
		}
コード例 #22
0
		public static SybaseBoolean GreaterThanOrEqual (SybaseDecimal x, SybaseDecimal y)
		{
			return (x >= y);
		}
コード例 #23
0
		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);
		}
コード例 #24
0
		public static SybaseDecimal Divide (SybaseDecimal x, SybaseDecimal y)
		{
			return (x / y);
		}
コード例 #25
0
		public static SybaseInt32 Sign (SybaseDecimal n)
		{
			SybaseInt32 result = 0;
			if (n >= new SybaseDecimal (0))
				result = 1;
			else
				result = -1;
			return result;
		}
コード例 #26
0
 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]));
 }
コード例 #27
0
		public static SybaseDecimal Subtract (SybaseDecimal x, SybaseDecimal y)
		{
			return (x - y);
		}
コード例 #28
0
		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);
		}
コード例 #29
0
		// 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;
			}
		}
コード例 #30
0
 public static SybaseDecimal ConvertToPrecScale(SybaseDecimal n, int precision, int scale)
 {
     return(new SybaseDecimal((byte)precision, (byte)scale, n.IsPositive, n.Data));
 }
コード例 #31
0
 public static SybaseDecimal Multiply(SybaseDecimal x, SybaseDecimal y)
 {
     return(x * y);
 }
コード例 #32
0
 public static SybaseDecimal Floor(SybaseDecimal n)
 {
     return(AdjustScale(n, -(n.Scale), false));
 }
コード例 #33
0
		public static SybaseDecimal Add (SybaseDecimal x, SybaseDecimal y)
		{
			return (x + y);
		}
コード例 #34
0
 public static SybaseBoolean GreaterThanOrEqual(SybaseDecimal x, SybaseDecimal y)
 {
     return(x >= y);
 }
コード例 #35
0
		public static SybaseDecimal ConvertToPrecScale (SybaseDecimal n, int precision, int scale)
		{
			return new SybaseDecimal ((byte) precision, (byte) scale, n.IsPositive, n.Data);
		}
コード例 #36
0
 public static SybaseBoolean LessThanOrEqual(SybaseDecimal x, SybaseDecimal y)
 {
     return(x <= y);
 }
コード例 #37
0
		public static SybaseDecimal Floor (SybaseDecimal n)
		{
			return AdjustScale (n, -(n.Scale), false);
		}
コード例 #38
0
 public static SybaseBoolean NotEquals(SybaseDecimal x, SybaseDecimal y)
 {
     return(x != y);
 }
コード例 #39
0
		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]);
		}
コード例 #40
0
		public static SybaseDecimal Truncate (SybaseDecimal n, int position)
		{
			return new SybaseDecimal ((byte) n.Precision, (byte) position, n.IsPositive, n.Data);
		}
コード例 #41
0
		public static SybaseDecimal Ceiling (SybaseDecimal n)
		{
			return AdjustScale (n, -(n.Scale), true);
		}
コード例 #42
0
 public static SybaseDecimal Subtract(SybaseDecimal x, SybaseDecimal y)
 {
     return(x - y);
 }
コード例 #43
0
 public static SybaseDecimal Truncate(SybaseDecimal n, int position)
 {
     return(new SybaseDecimal((byte)n.Precision, (byte)position, n.IsPositive, n.Data));
 }
コード例 #44
0
        // 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;
            }
        }
コード例 #45
0
		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);
		}