2002-04-11 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                 public static double Parse (string s, NumberStyles style, IFormatProvider provider)
112                 {
113                         if (s == null) throw new ArgumentNullException();
114                         if (style > NumberStyles.Any)
115                         {
116                                 throw new ArgumentException();
117                         }
118                         NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);
119                         if (format == null) throw new Exception("How did this happen?");
120                         if (s == format.NaNSymbol) return Double.NaN;
121                         if (s == format.PositiveInfinitySymbol) return Double.PositiveInfinity;
122                         if (s == format.NegativeInfinitySymbol) return Double.NegativeInfinity;
123                         string[] sl;
124                         long integral = 0;
125                         long fraction = 0;
126                         long exponent = 1;
127                         double retval = 0;
128                         if ((style & NumberStyles.AllowLeadingWhite) != 0)
129                         {
130                                 s.TrimStart(null);
131                         }
132                         if ((style & NumberStyles.AllowTrailingWhite) != 0)
133                         {
134                                 s.TrimEnd(null);
135                         }
136                         sl = s.Split(new Char[] {'e', 'E'}, 2);
137                         if (sl.Length > 1)
138                         {
139                                 if ((style & NumberStyles.AllowExponent) == 0)
140                                 {
141                                         throw new FormatException();
142                                 }
143                                 exponent = long.Parse(sl[1], NumberStyles.AllowLeadingSign, format);
144                         }
145                         s = sl[0];
146                         sl = s.Split(format.NumberDecimalSeparator.ToCharArray(), 2);
147                         if (sl.Length > 1)
148                         {
149                                 if ((style & NumberStyles.AllowDecimalPoint) == 0)
150                                 {
151                                         throw new FormatException();
152                                 }
153                                 fraction = long.Parse(sl[1], NumberStyles.None, format);
154                         }
155                         NumberStyles tempstyle = NumberStyles.None;
156                         if ((style & NumberStyles.AllowLeadingSign) != 0){
157                                 tempstyle = NumberStyles.AllowLeadingSign;
158                         }
159                         integral = long.Parse(sl[0], tempstyle, format);
160                         retval = fraction;
161                         while (retval >1) retval /= 10;
162                         if (integral < 0){
163                                 retval -= integral;
164                                 retval = -retval;
165                         }
166                         else retval += integral;
167                         if (exponent != 1) retval *= Math.Pow(10, exponent);
168                         return retval;
169                 }
170
171                 public override string ToString ()
172                 {
173                         return ToString (null, null);
174                 }
175
176                 public string ToString (IFormatProvider fp)
177                 {
178                         return ToString (null, fp);
179                 }
180
181                 public string ToString (string format)
182                 {
183                         return ToString (format, null);
184                 }
185
186                 [MonoTODO]
187                 public string ToString (string format, IFormatProvider fp)
188                 {
189                         // FIXME: Need to pass format and provider info to this call too.
190                         return ToStringImpl(value);
191                 }
192
193                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
194                 private static extern string ToStringImpl (double value);
195
196                 // =========== IConvertible Methods =========== //
197
198                 public TypeCode GetTypeCode ()
199                 {
200                         return TypeCode.Double;
201                 }
202
203                 public object ToType (Type conversionType, IFormatProvider provider)
204                 {
205                         return System.Convert.ToType(value, conversionType, provider);
206                 }
207                 
208                 public bool ToBoolean (IFormatProvider provider)
209                 {
210                         return System.Convert.ToBoolean(value);
211                 }
212                 
213                 public byte ToByte (IFormatProvider provider)
214                 {
215                         return System.Convert.ToByte(value);
216                 }
217                 
218                 public char ToChar (IFormatProvider provider)
219                 {
220                         throw new InvalidCastException();
221                 }
222                 
223                 [CLSCompliant(false)]
224                 public DateTime ToDateTime (IFormatProvider provider)
225                 {
226                         throw new InvalidCastException();
227                 }
228                 
229                 public decimal ToDecimal (IFormatProvider provider)
230                 {
231                         return System.Convert.ToDecimal(value);
232                 }
233                 
234                 public double ToDouble (IFormatProvider provider)
235                 {
236                         return System.Convert.ToDouble(value);
237                 }
238                 
239                 public short ToInt16 (IFormatProvider provider)
240                 {
241                         return System.Convert.ToInt16(value);
242                 }
243                 
244                 public int ToInt32 (IFormatProvider provider)
245                 {
246                         return System.Convert.ToInt32(value);
247                 }
248                 
249                 public long ToInt64 (IFormatProvider provider)
250                 {
251                         return System.Convert.ToInt64(value);
252                 }
253                 
254                 [CLSCompliant(false)] 
255                 public sbyte ToSByte (IFormatProvider provider)
256                 {
257                         return System.Convert.ToSByte(value);
258                 }
259                 
260                 public float ToSingle (IFormatProvider provider)
261                 {
262                         return System.Convert.ToSingle(value);
263                 }
264                 
265                 string IConvertible.ToString (IFormatProvider provider)
266                 {
267                         return ToString(provider);
268                 }
269
270                 [CLSCompliant(false)]
271                 public ushort ToUInt16 (IFormatProvider provider)
272                 {
273                         return System.Convert.ToUInt16(value);
274                 }
275                 
276                 [CLSCompliant(false)]
277                 public uint ToUInt32 (IFormatProvider provider)
278                 {
279                         return System.Convert.ToUInt32(value);
280                 }
281                 
282                 [CLSCompliant(false)]
283                 public ulong ToUInt64 (IFormatProvider provider)
284                 {
285                         return System.Convert.ToUInt64(value);
286                 }
287         }
288 }