1 // System.Data.SqlTypes.SqlDecimal
\r
4 // Konstantin Triger <kostat@mainsoft.com>
5 // Boris Kirzner <borisk@mainsoft.com>
7 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 namespace System.Data.SqlTypes
\r
36 * <p>Description: </p>
\r
37 * <p>Copyright: Copyright (c) 2002</p>
\r
38 * <p>Company: MainSoft</p>
\r
39 * @author Pavel Sandler
\r
48 * CURRENT LIMITATIONS:
\r
49 * 1. public byte[] Data not implemented.
\r
50 * 2. public byte[] BinData not implemented.
\r
51 * 3. Precision value is ignored.
\r
52 * 4. public SqlDecimal AdjustScale(SqlDecimal n, int position) not implemented.
\r
53 * 5. public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale) not implemented.
\r
57 public struct SqlDecimal : INullable
\r
60 private Decimal _value;
\r
61 private bool _isNull;
\r
63 public static readonly SqlDecimal MaxValue = new SqlDecimal(Decimal.MaxValue);
\r
64 public static readonly SqlDecimal MinValue = new SqlDecimal(Decimal.MinValue);
\r
65 public static readonly int MaxPrecision = 38;
\r
66 public static readonly int MaxScale = MaxPrecision;
\r
67 public static readonly SqlDecimal Null = new SqlDecimal(true);
\r
69 private int _precision;
\r
73 private SqlDecimal(bool isNull)
\r
75 _value = Decimal.Zero;
\r
81 * Initializes a new instance of the SqlDecimal instance using the supplied Decimal value.
\r
82 * @param value The Decimal value to be stored as a SqlDecimal instance.
\r
84 public SqlDecimal(Decimal value)
\r
88 int[] bits = Decimal.GetBits(value);
\r
89 int i = bits[3] & 0xff0000;
\r
95 * Initializes a new instance of the SqlDecimal instance using the supplied double value.
\r
96 * @param value The double value to be stored as a SqlDecimal instance.
\r
98 public SqlDecimal(double value)
\r
100 _value = new Decimal(value);
\r
102 int[] bits = Decimal.GetBits(_value);
\r
103 int i = bits[3] & 0xff0000;
\r
109 * Initializes a new instance of the SqlDecimal instance using the supplied int value.
\r
110 * @param value The int value to be stored as a SqlDecimal instance.
\r
112 public SqlDecimal(int value)
\r
114 _value = new Decimal(value);
\r
116 int[] bits = Decimal.GetBits(_value);
\r
117 int i = bits[3] & 0xff0000;
\r
123 * Initializes a new instance of the SqlDecimal instance using the supplied long value.
\r
124 * @param value The long value to be stored as a SqlDecimal instance.
\r
126 public SqlDecimal(long value)
\r
128 _value = new Decimal(value);
\r
130 int[] bits = Decimal.GetBits(_value);
\r
131 int i = bits[3] & 0xff0000;
\r
138 * Indicates whether or not Value is null.
\r
139 * @return true if Value is null, otherwise false.
\r
150 * Gets the value of the SqlDecimal instance.
\r
151 * @return the value of this instance
\r
153 public Decimal Value
\r
158 throw new SqlNullValueException();
\r
163 public byte[] BinData
\r
167 /** @todo implement this method */
\r
168 throw new NotImplementedException();
\r
176 /** @todo implement this method */
\r
177 throw new NotImplementedException();
\r
182 * Indicates whether or not the Value of this SqlDecimal instance is greater than zero.
\r
183 * @return true if the Value is assigned to null, otherwise false.
\r
185 public bool IsPositive
\r
197 throw new SqlNullValueException("The value of this instance is null");
\r
202 * Gets the maximum number of digits used to represent the Value property.
\r
203 * @return The maximum number of digits used to represent the Value of this SqlDecimal instance.
\r
205 public int Precision
\r
214 * Gets the number of decimal places to which Value is resolved.
\r
215 * @return The number of decimal places to which the Value property is resolved.
\r
226 * The Abs member function gets the absolute value of the SqlDecimal parameter.
\r
227 * @param n A SqlDecimal instance.
\r
228 * @return A SqlDecimal instance whose Value property contains the unsigned number representing the absolute value of the SqlDecimal parameter.
\r
230 public static SqlDecimal Abs(SqlDecimal n)
\r
233 return new SqlDecimal();
\r
240 val = Decimal.Negate(n._value);
\r
242 return new SqlDecimal(val);
\r
247 * Calcuates the sum of the two SqlDecimal operators.
\r
248 * @param x A SqlDecimal instance.
\r
249 * @param y A SqlDecimal instance.
\r
250 * @return A new SqlDecimal instance whose Value property contains the sum.
\r
251 * If one of the parameters or their value is null return SqlDecimal.Null.
\r
253 public static SqlDecimal Add(SqlDecimal x, SqlDecimal y)
\r
255 if (x.IsNull || y.IsNull)
\r
256 return SqlDecimal.Null;
\r
258 Decimal res = Decimal.Add(x._value, y._value);
\r
260 return new SqlDecimal(res);
\r
263 public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fround)
\r
265 /** @todo find out what the logic */
\r
266 throw new NotImplementedException();
\r
270 * Returns the smallest whole number greater than or equal to the specified SqlDecimal instance.
\r
271 * @param n The SqlDecimal instance for which the ceiling value is to be calculated.
\r
272 * @return A SqlDecimal representing the smallest whole number greater than or equal to the specified SqlDecimal instance.
\r
274 public static SqlDecimal Ceiling(SqlDecimal n)
\r
277 return SqlDecimal.Null;
\r
279 double d = Math.Ceiling((double)n._value);
\r
280 return new SqlDecimal(d);
\r
284 * Compares this instance to the supplied object and returns an indication of their relative values.
\r
285 * @param obj The object to compare.
\r
286 * @return A signed number indicating the relative values of the instance and the object.
\r
287 * Less than zero This instance is less than object.
\r
288 * Zero This instance is the same as object.
\r
289 * Greater than zero This instance is greater than object -or-
\r
290 * object is a null reference.
\r
292 public int CompareTo(Object obj)
\r
297 if (obj is SqlDecimal)
\r
299 SqlDecimal value = (SqlDecimal)obj;
\r
307 if (_value == value._value)
\r
310 return Decimal.Compare(_value, value._value);
\r
313 throw new ArgumentException("parameter obj is not SqlDecimal : " + obj.GetType().Name);
\r
319 public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
\r
321 /** @todo find out what the logic */
\r
322 throw new NotImplementedException();
\r
326 * The division operator divides the first SqlDecimal operand by the second.
\r
327 * @param x A SqlDecimal instance.
\r
328 * @param y A SqlDecimal instance.
\r
329 * @return A SqlDecimal instance containing the results of the division operation.
\r
330 * If one of the parameters is null or null value - return SqlDouble.Null.
\r
332 public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y)
\r
334 if (x.IsNull || y.IsNull)
\r
335 return SqlDecimal.Null;
\r
337 Decimal res = Decimal.Divide(x._value, y._value);
\r
339 return new SqlDecimal(res);
\r
342 public override bool Equals(Object obj)
\r
347 if (obj is SqlDecimal)
\r
349 SqlDecimal dec = (SqlDecimal)obj;
\r
351 return Decimal.Equals(_value, dec._value);
\r
359 * Performs a logical comparison on two instances of SqlDecimal to determine if they are equal.
\r
360 * @param x A SqlDecimal instance.
\r
361 * @param y A SqlDecimal instance.
\r
362 * @return true if the two values are equal, otherwise false.
\r
363 * If one of the parameters is null or null value return SqlBoolean.Null.
\r
365 public static SqlBoolean Equals(SqlDecimal x, SqlDecimal y)
\r
367 if (x.IsNull || y.IsNull)
\r
368 return SqlBoolean.Null;
\r
371 return SqlBoolean.True;
\r
373 return SqlBoolean.False;
\r
377 * Rounds a specified SqlDecimal number to the next lower whole number.
\r
378 * @param n The SqlDecimal instance for which the floor value is to be calculated.
\r
379 * @return A SqlDecimal instance containing the whole number portion of this SqlDecimal instance.
\r
381 public static SqlDecimal Floor(SqlDecimal n)
\r
383 Decimal res = Decimal.Floor(n._value);
\r
385 return new SqlDecimal(res);
\r
389 * Compares two instances of SqlDecimal to determine if the first is greater than the second.
\r
390 * @param x A SqlDecimal instance
\r
391 * @param y A SqlDecimal instance
\r
392 * @return A SqlBoolean that is True if the first instance is greater than the second instance, otherwise False.
\r
393 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
395 public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y)
\r
397 if (x.IsNull || y.IsNull)
\r
398 return SqlBoolean.Null;
\r
400 if (x.CompareTo(y) > 0)
\r
401 return SqlBoolean.True;
\r
403 return SqlBoolean.False;
\r
407 * Compares two instances of SqlDecimal to determine if the first is greater than or equal to the second.
\r
408 * @param x A SqlDecimal instance
\r
409 * @param y A SqlDecimal instance
\r
410 * @return A SqlBoolean that is True if the first instance is greaater than or equal to the second instance, otherwise False.
\r
411 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
413 public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y)
\r
415 if (x.IsNull || y.IsNull)
\r
416 return SqlBoolean.Null;
\r
418 if (x.CompareTo(y) >= 0)
\r
419 return SqlBoolean.True;
\r
421 return SqlBoolean.False;
\r
425 * Compares two instances of SqlDecimal to determine if the first is less than the second.
\r
426 * @param x A SqlDecimal instance
\r
427 * @param y A SqlDecimal instance
\r
428 * @return A SqlBoolean that is True if the first instance is less than the second instance, otherwise False.
\r
429 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
431 public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y)
\r
433 if (x.IsNull || y.IsNull)
\r
434 return SqlBoolean.Null;
\r
436 if (x.CompareTo(y) < 0)
\r
437 return SqlBoolean.True;
\r
439 return SqlBoolean.False;
\r
443 * Compares two instances of SqlDecimal to determine if the first is less than the second.
\r
444 * @param x A SqlDecimal instance
\r
445 * @param y A SqlDecimal instance
\r
446 * @return A SqlBoolean that is True if the first instance is less than the second instance, otherwise False.
\r
447 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
449 public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y)
\r
451 if (x.IsNull || y.IsNull)
\r
452 return SqlBoolean.Null;
\r
454 if (x.CompareTo(y) <= 0)
\r
455 return SqlBoolean.True;
\r
457 return SqlBoolean.False;
\r
461 * The multiplication operator computes the product of the two SqlDecimal operands.
\r
462 * @param x A SqlDecimal instance
\r
463 * @param y A SqlDecimal instance
\r
464 * @return The product of the two SqlDecimal operands.
\r
466 public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y)
\r
468 if (x.IsNull || y.IsNull)
\r
469 return SqlDecimal.Null;
\r
471 Decimal res = Decimal.Multiply(x._value, y._value);
\r
473 return new SqlDecimal(res);
\r
477 * Compares two instances of SqlDecimal to determine if they are equal.
\r
478 * @param x A SqlDecimal instance
\r
479 * @param y A SqlDecimal instance
\r
480 * @return A SqlBoolean that is True if the two instances are not equal or False if the two instances are equal.
\r
481 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
483 public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y)
\r
485 SqlBoolean eVal = Equals(x, y);
\r
490 return SqlBoolean.False;
\r
492 return SqlBoolean.True;
\r
496 * Converts the String representation of a number to its Decimal number equivalent.
\r
497 * @param s The String to be parsed.
\r
498 * @return A SqlDecimal containing the value represented by the String.
\r
500 public static SqlDecimal Parse(String s)
\r
502 Decimal val = Decimal.Parse(s);
\r
503 SqlDecimal retVal = new SqlDecimal(val);
\r
505 if (GreaterThan(retVal, MaxValue).IsTrue || LessThan(retVal, MinValue).IsTrue)
\r
506 throw new OverflowException("The parse of this string is overflowing : " + val);
\r
513 * Raises the value of the specified SqlDecimal instance to the specified exponential power.
\r
514 * @param n The SqlDecimal instance to be raised to a power.
\r
515 * @param exponent A double value indicating the power to which the number should be raised.
\r
516 * @return A SqlDecimal instance containing the results.
\r
518 public static SqlDecimal Power(SqlDecimal n, double exponent)
\r
520 /** @todo decide if we treat the Decimal as a double and use Math.pow() */
\r
522 double d = (double)n._value;
\r
524 d = java.lang.Math.pow(d, exponent);
\r
526 return new SqlDecimal(d);
\r
530 * Gets the number nearest the specified SqlDecimal instance's value with the specified precision.
\r
531 * @param n The SqlDecimal instance to be rounded.
\r
532 * @param position The number of significant fractional digits (precision) in the return value.
\r
533 * @return A SqlDecimal instance containing the results of the rounding operation.
\r
535 public static SqlDecimal Round(SqlDecimal n, int position)
\r
537 Decimal val = Decimal.Round(n._value, position);
\r
539 return new SqlDecimal(val);
\r
543 * Gets a value indicating the sign of a SqlDecimal instance's Value property.
\r
544 * @param n The SqlDecimal instance whose sign is to be evaluated.
\r
545 * @return A number indicating the sign of the SqlDecimal instance.
\r
547 public static int Sign(SqlDecimal n)
\r
557 * The subtraction operator the second SqlDecimal operand from the first.
\r
558 * @param x A SqlDecimal instance
\r
559 * @param y A SqlDecimal instance
\r
560 * @return The results of the subtraction operation.
\r
562 public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y)
\r
564 Decimal val = Decimal.Subtract(x._value, y._value);
\r
565 SqlDecimal retVal = new SqlDecimal(val);
\r
572 * Returns the a double equal to the contents of the Value property of this instance.
\r
573 * @return The decimal representation of the Value property.
\r
575 public double ToDouble()
\r
577 return Decimal.ToDouble(_value);
\r
581 * Converts this SqlDecimal instance to SqlBoolean.
\r
582 * @return A SqlBoolean instance whose Value will be True if the SqlDecimal instance's Value is non-zero,
\r
583 * False if the SqlDecimal is zero
\r
584 * and Null if the SqlDecimal instance is Null.
\r
586 public SqlBoolean ToSqlBoolean()
\r
589 return SqlBoolean.Null;
\r
591 return new SqlBoolean(!_value.Equals(Decimal.Zero));
\r
595 * Converts this SqlDecimal instance to SqlByte.
\r
596 * @return A SqlByte instance whose Value equals the Value of this SqlDouble instance.
\r
598 public SqlByte ToSqlByte()
\r
601 return SqlByte.Null;
\r
603 return new SqlByte(checked((byte)_value));
\r
607 * Converts this SqlDecimal instance to SqlDouble.
\r
608 * @return A SqlDouble instance whose Value equals the Value of this SqlDecimal instance.
\r
610 public SqlDouble ToSqlDouble()
\r
613 return SqlDouble.Null;
\r
615 return new SqlDouble((double)_value);
\r
619 * Converts this SqlDouble structure to SqlInt16.
\r
620 * @return A SqlInt16 structure whose Value equals the Value of this SqlDouble structure.
\r
622 public SqlInt16 ToSqlInt16()
\r
625 return SqlInt16.Null;
\r
627 return new SqlInt16(checked((short)_value));
\r
631 * Converts this SqlDouble structure to SqlInt32.
\r
632 * @return A SqlInt32 structure whose Value equals the Value of this SqlDouble structure.
\r
634 public SqlInt32 ToSqlInt32()
\r
637 return SqlInt32.Null;
\r
639 return new SqlInt32(checked((int)_value));
\r
643 * Converts this SqlDecimal structure to SqlInt64.
\r
644 * @return A SqlInt64 structure whose Value equals the Value of this SqlDecimal structure.
\r
646 public SqlInt64 ToSqlInt64()
\r
649 return SqlInt64.Null;
\r
651 return new SqlInt64(checked((long)_value));
\r
655 * Converts this SqlDecimal instance to SqlDouble.
\r
656 * @return A SqlMoney instance whose Value equals the Value of this SqlDecimal instance.
\r
658 public SqlMoney ToSqlMoney()
\r
661 return SqlMoney.Null;
\r
663 return new SqlMoney(_value);
\r
667 * Converts this SqlDecimal instance to SqlSingle.
\r
668 * @return A SqlSingle instance whose Value equals the Value of this SqlDecimal instance.
\r
670 public SqlSingle ToSqlSingle()
\r
673 return SqlSingle.Null;
\r
675 return new SqlSingle(checked((float)_value));
\r
679 * Converts this SqlDecimal structure to SqlString.
\r
680 * @return A SqlString structure whose value is a string representing the date and time contained in this SqlDecimal structure.
\r
682 public SqlString ToSqlString()
\r
684 return new SqlString(ToString());
\r
688 public override String ToString()
\r
693 return _value.ToString();
\r
697 * Truncates the specified SqlDecimal instance's value to the desired position.
\r
698 * @param n The SqlDecimal instance to be truncated.
\r
699 * @param position The decimal position to which the number will be truncated.
\r
700 * @return Supply a negative value for the position parameter in order to truncate the value to the corresponding positon to the left of the decimal point.
\r
702 public static SqlDecimal Truncate(SqlDecimal n, int position)
\r
707 Decimal tmp = Decimal.Round(n._value, position);
\r
709 return new SqlDecimal(tmp);
\r
712 public override int GetHashCode()
\r
714 return _value.GetHashCode();
\r
717 public static SqlDecimal operator + (SqlDecimal x, SqlDecimal y)
\r
719 if(x.IsNull || y.IsNull)
\r
720 return SqlDecimal.Null;
\r
722 return new SqlDecimal(x.Value + y.Value);
\r
725 public static SqlDecimal operator / (SqlDecimal x, SqlDecimal y)
\r
727 if(x.IsNull || y.IsNull)
\r
728 return SqlDecimal.Null;
\r
729 return new SqlDecimal (x.Value / y.Value);
\r
732 public static SqlBoolean operator == (SqlDecimal x, SqlDecimal y)
\r
734 if (x.IsNull || y.IsNull)
\r
735 return SqlBoolean.Null;
\r
737 return new SqlBoolean(x.Value == y.Value);
\r
740 public static SqlBoolean operator > (SqlDecimal x, SqlDecimal y)
\r
742 if (x.IsNull || y.IsNull)
\r
743 return SqlBoolean.Null;
\r
745 return new SqlBoolean(x.Value > y.Value);
\r
748 public static SqlBoolean operator >= (SqlDecimal x, SqlDecimal y)
\r
750 if (x.IsNull || y.IsNull)
\r
751 return SqlBoolean.Null;
\r
753 return new SqlBoolean(x.Value >= y.Value);
\r
756 public static SqlBoolean operator != (SqlDecimal x, SqlDecimal y)
\r
758 if (x.IsNull || y.IsNull)
\r
759 return SqlBoolean.Null;
\r
761 return new SqlBoolean(x.Value != y.Value);
\r
764 public static SqlBoolean operator < (SqlDecimal x, SqlDecimal y)
\r
767 if (x.IsNull || y.IsNull)
\r
768 return SqlBoolean.Null;
\r
770 return new SqlBoolean(x.Value < y.Value);
\r
774 public static SqlBoolean operator <= (SqlDecimal x, SqlDecimal y)
\r
776 if (x.IsNull || y.IsNull)
\r
777 return SqlBoolean.Null;
\r
779 return new SqlBoolean(x.Value <= y.Value);
\r
782 public static SqlDecimal operator * (SqlDecimal x, SqlDecimal y)
\r
784 // adjust the scale to the smaller of the two beforehand
\r
785 if (x.Scale > y.Scale)
\r
786 x = SqlDecimal.AdjustScale(x, y.Scale - x.Scale, true);
\r
787 else if (y.Scale > x.Scale)
\r
788 y = SqlDecimal.AdjustScale(y, x.Scale - y.Scale, true);
\r
790 return new SqlDecimal(x.Value * y.Value);
\r
793 public static SqlDecimal operator - (SqlDecimal x, SqlDecimal y)
\r
795 if(x.IsNull || y.IsNull)
\r
796 return SqlDecimal.Null;
\r
798 return new SqlDecimal(x.Value - y.Value);
\r
801 public static SqlDecimal operator - (SqlDecimal n)
\r
805 return new SqlDecimal (Decimal.Negate(n.Value));
\r
808 public static explicit operator SqlDecimal (SqlBoolean x)
\r
813 return new SqlDecimal ((decimal)x.ByteValue);
\r
816 public static explicit operator Decimal (SqlDecimal n)
\r
821 public static explicit operator SqlDecimal (SqlDouble x)
\r
828 return new SqlDecimal ((decimal)x.Value);
\r
832 public static explicit operator SqlDecimal (SqlSingle x)
\r
839 return new SqlDecimal ((decimal)x.Value);
\r
843 public static explicit operator SqlDecimal (SqlString x)
\r
847 return Parse (x.Value);
\r
851 public static implicit operator SqlDecimal (decimal x)
\r
853 return new SqlDecimal (x);
\r
856 public static implicit operator SqlDecimal (SqlByte x)
\r
861 return new SqlDecimal ((decimal)x.Value);
\r
864 public static implicit operator SqlDecimal (SqlInt16 x)
\r
869 return new SqlDecimal ((decimal)x.Value);
\r
872 public static implicit operator SqlDecimal (SqlInt32 x)
\r
877 return new SqlDecimal ((decimal)x.Value);
\r
880 public static implicit operator SqlDecimal (SqlInt64 x)
\r
885 return new SqlDecimal ((decimal)x.Value);
\r
888 public static implicit operator SqlDecimal (SqlMoney x)
\r
893 return new SqlDecimal ((decimal)x.Value);
\r