protected SqlDecimalBase(SqlDecimalAny d, byte precision, byte scale) { if (d != null) { _d = SqlDecimal.ConvertToPrecScale(d._d, precision, scale); } }
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); }
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); }
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; }
/// <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; }
public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y) { return (x < y); }
public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y) { return (x/y); }
public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y) { return (x > y); }
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); }
public int CompareTo(SqlDecimal value) { if (value.IsNull) { return 1; } else { return this.Value.CompareTo(value.Value); } }
public static SqlInt32 Sign(SqlDecimal n) { if (n.IsNull) { return SqlInt32.Null; } return (n.IsPositive ? 1 : -1); }
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)); } }
public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y) { return(x < y); }
public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y) { return(x <= y); }
public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y) { return(x > y); }
public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y) { return(x >= y); }
public static SqlDecimal Floor(SqlDecimal n) { return(AdjustScale(n, -(n.Scale), false)); }
public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y) { return(x / y); }
public static SqlDecimal Add(SqlDecimal x, SqlDecimal y) { return(x + y); }
public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y) { return (x*y); }
public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y) { return(x * y); }
public static SqlDecimal Power(SqlDecimal n, double exp) { if (n.IsNull) { return Null; } return new SqlDecimal(Math.Pow(n.ToDouble(), exp)); }
public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y) { return(x != y); }
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); }
public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y) { return(x - y); }
public static SqlDecimal Add(SqlDecimal x, SqlDecimal y) { return (x + y); }
// 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--; } }
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"); } }
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); } }
/** * 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)); }
public static SqlDecimal Floor(SqlDecimal n) { return AdjustScale(n, -(n.Scale), false); }
/** * 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)); }
public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y) { return (x >= y); }
/** * 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)); }
public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y) { return (x <= y); }
public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale) { /** @todo find out what the logic */ throw new NotImplementedException(); }
public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y) { return (x != y); }
public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fround) { /** @todo find out what the logic */ throw new NotImplementedException(); }
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); }
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); } }
public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y) { return (x - y); }
public static SqlDecimal Abs(SqlDecimal n) { if (!n.notNull) { return n; } return new SqlDecimal(n.Precision, n.Scale, true, n.Data); }
// 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--; } }
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)); } }