Example #1
0
 protected SqlDecimalBase(SqlDecimalAny d, byte precision, byte scale)
 {
     if (d != null)
     {
         _d = SqlDecimal.ConvertToPrecScale(d._d, precision, scale);
     }
 }
Example #2
0
		public void Create ()
		{
			// SqlDecimal (decimal)
			SqlDecimal Test = new SqlDecimal (30.3098m);
			Assert.AreEqual ((decimal) 30.3098, Test.Value, "#A01");

			try {
				decimal d = Decimal.MaxValue;
				SqlDecimal test = new SqlDecimal (d + 1);
				Assert.Fail ("#A02");
			} catch (OverflowException e) {
				Assert.AreEqual (typeof (OverflowException), e.GetType (), "#A03");
			}

			// SqlDecimal (double)
			Test = new SqlDecimal (10E+10d);
			Assert.AreEqual (100000000000.00000m, Test.Value, "#A05");

			try {
				SqlDecimal test = new SqlDecimal (10E+200d);
				Assert.Fail ("#A06");
			} catch (OverflowException e) {
				Assert.AreEqual (typeof (OverflowException), e.GetType (), "#A07");
			}

			// SqlDecimal (int)
			Test = new SqlDecimal (-1);
			Assert.AreEqual (-1m, Test.Value, "#A08");

			// SqlDecimal (long)
			Test = new SqlDecimal ((long) (-99999));
			Assert.AreEqual (-99999m, Test.Value, "#A09");

			// SqlDecimal (byte, byte, bool. int[]
			Test = new SqlDecimal (10, 3, false, new int [4] { 200, 1, 0, 0 });
			Assert.AreEqual (-4294967.496m, Test.Value, "#A10");

			try {
				Test = new SqlDecimal (100, 100, false,
					new int [4] {Int32.MaxValue,
					Int32.MaxValue, Int32.MaxValue,
					Int32.MaxValue});
				Assert.Fail ("#A11");
			} catch (SqlTypeException) {
			}

			// sqlDecimal (byte, byte, bool, int, int, int, int)
			Test = new SqlDecimal (12, 2, true, 100, 100, 0, 0);
			Assert.AreEqual (4294967297.00m, Test.Value, "#A13");

			try {
				Test = new SqlDecimal (100, 100, false,
					Int32.MaxValue,
					Int32.MaxValue, Int32.MaxValue,
					Int32.MaxValue);
				Assert.Fail ("#A14");
			} catch (SqlTypeException) {
			}
		}
 public void GetReady() 
 {
 	Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
 	Test1 = new SqlDecimal (6464.6464m);
 	Test2 = new SqlDecimal (10000.00m); 
 	Test3 = new SqlDecimal (10000.00m);                 
 	Test4 = new SqlDecimal (-6m);                 
 }
		public void GetReady ()
		{
            Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";
			Test1 = new SqlDecimal (6464.6464m);
			Test2 = new SqlDecimal (10000.00m);
			Test3 = new SqlDecimal (10000.00m);
			Test4 = new SqlDecimal (-6m);
			Test5 = new SqlDecimal (Decimal.MaxValue);
		}
Example #5
0
		public void GetReady ()
		{
			originalCulture = Thread.CurrentThread.CurrentCulture;
			Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
			Test1 = new SqlDecimal (6464.6464m);
			Test2 = new SqlDecimal (10000.00m);
			Test3 = new SqlDecimal (10000.00m);
			Test4 = new SqlDecimal (-6m);
			Test5 = new SqlDecimal (Decimal.MaxValue);
		}
Example #6
0
 public SqlDecimalTest()
 {
     _originalCulture = CultureInfo.CurrentCulture; ;
     CultureInfo.CurrentCulture = new CultureInfo("en-US");
     _test1 = new SqlDecimal(6464.6464m);
     _test2 = new SqlDecimal(10000.00m);
     _test3 = new SqlDecimal(10000.00m);
     _test4 = new SqlDecimal(-6m);
     _test5 = new SqlDecimal(decimal.MaxValue);
 }
        private static Decimal ToDecimal(SqlDecimal value)
        {
            var data = value.Data;
            var scale = value.Scale;

            if (data[3] != 0 || scale > 28)
            {
                var result = decimal.Parse(value.ToString());

                return result;
            }

            return new Decimal(data[0], data[1], data[2], !value.IsPositive, scale);
        }
 public SqlMoney(decimal value)
 {
     SqlDecimal num2 = new SqlDecimal(value);
     num2.AdjustScale(x_iMoneyScale - num2.Scale, true);
     if ((num2.m_data3 != 0) || (num2.m_data4 != 0))
     {
         throw new OverflowException(SQLResource.ArithOverflowMessage);
     }
     bool isPositive = num2.IsPositive;
     ulong num = num2.m_data1 + (num2.m_data2 << 0x20);
     if ((isPositive && (num > 0x7fffffffffffffffL)) || (!isPositive && (num > 9223372036854775808L)))
     {
         throw new OverflowException(SQLResource.ArithOverflowMessage);
     }
     this.m_value = isPositive ? ((long) num) : ((long) -num);
     this.m_fNotNull = true;
 }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref='SqlMoney'/> class with the value given.
        /// </summary>
        public SqlMoney(decimal value)
        {
            // Since Decimal is a value type, operate directly on value, don't worry about changing it.
            SqlDecimal snum = new SqlDecimal(value);
            snum.AdjustScale(s_iMoneyScale - snum.Scale, true);
            Debug.Assert(snum.Scale == s_iMoneyScale);

            if (snum._data3 != 0 || snum._data4 != 0)
                throw new OverflowException(SQLResource.s_arithOverflowMessage);

            bool fPositive = snum.IsPositive;
            ulong ulValue = snum._data1 + (((ulong)snum._data2) << 32);
            if (fPositive && ulValue > long.MaxValue ||
                !fPositive && ulValue > unchecked((ulong)(long.MinValue)))
                throw new OverflowException(SQLResource.s_arithOverflowMessage);

            _value = fPositive ? (long)ulValue : unchecked(-(long)ulValue);
            _fNotNull = true;
        }
Example #10
0
 public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y)
 {
     return (x < y);
 }
Example #11
0
 public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y)
 {
     return (x/y);
 }
Example #12
0
 public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y)
 {
     return (x > y);
 }
Example #13
0
        public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fRound)
        {
            byte prec = n.Precision;
            if (n.IsNull)
            {
                throw new SqlNullValueException();
            }

            byte scale;
            if (digits == 0)
            {
                return n;
            }
            else if (digits > 0)
            {
                prec = (byte) (prec + digits);
                scale = (byte) (n.scale + digits);
                // use Math.Pow once the Ctr (double) is fixed to  handle
                // values greater than Decimal.MaxValue
                // the current code creates too many sqldecimal objects 
                //n = n * (new SqlDecimal ((double)Math.Pow (10, digits)));
                for (int i = 0; i < digits; i++)
                {
                    n *= 10;
                }
            }
            else
            {
                if (n.Scale < Math.Abs(digits))
                {
                    throw new SqlTruncateException();
                }

                if (fRound)
                {
                    n = Round(n, digits + n.scale);
                }
                else
                {
                    n = Round(Truncate(n, digits + n.scale), digits + n.scale);
                }
                scale = n.scale;
            }

            return new SqlDecimal(prec, scale, n.positive, n.Data);
        }
Example #14
0
 public int CompareTo(SqlDecimal value)
 {
     if (value.IsNull)
     {
         return 1;
     }
     else
     {
         return this.Value.CompareTo(value.Value);
     }
 }
Example #15
0
 public static SqlInt32 Sign(SqlDecimal n)
 {
     if (n.IsNull)
     {
         return SqlInt32.Null;
     }
     return (n.IsPositive ? 1 : -1);
 }
Example #16
0
        public static SqlDecimal operator -(SqlDecimal x, SqlDecimal y)
        {
            if (x.IsNull || y.IsNull)
            {
                return(SqlDecimal.Null);
            }

            if (x.IsPositive && !y.IsPositive)
            {
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                return(x + y);
            }
            if (!x.IsPositive && y.IsPositive)
            {
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                x = (x + y);
                return(new SqlDecimal(x.Precision, x.Scale, false, x.Data));
            }
            if (!x.IsPositive && !y.IsPositive)
            {
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                return(y - x);
            }
            // adjust the scale to the larger of the two beforehand
            if (x.scale > y.scale)
            {
                y = SqlDecimal.AdjustScale(y, x.scale - y.scale, false);
            }
            else if (y.scale > x.scale)
            {
                x = SqlDecimal.AdjustScale(x, y.scale - x.scale, false);
            }

            //calculation of the new Precision for the result
            byte resultPrecision = (byte)(Math.Max(x.Scale, y.Scale) +
                                          Math.Max(x.Precision - x.Scale, y.Precision - y.Scale));

            int[] op1_Data;
            int[] op2_Data;
            if (x >= y)
            {
                op1_Data = x.Data;
                op2_Data = y.Data;
            }
            else
            {
                op1_Data = y.Data;
                op2_Data = x.Data;
            }

            ulong res   = 0;
            int   carry = 0;

            int[] resultBits = new int[4];


            /*
             * if ((uint)op2_Data [i] > (uint)op1_Data [i]) {
             *       carry = UInt32.MaxValue;
             *       op2_Data [i] = op2_Data [i] >> 1;
             * } else
             *       carr = 0;
             *      res = (uint)carry; +(ulong)((uint)op1_Data [i]) - (ulong)((uint)op2_Data [i])
             */

            for (int i = 0; i < 4; i += 1)
            {
                res   = (ulong)((uint)op1_Data [i]) - (ulong)((uint)op2_Data [i]) + (ulong)carry;
                carry = 0;
                if ((uint)op2_Data [i] > (uint)op1_Data [i])
                {
                    carry = -1;
                }
                resultBits [i] = (int)res;
            }

            if (carry > 0)
            {
                throw new OverflowException();
            }
            else
            {
                return(new SqlDecimal(resultPrecision, x.Scale, (x >= y).Value, resultBits));
            }
        }
Example #17
0
 public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y)
 {
     return(x < y);
 }
Example #18
0
 public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y)
 {
     return(x <= y);
 }
Example #19
0
 public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y)
 {
     return(x > y);
 }
Example #20
0
 public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y)
 {
     return(x >= y);
 }
Example #21
0
 public static SqlDecimal Floor(SqlDecimal n)
 {
     return(AdjustScale(n, -(n.Scale), false));
 }
Example #22
0
 public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y)
 {
     return(x / y);
 }
Example #23
0
 public static SqlDecimal Add(SqlDecimal x, SqlDecimal y)
 {
     return(x + y);
 }
Example #24
0
 public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y)
 {
     return (x*y);
 }
Example #25
0
 public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y)
 {
     return(x * y);
 }
Example #26
0
        public static SqlDecimal Power(SqlDecimal n, double exp)
        {
            if (n.IsNull)
            {
                return Null;
            }

            return new SqlDecimal(Math.Pow(n.ToDouble(), exp));
        }
Example #27
0
 public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y)
 {
     return(x != y);
 }
Example #28
0
        private static SqlDecimal DecimalDiv(SqlDecimal x, SqlDecimal y)
        {
            ulong lo = 0;
            ulong hi = 0;
            int sc = 0; // scale
            int texp = 0;
            byte prec = 0; // precision
            bool positive = ! (x.positive ^ y.positive);

            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--;
            }

            if (r >= 5)
            {
                lo++;
            }

            while (((hi)*Math.Pow(2, 64) + lo) - Math.Pow(10, prec) > 0)
            {
                prec++;
            }

            while ((prec + sc) > MaxScale)
            {
                Div128By32(ref hi, ref lo, 10, ref r);
                sc--;
                if (r >= 5)
                {
                    lo++;
                }
            }

            var resultLo = (int) lo;
            var resultMi = (int) (lo >> 32);
            var resultMi2 = (int) (hi);
            var resultHi = (int) (hi >> 32);

            return new SqlDecimal(prec, (byte) sc, positive, resultLo,
                                  resultMi, resultMi2,
                                  resultHi);
        }
Example #29
0
 public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y)
 {
     return(x - y);
 }
Example #30
0
 public static SqlDecimal Add(SqlDecimal x, SqlDecimal y)
 {
     return (x + y);
 }
Example #31
0
        // From decimal.c
        private static void DecimalDivSub(ref SqlDecimal x, ref SqlDecimal 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--;
            }

            // try loss free right shift
            while (exp > 0 && (clo & 1) == 0)
            {
                RShift128(ref clo, ref chi);
                exp--;
            }
        }
Example #32
0
 public static SqlDecimal Ceiling(SqlDecimal n)
 {
     if (!n.notNull)
     {
         return n;
     }
     return AdjustScale(n, -(n.Scale), true);
 }
        /// <summary>
        /// [To be supplied.]
        /// </summary>
        /// <returns>[To be supplied.]</returns>
        public bool Refresh()
        {
            this.displayName = null;

            this.col_JobIdWasUpdated = false;
            this.col_JobIdWasSet     = false;
            this.col_JobId           = System.Data.SqlTypes.SqlInt32.Null;

            this.col_DescriptionWasUpdated = false;
            this.col_DescriptionWasSet     = false;
            this.col_Description           = System.Data.SqlTypes.SqlString.Null;

            this.col_JobPartTypeIdWasUpdated = false;
            this.col_JobPartTypeIdWasSet     = false;
            this.col_JobPartTypeId           = System.Data.SqlTypes.SqlInt32.Null;

            this.col_UnitsWasUpdated = false;
            this.col_UnitsWasSet     = false;
            this.col_Units           = System.Data.SqlTypes.SqlDecimal.Null;

            this.col_PricePerUnitWasUpdated = false;
            this.col_PricePerUnitWasSet     = false;
            this.col_PricePerUnit           = System.Data.SqlTypes.SqlMoney.Null;

            this.col_TotalPriceWasUpdated = false;
            this.col_TotalPriceWasSet     = false;
            this.col_TotalPrice           = System.Data.SqlTypes.SqlMoney.Null;

            bool alreadyOpened = false;

            Params.spS_JobPart Param = new Params.spS_JobPart(true);
            Param.CommandTimeOut = this.selectCommandTimeOut;
            switch (this.lastKnownConnectionType)
            {
            case Bob.DataClasses.ConnectionType.ConnectionString:
                Param.SetUpConnection(this.connectionString);
                break;

            case Bob.DataClasses.ConnectionType.SqlConnection:
                Param.SetUpConnection(this.sqlConnection);
                alreadyOpened = (this.sqlConnection.State == System.Data.ConnectionState.Open);
                break;

            case Bob.DataClasses.ConnectionType.SqlTransaction:
                Param.SetUpConnection(this.sqlTransaction);
                break;
            }

            if (!this.col_JobPartId.IsNull)
            {
                Param.Param_JobPartId = this.col_JobPartId;
            }


            System.Data.SqlClient.SqlDataReader sqlDataReader = null;
            SPs.spS_JobPart Sp = new SPs.spS_JobPart(false);
            if (Sp.Execute(ref Param, out sqlDataReader))
            {
                if (sqlDataReader.Read())
                {
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_JobId.ColumnIndex))
                    {
                        this.col_JobId = sqlDataReader.GetSqlInt32(SPs.spS_JobPart.Resultset1.Fields.Column_JobId.ColumnIndex);
                    }
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_Description.ColumnIndex))
                    {
                        this.col_Description = sqlDataReader.GetSqlString(SPs.spS_JobPart.Resultset1.Fields.Column_Description.ColumnIndex);
                    }
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_JobPartTypeId.ColumnIndex))
                    {
                        this.col_JobPartTypeId = sqlDataReader.GetSqlInt32(SPs.spS_JobPart.Resultset1.Fields.Column_JobPartTypeId.ColumnIndex);
                    }
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_Units.ColumnIndex))
                    {
                        this.col_Units = sqlDataReader.GetSqlDecimal(SPs.spS_JobPart.Resultset1.Fields.Column_Units.ColumnIndex);
                    }
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_PricePerUnit.ColumnIndex))
                    {
                        this.col_PricePerUnit = sqlDataReader.GetSqlMoney(SPs.spS_JobPart.Resultset1.Fields.Column_PricePerUnit.ColumnIndex);
                    }
                    if (!sqlDataReader.IsDBNull(SPs.spS_JobPart.Resultset1.Fields.Column_TotalPrice.ColumnIndex))
                    {
                        this.col_TotalPrice = sqlDataReader.GetSqlMoney(SPs.spS_JobPart.Resultset1.Fields.Column_TotalPrice.ColumnIndex);
                    }

                    if (sqlDataReader != null && !sqlDataReader.IsClosed)
                    {
                        sqlDataReader.Close();
                    }

                    CloseConnection(Sp.Connection, alreadyOpened);

                    this.recordIsLoaded = true;

                    return(true);
                }
                else
                {
                    if (sqlDataReader != null && !sqlDataReader.IsClosed)
                    {
                        sqlDataReader.Close();
                    }

                    CloseConnection(Sp.Connection, alreadyOpened);

                    this.recordIsLoaded = false;

                    return(false);
                }
            }
            else
            {
                if (sqlDataReader != null && !sqlDataReader.IsClosed)
                {
                    sqlDataReader.Close();
                }

                CloseConnection(Sp.Connection, alreadyOpened);

                throw new Bob.DataClasses.CustomException(Param, "Bob.BusinessComponents.JobPart_Record", "Refresh");
            }
        }
Example #34
0
 public static SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
 {
     int prec = n.Precision;
     int sc = n.Scale;
     n = AdjustScale(n, scale - n.scale, true);
     if ((n.Scale >= sc) && (precision < n.Precision))
     {
         throw new SqlTruncateException();
     }
     else
     {
         prec = precision;
         return new SqlDecimal((byte) prec, n.scale, n.IsPositive, n.Data);
     }
 }
Example #35
0
 /**
  * Converts this SqlString structure to SqlDecimal.
  * @return A SqlDecimal structure whose Value equals the Value of this SqlString structure.
  */
 public SqlDecimal ToSqlDecimal()
 {
     return(SqlDecimal.Parse(_value));
 }
Example #36
0
 public static SqlDecimal Floor(SqlDecimal n)
 {
     return AdjustScale(n, -(n.Scale), false);
 }
Example #37
0
        /**
         * Gets the number nearest the specified SqlDecimal instance's value with the specified precision.
         * @param n The SqlDecimal instance to be rounded.
         * @param position The number of significant fractional digits (precision) in the return value.
         * @return A SqlDecimal instance containing the results of the rounding operation.
         */
        public static SqlDecimal Round(SqlDecimal n, int position)
        {
            Decimal val = Decimal.Round(n._value, position);

            return(new SqlDecimal(val));
        }
Example #38
0
 public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y)
 {
     return (x >= y);
 }
Example #39
0
        /**
         * Rounds a specified SqlDecimal number to the next lower whole number.
         * @param n The SqlDecimal instance for which the floor value is to be calculated.
         * @return A SqlDecimal instance containing the whole number portion of this SqlDecimal instance.
         */
        public static SqlDecimal Floor(SqlDecimal n)
        {
            Decimal res = Decimal.Floor(n._value);

            return(new SqlDecimal(res));
        }
Example #40
0
 public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y)
 {
     return (x <= y);
 }
Example #41
0
 public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
 {
     /** @todo find out what the logic */
     throw new NotImplementedException();
 }
Example #42
0
 public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y)
 {
     return (x != y);
 }
Example #43
0
 public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fround)
 {
     /** @todo find out what the logic */
     throw new NotImplementedException();
 }
Example #44
0
        public static SqlDecimal Round(SqlDecimal n, int position)
        {
            if (n.IsNull)
            {
                throw new SqlNullValueException();
            }

            decimal d = n.Value;
            d = Math.Round(d, position);
            return new SqlDecimal(d);
        }
Example #45
0
        public static SqlDecimal operator -(SqlDecimal x, SqlDecimal y)
        {
            if (x.IsNull || y.IsNull)
            {
                return Null;
            }

            if (x.IsPositive && !y.IsPositive)
            {
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                return x + y;
            }
            if (!x.IsPositive && y.IsPositive)
            {
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                x = (x + y);
                return new SqlDecimal(x.Precision, x.Scale, false, x.Data);
            }
            if (!x.IsPositive && !y.IsPositive)
            {
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                return (y - x);
            }
            // adjust the scale to the larger of the two beforehand
            if (x.scale > y.scale)
            {
                y = AdjustScale(y, x.scale - y.scale, false);
            }
            else if (y.scale > x.scale)
            {
                x = AdjustScale(x, y.scale - x.scale, false);
            }

            //calculation of the new Precision for the result
            var resultPrecision = (byte) (Math.Max(x.Scale, y.Scale) +
                                          Math.Max(x.Precision - x.Scale, y.Precision - y.Scale));

            int[] op1_Data;
            int[] op2_Data;
            if (x >= y)
            {
                op1_Data = x.Data;
                op2_Data = y.Data;
            }
            else
            {
                op1_Data = y.Data;
                op2_Data = x.Data;
            }

            ulong res = 0;
            int carry = 0;
            var resultBits = new int[4];


            /*
			 if ((uint)op2_Data [i] > (uint)op1_Data [i]) {
				 carry = UInt32.MaxValue;
				 op2_Data [i] = op2_Data [i] >> 1;
			 } else
				 carr = 0;
				res = (uint)carry; +(ulong)((uint)op1_Data [i]) - (ulong)((uint)op2_Data [i]) 
			*/

            for (int i = 0; i < 4; i += 1)
            {
                res = ((uint) op1_Data[i]) - (ulong) ((uint) op2_Data[i]) + (ulong) carry;
                carry = 0;
                if ((uint) op2_Data[i] > (uint) op1_Data[i])
                {
                    carry = -1;
                }
                resultBits[i] = (int) res;
            }

            if (carry > 0)
            {
                throw new OverflowException();
            }
            else
            {
                return new SqlDecimal(resultPrecision, x.Scale, (x >= y).Value, resultBits);
            }
        }
Example #46
0
 public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y)
 {
     return (x - y);
 }
Example #47
0
 public static SqlDecimal Abs(SqlDecimal n)
 {
     if (!n.notNull)
     {
         return n;
     }
     return new SqlDecimal(n.Precision, n.Scale, true, n.Data);
 }
Example #48
0
        // From decimal.c
        private static void DecimalDivSub(ref SqlDecimal x, ref SqlDecimal 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) x.Data[3] << 32) | (ulong) x.Data[2];
            xmi = ((ulong) x.Data[1] << 32) | (ulong) x.Data[0];
            xlo = 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 | ymi2;
            tmi = ((ulong) ymi) << 32 | 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--;
            }

            // try loss free right shift
            while (exp > 0 && (clo & 1) == 0)
            {
                RShift128(ref clo, ref chi);
                exp--;
            }
        }
Example #49
0
        public static SqlDecimal operator +(SqlDecimal x, SqlDecimal y)
        {
            if (x.IsNull || y.IsNull)
            {
                return(SqlDecimal.Null);
            }
            //if one of them is negative, perform subtraction
            if (x.IsPositive && !y.IsPositive)
            {
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                return(x - y);
            }
            if (!x.IsPositive && y.IsPositive)
            {
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                return(y - x);
            }
            if (!x.IsPositive && !y.IsPositive)
            {
                x = new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data);
                y = new SqlDecimal(y.Precision, y.Scale, !y.IsPositive, y.Data);
                x = (x + y);
                return(new SqlDecimal(x.Precision, x.Scale, !x.IsPositive, x.Data));
            }
            // adjust the scale to the larger of the two beforehand
            if (x.scale > y.scale)
            {
                y = SqlDecimal.AdjustScale(y, x.scale - y.scale, false);
            }
            else if (y.scale > x.scale)
            {
                x = SqlDecimal.AdjustScale(x, y.scale - x.scale, false);
            }

            byte resultPrecision = (byte)(Math.Max(x.Scale, y.Scale) +
                                          Math.Max(x.Precision - x.Scale, y.Precision - y.Scale) + 1);

            if (resultPrecision > MaxPrecision)
            {
                resultPrecision = MaxPrecision;
            }

            int [] xData      = x.Data;
            int [] yData      = y.Data;
            int [] resultBits = new int[4];
            ulong  carry      = 0;
            ulong  res        = 0;

            for (int i = 0; i < 4; i++)
            {
                res            = (ulong)((uint)xData [i]) + (ulong)((uint)yData [i]) + carry;
                resultBits [i] = (int)(res & (UInt32.MaxValue));
                carry          = res >> 32;
            }

            if (carry > 0)
            {
                throw new OverflowException();
            }
            else
            {
                return(new SqlDecimal(resultPrecision, x.Scale, x.IsPositive, resultBits));
            }
        }