2 * Copyright (c) 2002-2004 Mainsoft Corporation.
\r
4 * Permission is hereby granted, free of charge, to any person obtaining a
\r
5 * copy of this software and associated documentation files (the "Software"),
\r
6 * to deal in the Software without restriction, including without limitation
\r
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
8 * and/or sell copies of the Software, and to permit persons to whom the
\r
9 * Software is furnished to do so, subject to the following conditions:
\r
11 * The above copyright notice and this permission notice shall be included in
\r
12 * all copies or substantial portions of the Software.
\r
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
20 * DEALINGS IN THE SOFTWARE.
\r
23 namespace System.Data.SqlTypes
\r
28 * <p>Description: </p>
\r
29 * <p>Copyright: Copyright (c) 2002</p>
\r
30 * <p>Company: MainSoft</p>
\r
31 * @author Pavel Sandler
\r
40 * CURRENT LIMITATIONS:
\r
41 * 1. public byte[] Data not implemented.
\r
42 * 2. public byte[] BinData not implemented.
\r
43 * 3. Precision value is ignored.
\r
44 * 4. public SqlDecimal AdjustScale(SqlDecimal n, int position) not implemented.
\r
45 * 5. public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale) not implemented.
\r
49 public struct SqlDecimal : INullable
\r
52 private Decimal _value;
\r
53 private bool _isNull;
\r
55 public static readonly SqlDecimal MaxValue = new SqlDecimal(Decimal.MaxValue);
\r
56 public static readonly SqlDecimal MinValue = new SqlDecimal(Decimal.MinValue);
\r
57 public static readonly int MaxPrecision = 38;
\r
58 public static readonly int MaxScale = MaxPrecision;
\r
59 public static readonly SqlDecimal Null = new SqlDecimal(true);
\r
61 private int _precision;
\r
65 private SqlDecimal(bool isNull)
\r
67 _value = Decimal.Zero;
\r
73 * Initializes a new instance of the SqlDecimal instance using the supplied Decimal value.
\r
74 * @param value The Decimal value to be stored as a SqlDecimal instance.
\r
76 public SqlDecimal(Decimal value)
\r
80 int[] bits = Decimal.GetBits(value);
\r
81 int i = bits[3] & 0xff0000;
\r
87 * Initializes a new instance of the SqlDecimal instance using the supplied double value.
\r
88 * @param value The double value to be stored as a SqlDecimal instance.
\r
90 public SqlDecimal(double value)
\r
92 _value = new Decimal(value);
\r
94 int[] bits = Decimal.GetBits(_value);
\r
95 int i = bits[3] & 0xff0000;
\r
101 * Initializes a new instance of the SqlDecimal instance using the supplied int value.
\r
102 * @param value The int value to be stored as a SqlDecimal instance.
\r
104 public SqlDecimal(int value)
\r
106 _value = new Decimal(value);
\r
108 int[] bits = Decimal.GetBits(_value);
\r
109 int i = bits[3] & 0xff0000;
\r
115 * Initializes a new instance of the SqlDecimal instance using the supplied long value.
\r
116 * @param value The long value to be stored as a SqlDecimal instance.
\r
118 public SqlDecimal(long value)
\r
120 _value = new Decimal(value);
\r
122 int[] bits = Decimal.GetBits(_value);
\r
123 int i = bits[3] & 0xff0000;
\r
130 * Indicates whether or not Value is null.
\r
131 * @return true if Value is null, otherwise false.
\r
142 * Gets the value of the SqlDecimal instance.
\r
143 * @return the value of this instance
\r
145 public Decimal Value
\r
150 throw new SqlNullValueException();
\r
155 public byte[] BinData
\r
159 /** @todo implement this method */
\r
160 throw new NotImplementedException();
\r
168 /** @todo implement this method */
\r
169 throw new NotImplementedException();
\r
174 * Indicates whether or not the Value of this SqlDecimal instance is greater than zero.
\r
175 * @return true if the Value is assigned to null, otherwise false.
\r
177 public bool IsPositive
\r
189 throw new SqlNullValueException("The value of this instance is null");
\r
194 * Gets the maximum number of digits used to represent the Value property.
\r
195 * @return The maximum number of digits used to represent the Value of this SqlDecimal instance.
\r
197 public int Precision
\r
206 * Gets the number of decimal places to which Value is resolved.
\r
207 * @return The number of decimal places to which the Value property is resolved.
\r
218 * The Abs member function gets the absolute value of the SqlDecimal parameter.
\r
219 * @param n A SqlDecimal instance.
\r
220 * @return A SqlDecimal instance whose Value property contains the unsigned number representing the absolute value of the SqlDecimal parameter.
\r
222 public static SqlDecimal Abs(SqlDecimal n)
\r
225 return new SqlDecimal();
\r
232 val = Decimal.Negate(n._value);
\r
234 return new SqlDecimal(val);
\r
239 * Calcuates the sum of the two SqlDecimal operators.
\r
240 * @param x A SqlDecimal instance.
\r
241 * @param y A SqlDecimal instance.
\r
242 * @return A new SqlDecimal instance whose Value property contains the sum.
\r
243 * If one of the parameters or their value is null return SqlDecimal.Null.
\r
245 public static SqlDecimal Add(SqlDecimal x, SqlDecimal y)
\r
247 if (x.IsNull || y.IsNull)
\r
248 return SqlDecimal.Null;
\r
250 Decimal res = Decimal.Add(x._value, y._value);
\r
252 return new SqlDecimal(res);
\r
255 public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fround)
\r
257 /** @todo find out what the logic */
\r
258 throw new NotImplementedException();
\r
262 * Returns the smallest whole number greater than or equal to the specified SqlDecimal instance.
\r
263 * @param n The SqlDecimal instance for which the ceiling value is to be calculated.
\r
264 * @return A SqlDecimal representing the smallest whole number greater than or equal to the specified SqlDecimal instance.
\r
266 public static SqlDecimal Ceiling(SqlDecimal n)
\r
269 return SqlDecimal.Null;
\r
271 double d = Math.Ceiling((double)n._value);
\r
272 return new SqlDecimal(d);
\r
276 * Compares this instance to the supplied object and returns an indication of their relative values.
\r
277 * @param obj The object to compare.
\r
278 * @return A signed number indicating the relative values of the instance and the object.
\r
279 * Less than zero This instance is less than object.
\r
280 * Zero This instance is the same as object.
\r
281 * Greater than zero This instance is greater than object -or-
\r
282 * object is a null reference.
\r
284 public int CompareTo(Object obj)
\r
289 if (obj is SqlDecimal)
\r
291 SqlDecimal value = (SqlDecimal)obj;
\r
299 if (_value == value._value)
\r
302 return Decimal.Compare(_value, value._value);
\r
305 throw new ArgumentException("parameter obj is not SqlDecimal : " + obj.GetType().Name);
\r
311 public SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
\r
313 /** @todo find out what the logic */
\r
314 throw new NotImplementedException();
\r
318 * The division operator divides the first SqlDecimal operand by the second.
\r
319 * @param x A SqlDecimal instance.
\r
320 * @param y A SqlDecimal instance.
\r
321 * @return A SqlDecimal instance containing the results of the division operation.
\r
322 * If one of the parameters is null or null value - return SqlDouble.Null.
\r
324 public static SqlDecimal Divide(SqlDecimal x, SqlDecimal y)
\r
326 if (x.IsNull || y.IsNull)
\r
327 return SqlDecimal.Null;
\r
329 Decimal res = Decimal.Divide(x._value, y._value);
\r
331 return new SqlDecimal(res);
\r
334 public override bool Equals(Object obj)
\r
339 if (obj is SqlDecimal)
\r
341 SqlDecimal dec = (SqlDecimal)obj;
\r
343 return Decimal.Equals(_value, dec._value);
\r
351 * Performs a logical comparison on two instances of SqlDecimal to determine if they are equal.
\r
352 * @param x A SqlDecimal instance.
\r
353 * @param y A SqlDecimal instance.
\r
354 * @return true if the two values are equal, otherwise false.
\r
355 * If one of the parameters is null or null value return SqlBoolean.Null.
\r
357 public static SqlBoolean Equals(SqlDecimal x, SqlDecimal y)
\r
359 if (x.IsNull || y.IsNull)
\r
360 return SqlBoolean.Null;
\r
363 return SqlBoolean.True;
\r
365 return SqlBoolean.False;
\r
369 * Rounds a specified SqlDecimal number to the next lower whole number.
\r
370 * @param n The SqlDecimal instance for which the floor value is to be calculated.
\r
371 * @return A SqlDecimal instance containing the whole number portion of this SqlDecimal instance.
\r
373 public static SqlDecimal Floor(SqlDecimal n)
\r
375 Decimal res = Decimal.Floor(n._value);
\r
377 return new SqlDecimal(res);
\r
381 * Compares two instances of SqlDecimal to determine if the first is greater than the second.
\r
382 * @param x A SqlDecimal instance
\r
383 * @param y A SqlDecimal instance
\r
384 * @return A SqlBoolean that is True if the first instance is greater than the second instance, otherwise False.
\r
385 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
387 public static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y)
\r
389 if (x.IsNull || y.IsNull)
\r
390 return SqlBoolean.Null;
\r
392 if (x.CompareTo(y) > 0)
\r
393 return SqlBoolean.True;
\r
395 return SqlBoolean.False;
\r
399 * Compares two instances of SqlDecimal to determine if the first is greater than or equal to the second.
\r
400 * @param x A SqlDecimal instance
\r
401 * @param y A SqlDecimal instance
\r
402 * @return A SqlBoolean that is True if the first instance is greaater than or equal to the second instance, otherwise False.
\r
403 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
405 public static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y)
\r
407 if (x.IsNull || y.IsNull)
\r
408 return SqlBoolean.Null;
\r
410 if (x.CompareTo(y) >= 0)
\r
411 return SqlBoolean.True;
\r
413 return SqlBoolean.False;
\r
417 * Compares two instances of SqlDecimal to determine if the first is less than the second.
\r
418 * @param x A SqlDecimal instance
\r
419 * @param y A SqlDecimal instance
\r
420 * @return A SqlBoolean that is True if the first instance is less than the second instance, otherwise False.
\r
421 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
423 public static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y)
\r
425 if (x.IsNull || y.IsNull)
\r
426 return SqlBoolean.Null;
\r
428 if (x.CompareTo(y) < 0)
\r
429 return SqlBoolean.True;
\r
431 return SqlBoolean.False;
\r
435 * Compares two instances of SqlDecimal to determine if the first is less than the second.
\r
436 * @param x A SqlDecimal instance
\r
437 * @param y A SqlDecimal instance
\r
438 * @return A SqlBoolean that is True if the first instance is less than the second instance, otherwise False.
\r
439 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
441 public static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y)
\r
443 if (x.IsNull || y.IsNull)
\r
444 return SqlBoolean.Null;
\r
446 if (x.CompareTo(y) <= 0)
\r
447 return SqlBoolean.True;
\r
449 return SqlBoolean.False;
\r
453 * The multiplication operator computes the product of the two SqlDecimal operands.
\r
454 * @param x A SqlDecimal instance
\r
455 * @param y A SqlDecimal instance
\r
456 * @return The product of the two SqlDecimal operands.
\r
458 public static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y)
\r
460 if (x.IsNull || y.IsNull)
\r
461 return SqlDecimal.Null;
\r
463 Decimal res = Decimal.Multiply(x._value, y._value);
\r
465 return new SqlDecimal(res);
\r
469 * Compares two instances of SqlDecimal to determine if they are equal.
\r
470 * @param x A SqlDecimal instance
\r
471 * @param y A SqlDecimal instance
\r
472 * @return A SqlBoolean that is True if the two instances are not equal or False if the two instances are equal.
\r
473 * If either instance of SqlDouble is null, the Value of the SqlBoolean will be Null.
\r
475 public static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y)
\r
477 SqlBoolean eVal = Equals(x, y);
\r
482 return SqlBoolean.False;
\r
484 return SqlBoolean.True;
\r
488 * Converts the String representation of a number to its Decimal number equivalent.
\r
489 * @param s The String to be parsed.
\r
490 * @return A SqlDecimal containing the value represented by the String.
\r
492 public static SqlDecimal Parse(String s)
\r
494 Decimal val = Decimal.Parse(s);
\r
495 SqlDecimal retVal = new SqlDecimal(val);
\r
497 if (GreaterThan(retVal, MaxValue).IsTrue || LessThan(retVal, MinValue).IsTrue)
\r
498 throw new OverflowException("The parse of this string is overflowing : " + val);
\r
505 * Raises the value of the specified SqlDecimal instance to the specified exponential power.
\r
506 * @param n The SqlDecimal instance to be raised to a power.
\r
507 * @param exponent A double value indicating the power to which the number should be raised.
\r
508 * @return A SqlDecimal instance containing the results.
\r
510 public static SqlDecimal Power(SqlDecimal n, double exponent)
\r
512 /** @todo decide if we treat the Decimal as a double and use Math.pow() */
\r
514 double d = (double)n._value;
\r
516 d = java.lang.Math.pow(d, exponent);
\r
518 return new SqlDecimal(d);
\r
522 * Gets the number nearest the specified SqlDecimal instance's value with the specified precision.
\r
523 * @param n The SqlDecimal instance to be rounded.
\r
524 * @param position The number of significant fractional digits (precision) in the return value.
\r
525 * @return A SqlDecimal instance containing the results of the rounding operation.
\r
527 public static SqlDecimal Round(SqlDecimal n, int position)
\r
529 Decimal val = Decimal.Round(n._value, position);
\r
531 return new SqlDecimal(val);
\r
535 * Gets a value indicating the sign of a SqlDecimal instance's Value property.
\r
536 * @param n The SqlDecimal instance whose sign is to be evaluated.
\r
537 * @return A number indicating the sign of the SqlDecimal instance.
\r
539 public static int Sign(SqlDecimal n)
\r
549 * The subtraction operator the second SqlDecimal operand from the first.
\r
550 * @param x A SqlDecimal instance
\r
551 * @param y A SqlDecimal instance
\r
552 * @return The results of the subtraction operation.
\r
554 public static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y)
\r
556 Decimal val = Decimal.Subtract(x._value, y._value);
\r
557 SqlDecimal retVal = new SqlDecimal(val);
\r
564 * Returns the a double equal to the contents of the Value property of this instance.
\r
565 * @return The decimal representation of the Value property.
\r
567 public double ToDouble()
\r
569 return Decimal.ToDouble(_value);
\r
573 * Converts this SqlDecimal instance to SqlBoolean.
\r
574 * @return A SqlBoolean instance whose Value will be True if the SqlDecimal instance's Value is non-zero,
\r
575 * False if the SqlDecimal is zero
\r
576 * and Null if the SqlDecimal instance is Null.
\r
578 public SqlBoolean ToSqlBoolean()
\r
581 return SqlBoolean.Null;
\r
583 return new SqlBoolean(!_value.Equals(Decimal.Zero));
\r
587 * Converts this SqlDecimal instance to SqlByte.
\r
588 * @return A SqlByte instance whose Value equals the Value of this SqlDouble instance.
\r
590 public SqlByte ToSqlByte()
\r
593 return SqlByte.Null;
\r
595 return new SqlByte(checked((byte)_value));
\r
599 * Converts this SqlDecimal instance to SqlDouble.
\r
600 * @return A SqlDouble instance whose Value equals the Value of this SqlDecimal instance.
\r
602 public SqlDouble ToSqlDouble()
\r
605 return SqlDouble.Null;
\r
607 return new SqlDouble((double)_value);
\r
611 * Converts this SqlDouble structure to SqlInt16.
\r
612 * @return A SqlInt16 structure whose Value equals the Value of this SqlDouble structure.
\r
614 public SqlInt16 ToSqlInt16()
\r
617 return SqlInt16.Null;
\r
619 return new SqlInt16(checked((short)_value));
\r
623 * Converts this SqlDouble structure to SqlInt32.
\r
624 * @return A SqlInt32 structure whose Value equals the Value of this SqlDouble structure.
\r
626 public SqlInt32 ToSqlInt32()
\r
629 return SqlInt32.Null;
\r
631 return new SqlInt32(checked((int)_value));
\r
635 * Converts this SqlDecimal structure to SqlInt64.
\r
636 * @return A SqlInt64 structure whose Value equals the Value of this SqlDecimal structure.
\r
638 public SqlInt64 ToSqlInt64()
\r
641 return SqlInt64.Null;
\r
643 return new SqlInt64(checked((long)_value));
\r
647 * Converts this SqlDecimal instance to SqlDouble.
\r
648 * @return A SqlMoney instance whose Value equals the Value of this SqlDecimal instance.
\r
650 public SqlMoney ToSqlMoney()
\r
653 return SqlMoney.Null;
\r
655 return new SqlMoney(_value);
\r
659 * Converts this SqlDecimal instance to SqlSingle.
\r
660 * @return A SqlSingle instance whose Value equals the Value of this SqlDecimal instance.
\r
662 public SqlSingle ToSqlSingle()
\r
665 return SqlSingle.Null;
\r
667 return new SqlSingle(checked((float)_value));
\r
671 * Converts this SqlDecimal structure to SqlString.
\r
672 * @return A SqlString structure whose value is a string representing the date and time contained in this SqlDecimal structure.
\r
674 public SqlString ToSqlString()
\r
676 return new SqlString(ToString());
\r
680 public override String ToString()
\r
685 return _value.ToString();
\r
689 * Truncates the specified SqlDecimal instance's value to the desired position.
\r
690 * @param n The SqlDecimal instance to be truncated.
\r
691 * @param position The decimal position to which the number will be truncated.
\r
692 * @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
694 public static SqlDecimal Truncate(SqlDecimal n, int position)
\r
699 Decimal tmp = Decimal.Round(n._value, position);
\r
701 return new SqlDecimal(tmp);
\r
704 public override int GetHashCode()
\r
706 return _value.GetHashCode();
\r
709 public static SqlDecimal operator + (SqlDecimal x, SqlDecimal y)
\r
711 if(x.IsNull || y.IsNull)
\r
712 return SqlDecimal.Null;
\r
714 return new SqlDecimal(x.Value + y.Value);
\r
717 public static SqlDecimal operator / (SqlDecimal x, SqlDecimal y)
\r
719 if(x.IsNull || y.IsNull)
\r
720 return SqlDecimal.Null;
\r
721 return new SqlDecimal (x.Value / y.Value);
\r
724 public static SqlBoolean operator == (SqlDecimal x, SqlDecimal y)
\r
726 if (x.IsNull || y.IsNull)
\r
727 return SqlBoolean.Null;
\r
729 return new SqlBoolean(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
759 if (x.IsNull || y.IsNull)
\r
760 return SqlBoolean.Null;
\r
762 return new SqlBoolean(x.Value < y.Value);
\r
766 public static SqlBoolean operator <= (SqlDecimal x, SqlDecimal y)
\r
768 if (x.IsNull || y.IsNull)
\r
769 return SqlBoolean.Null;
\r
771 return new SqlBoolean(x.Value <= y.Value);
\r
774 public static SqlDecimal operator * (SqlDecimal x, SqlDecimal y)
\r
776 // adjust the scale to the smaller of the two beforehand
\r
777 if (x.Scale > y.Scale)
\r
778 x = SqlDecimal.AdjustScale(x, y.Scale - x.Scale, true);
\r
779 else if (y.Scale > x.Scale)
\r
780 y = SqlDecimal.AdjustScale(y, x.Scale - y.Scale, true);
\r
782 return new SqlDecimal(x.Value * y.Value);
\r
785 public static SqlDecimal operator - (SqlDecimal x, SqlDecimal y)
\r
787 if(x.IsNull || y.IsNull)
\r
788 return SqlDecimal.Null;
\r
790 return new SqlDecimal(x.Value - y.Value);
\r
793 public static SqlDecimal operator - (SqlDecimal n)
\r
797 return new SqlDecimal (Decimal.Negate(n.Value));
\r
800 public static explicit operator SqlDecimal (SqlBoolean x)
\r
805 return new SqlDecimal ((decimal)x.ByteValue);
\r
808 public static explicit operator Decimal (SqlDecimal n)
\r
813 public static explicit operator SqlDecimal (SqlDouble x)
\r
820 return new SqlDecimal ((decimal)x.Value);
\r
824 public static explicit operator SqlDecimal (SqlSingle x)
\r
831 return new SqlDecimal ((decimal)x.Value);
\r
835 public static explicit operator SqlDecimal (SqlString x)
\r
839 return Parse (x.Value);
\r
843 public static implicit operator SqlDecimal (decimal x)
\r
845 return new SqlDecimal (x);
\r
848 public static implicit operator SqlDecimal (SqlByte x)
\r
853 return new SqlDecimal ((decimal)x.Value);
\r
856 public static implicit operator SqlDecimal (SqlInt16 x)
\r
861 return new SqlDecimal ((decimal)x.Value);
\r
864 public static implicit operator SqlDecimal (SqlInt32 x)
\r
869 return new SqlDecimal ((decimal)x.Value);
\r
872 public static implicit operator SqlDecimal (SqlInt64 x)
\r
877 return new SqlDecimal ((decimal)x.Value);
\r
880 public static implicit operator SqlDecimal (SqlMoney x)
\r
885 return new SqlDecimal ((decimal)x.Value);
\r