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