3 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 using System.Collections;
27 namespace Mono.Data.SqlExpressions {
28 internal class Numeric {
29 internal static bool IsNumeric (object o) {
30 if (o is IConvertible) {
31 TypeCode tc = ((IConvertible)o).GetTypeCode();
32 if(TypeCode.Char <= tc && tc <= TypeCode.Decimal)
38 //extends to Int32/Int64/Decimal/Double
39 internal static IConvertible Unify (IConvertible o)
41 switch (o.GetTypeCode()) {
47 return (IConvertible)Convert.ChangeType (o, TypeCode.Int32);
50 return (IConvertible)Convert.ChangeType (o, TypeCode.Int64);
53 return (IConvertible)Convert.ChangeType (o, TypeCode.Decimal);
56 return (IConvertible)Convert.ChangeType (o, TypeCode.Double);
63 //(note: o1 and o2 must both be of type Int32/Int64/Decimal/Double)
64 internal static void ToSameType (ref IConvertible o1, ref IConvertible o2)
66 TypeCode tc1 = o1.GetTypeCode();
67 TypeCode tc2 = o2.GetTypeCode();
72 // is it ok to make such assumptions about the order of an enum?
74 o1 = (IConvertible) Convert.ChangeType (o1, tc2);
76 o2 = (IConvertible) Convert.ChangeType (o2, tc1);
79 internal static IConvertible Add (IConvertible o1, IConvertible o2)
81 ToSameType (ref o1, ref o2);
82 switch (o1.GetTypeCode()) {
85 return (int)o1 + (int)o2;
87 return (long)o1 + (long)o2;
89 return (double)o1 + (double)o2;
90 case TypeCode.Decimal:
91 return (decimal)o1 + (decimal)o2;
95 internal static IConvertible Subtract (IConvertible o1, IConvertible o2)
97 ToSameType (ref o1, ref o2);
98 switch (o1.GetTypeCode()) {
101 return (int)o1 - (int)o2;
103 return (long)o1 - (long)o2;
104 case TypeCode.Double:
105 return (double)o1 - (double)o2;
106 case TypeCode.Decimal:
107 return (decimal)o1 - (decimal)o2;
111 internal static IConvertible Multiply (IConvertible o1, IConvertible o2)
113 ToSameType (ref o1, ref o2);
114 switch (o1.GetTypeCode()) {
117 return (int)o1 * (int)o2;
119 return (long)o1 * (long)o2;
120 case TypeCode.Double:
121 return (double)o1 * (double)o2;
122 case TypeCode.Decimal:
123 return (decimal)o1 * (decimal)o2;
127 internal static IConvertible Divide (IConvertible o1, IConvertible o2)
129 ToSameType (ref o1, ref o2);
130 switch (o1.GetTypeCode()) {
133 return (int)o1 / (int)o2;
135 return (long)o1 / (long)o2;
136 case TypeCode.Double:
137 return (double)o1 / (double)o2;
138 case TypeCode.Decimal:
139 return (decimal)o1 / (decimal)o2;
143 internal static IConvertible Modulo (IConvertible o1, IConvertible o2)
145 ToSameType (ref o1, ref o2);
146 switch (o1.GetTypeCode()) {
149 return (int)o1 % (int)o2;
151 return (long)o1 % (long)o2;
152 case TypeCode.Double:
153 return (double)o1 % (double)o2;
154 case TypeCode.Decimal:
155 return (decimal)o1 % (decimal)o2;
159 internal static IConvertible Negative (IConvertible o)
161 switch (o.GetTypeCode()) {
167 case TypeCode.Double:
169 case TypeCode.Decimal:
170 return -((decimal)o);
174 internal static IConvertible Min (IConvertible o1, IConvertible o2)
176 switch (o1.GetTypeCode()) {
179 return System.Math.Min ((int)o1, (int)o2);
181 return System.Math.Min ((long)o1, (long)o2);
182 case TypeCode.Double:
183 return System.Math.Min ((double)o1, (double)o2);
184 case TypeCode.Decimal:
185 return System.Math.Min ((decimal)o1, (decimal)o2);
189 internal static IConvertible Max (IConvertible o1, IConvertible o2)
191 switch (o1.GetTypeCode()) {
194 return System.Math.Max ((int)o1, (int)o2);
196 return System.Math.Max ((long)o1, (long)o2);
197 case TypeCode.Double:
198 return System.Math.Max ((double)o1, (double)o2);
199 case TypeCode.Decimal:
200 return System.Math.Max ((decimal)o1, (decimal)o2);