2002-03-18 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mcs / class / corlib / System / Double.cs
1 //
2 // System.Double.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Bob Smith       (bob@thestuff.net)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 // (C) Bob Smith.    http://www.thestuff.net
10 //
11
12 using System.Globalization;
13
14 namespace System {
15         
16         public struct Double : IComparable, IFormattable, IConvertible {
17                 public const double Epsilon = 4.9406564584124650e-324;
18                 public const double MaxValue =  1.7976931348623157e308;
19                 public const double MinValue = -1.7976931348623157e308;
20                 public const double NaN = 0.0d / 0.0d;
21                 public const double NegativeInfinity = -1.0d / 0.0d;
22                 public const double PositiveInfinity = 1.0d / 0.0d;
23                 
24                 // VES needs to know about value.  public is workaround
25                 // so source will compile
26                 public double value;
27
28                 public int CompareTo (object v)
29                 {
30                         if (v == null)
31                                 return 1;
32                         
33                         if (!(v is System.Double))
34                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Double"));
35
36                         if (IsPositiveInfinity(value) && IsPositiveInfinity((double) v)){
37                                 return 0;
38                         }
39
40                         if (IsNegativeInfinity(value) && IsNegativeInfinity((double) v)){
41                                 return 0;
42                         }
43
44                         if (IsNaN((double) v)) {
45                                 if (IsNaN(value))
46                                         return 0;
47                                 else
48                                         return 1;
49                         }
50
51                         return (int) (value - ((double) v));
52                 }
53
54                 public override bool Equals (object o)
55                 {
56                         if (!(o is System.Double))
57                                 return false;
58
59                         if (IsNaN ((double)o)) {
60                                 if (IsNaN(value))
61                                         return true;
62                                 else
63                                         return false;
64                         }
65
66                         return ((double) o) == value;
67                 }
68
69                 public override int GetHashCode ()
70                 {
71                         return (int) value;
72                 }
73
74                 public static bool IsInfinity (double d)
75                 {
76                         return (d == PositiveInfinity || d == NegativeInfinity);
77                 }
78
79                 public static bool IsNaN (double d)
80                 {
81                         return (d != d);
82                 }
83
84                 public static bool IsNegativeInfinity (double d)
85                 {
86                         return (d < 0.0d && (d == NegativeInfinity || d == PositiveInfinity));
87                 }
88
89                 public static bool IsPositiveInfinity (double d)
90                 {
91                         return (d > 0.0d && (d == NegativeInfinity || d == PositiveInfinity));
92                 }
93
94                 public static double Parse (string s)
95                 {
96                         return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), null);
97                 }
98
99                 public static double Parse (string s, IFormatProvider fp)
100                 {
101                         return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), fp);
102                 }
103
104                 public static double Parse (string s, NumberStyles style) 
105                 {
106                         return Parse (s, style, null);
107                 }
108
109                 public static double Parse (string s, NumberStyles style, IFormatProvider provider)
110                 {
111                         if (s == null) throw new ArgumentNullException();
112                         if (style > NumberStyles.Any)
113                         {
114                                 throw new ArgumentException();
115                         }
116                         NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);
117                         if (format == null) throw new Exception("How did this happen?");
118                         if (s == format.NaNSymbol) return Double.NaN;
119                         if (s == format.PositiveInfinitySymbol) return Double.PositiveInfinity;
120                         if (s == format.NegativeInfinitySymbol) return Double.NegativeInfinity;
121                         string[] sl;
122                         long integral = 0;
123                         long fraction = 0;
124                         long exponent = 1;
125                         double retval = 0;
126                         if ((style & NumberStyles.AllowLeadingWhite) != 0)
127                         {
128                                 s.TrimStart(null);
129                         }
130                         if ((style & NumberStyles.AllowTrailingWhite) != 0)
131                         {
132                                 s.TrimEnd(null);
133                         }
134                         sl = s.Split(new Char[] {'e', 'E'}, 2);
135                         if (sl.Length > 1)
136                         {
137                                 if ((style & NumberStyles.AllowExponent) == 0)
138                                 {
139                                         throw new FormatException();
140                                 }
141                                 exponent = long.Parse(sl[1], NumberStyles.AllowLeadingSign, format);
142                         }
143                         s = sl[0];
144                         sl = s.Split(format.NumberDecimalSeparator.ToCharArray(), 2);
145                         if (sl.Length > 1)
146                         {
147                                 if ((style & NumberStyles.AllowDecimalPoint) == 0)
148                                 {
149                                         throw new FormatException();
150                                 }
151                                 fraction = long.Parse(sl[1], NumberStyles.None, format);
152                         }
153                         NumberStyles tempstyle = NumberStyles.None;
154                         if ((style & NumberStyles.AllowLeadingSign) != 0){
155                                 tempstyle = NumberStyles.AllowLeadingSign;
156                         }
157                         integral = long.Parse(sl[0], tempstyle, format);
158                         retval = fraction;
159                         while (retval >1) retval /= 10;
160                         if (integral < 0){
161                                 retval -= integral;
162                                 retval = -retval;
163                         }
164                         else retval += integral;
165                         if (exponent != 1) retval *= Math.Pow(10, exponent);
166                         return retval;
167                 }
168
169                 public override string ToString ()
170                 {
171                         return ToString (null, null);
172                 }
173
174                 public string ToString (IFormatProvider fp)
175                 {
176                         return ToString (null, fp);
177                 }
178
179                 public string ToString (string format)
180                 {
181                         return ToString (format, null);
182                 }
183
184                 [MonoTODO]
185                 public string ToString (string format, IFormatProvider fp)
186                 {
187                         throw new NotImplementedException ();
188                 }
189
190                 // =========== IConvertible Methods =========== //
191
192                 public TypeCode GetTypeCode ()
193                 {
194                         return TypeCode.Double;
195                 }
196
197                 public object ToType (Type conversionType, IFormatProvider provider)
198                 {
199                         return System.Convert.ToType(value, conversionType, provider);
200                 }
201                 
202                 public bool ToBoolean (IFormatProvider provider)
203                 {
204                         return System.Convert.ToBoolean(value);
205                 }
206                 
207                 public byte ToByte (IFormatProvider provider)
208                 {
209                         return System.Convert.ToByte(value);
210                 }
211                 
212                 public char ToChar (IFormatProvider provider)
213                 {
214                         throw new InvalidCastException();
215                 }
216                 
217                 [CLSCompliant(false)]
218                 public DateTime ToDateTime (IFormatProvider provider)
219                 {
220                         throw new InvalidCastException();
221                 }
222                 
223                 public decimal ToDecimal (IFormatProvider provider)
224                 {
225                         return System.Convert.ToDecimal(value);
226                 }
227                 
228                 public double ToDouble (IFormatProvider provider)
229                 {
230                         return System.Convert.ToDouble(value);
231                 }
232                 
233                 public short ToInt16 (IFormatProvider provider)
234                 {
235                         return System.Convert.ToInt16(value);
236                 }
237                 
238                 public int ToInt32 (IFormatProvider provider)
239                 {
240                         return System.Convert.ToInt32(value);
241                 }
242                 
243                 public long ToInt64 (IFormatProvider provider)
244                 {
245                         return System.Convert.ToInt64(value);
246                 }
247                 
248                 [CLSCompliant(false)] 
249                 public sbyte ToSByte (IFormatProvider provider)
250                 {
251                         return System.Convert.ToSByte(value);
252                 }
253                 
254                 public float ToSingle (IFormatProvider provider)
255                 {
256                         return System.Convert.ToSingle(value);
257                 }
258                 
259                 string IConvertible.ToString (IFormatProvider provider)
260                 {
261                         return ToString(provider);
262                 }
263
264                 [CLSCompliant(false)]
265                 public ushort ToUInt16 (IFormatProvider provider)
266                 {
267                         return System.Convert.ToUInt16(value);
268                 }
269                 
270                 [CLSCompliant(false)]
271                 public uint ToUInt32 (IFormatProvider provider)
272                 {
273                         return System.Convert.ToUInt32(value);
274                 }
275                 
276                 [CLSCompliant(false)]
277                 public ulong ToUInt64 (IFormatProvider provider)
278                 {
279                         return System.Convert.ToUInt64(value);
280                 }
281         }
282 }