2004-04-24 Andreas Nahr <ClassDevelopment@A-SoftTech.com>
[mono.git] / mcs / class / corlib / System / Math.cs
1 //
2 // System.Math.cs
3 //
4 // Authors:
5 //   Bob Smith (bob@thestuff.net)
6 //   Dan Lewis (dihlewis@yahoo.co.uk)
7 //   Pedro Martínez Juliá (yoros@wanadoo.es)
8 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
9 //
10 // (C) 2001 Bob Smith.  http://www.thestuff.net
11 // Copyright (C) 2003 Pedro Martínez Juliá <yoros@wanadoo.es>
12 //
13
14 using System.Runtime.CompilerServices;
15
16 namespace System
17 {
18         public sealed class Math
19         {
20                 public const double E = 2.7182818284590452354;
21                 public const double PI = 3.14159265358979323846;
22
23                 private Math ()
24                 {
25                 }
26
27                 public static decimal Abs (decimal value)
28                 {
29                         return (value < 0)? -value: value;
30                 }
31
32                 public static double Abs (double value)
33                 {
34                         return (value < 0)? -value: value;
35                 }
36
37                 public static float Abs (float value)
38                 {
39                         return (value < 0)? -value: value;
40                 }
41
42                 public static int Abs (int value)
43                 {
44                         if (value == Int32.MinValue)
45                                 throw new OverflowException (Locale.GetText ("Value is too small."));
46                         return (value < 0)? -value: value;
47                 }
48
49                 public static long Abs (long value)
50                 {
51                         if (value == Int64.MinValue)
52                                 throw new OverflowException (Locale.GetText ("Value is too small."));
53                         return (value < 0)? -value: value;
54                 }
55
56                 [CLSCompliant (false)]
57                 public static sbyte Abs (sbyte value)
58                 {
59                         if (value == SByte.MinValue)
60                                 throw new OverflowException (Locale.GetText ("Value is too small."));
61                         return (sbyte)((value < 0)? -value: value);
62                 }
63
64                 public static short Abs (short value)
65                 {
66                         if (value == Int16.MinValue)
67                                 throw new OverflowException (Locale.GetText ("Value is too small."));
68                         return (short)((value < 0)? -value: value);
69                 }
70
71                 public static double Ceiling (double a)
72                 {
73                         double result = Floor(a);
74                         if (result != a) {
75                                 result++;
76                         }
77                         return result;
78                 }
79
80                 // The following methods are defined in ECMA specs but they are
81                 // not implemented in MS.NET. However, they are in MS.NET 1.1
82
83 #if (!NET_1_0)
84                 public static long BigMul (int a, int b)
85                 {
86                         return ((long)a * (long)b);
87                 }
88
89                 public static int DivRem (int a, int b, out int result)
90                 {
91                         result = (a % b);
92                         return (int)(a / b);
93                 }
94
95                 public static long DivRem (long a, long b, out long result)
96                 {
97                         result = (a % b);
98                         return (long)(a / b);
99                 }
100 #endif
101
102                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
103                 public extern static double Floor (double value);
104
105                 public static double IEEERemainder (double x, double y)
106                 {
107                         double r;
108                         if (y == 0) return Double.NaN;
109                         r = x - (y * Math.Round(x/y));
110                         if (r != 0)
111                                 return r;
112                         return (x > 0)? 0: -0;
113                 }
114
115                 public static double Log (double a, double newBase)
116                 {
117                         double result = Log(a) / Log(newBase);
118                         return (result == -0)? 0: result;
119                 }
120
121                 public static byte Max (byte val1, byte val2)
122                 {
123                         return (val1 > val2)? val1: val2;
124                 }
125
126                 public static decimal Max (decimal val1, decimal val2)
127                 {
128                         return (val1 > val2)? val1: val2;
129                 }
130
131                 public static double Max (double val1, double val2)
132                 {
133                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
134                                 return Double.NaN;
135                         }
136                         return (val1 > val2)? val1: val2;
137                 }
138
139                 public static float Max (float val1, float val2)
140                 {
141                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
142                                 return Single.NaN;
143                         }
144                         return (val1 > val2)? val1: val2;
145                 }
146
147                 public static int Max (int val1, int val2)
148                 {
149                         return (val1 > val2)? val1: val2;
150                 }
151
152                 public static long Max (long val1, long val2)
153                 {
154                         return (val1 > val2)? val1: val2;
155                 }
156
157                 [CLSCompliant (false)]
158                 public static sbyte Max (sbyte val1, sbyte val2)
159                 {
160                         return (val1 > val2)? val1: val2;
161                 }
162
163                 public static short Max (short val1, short val2)
164                 {
165                         return (val1 > val2)? val1: val2;
166                 }
167
168                 [CLSCompliant (false)]
169                 public static uint Max (uint val1, uint val2)
170                 {
171                         return (val1 > val2)? val1: val2;
172                 }
173
174                 [CLSCompliant (false)]
175                 public static ulong Max (ulong val1, ulong val2)
176                 {
177                         return (val1 > val2)? val1: val2;
178                 }
179
180                 [CLSCompliant (false)]
181                 public static ushort Max (ushort val1, ushort val2)
182                 {
183                         return (val1 > val2)? val1: val2;
184                 }
185
186                 public static byte Min (byte val1, byte val2)
187                 {
188                         return (val1 < val2)? val1: val2;
189                 }
190
191                 public static decimal Min (decimal val1, decimal val2)
192                 {
193                         return (val1 < val2)? val1: val2;
194                 }
195
196                 public static double Min (double val1, double val2)
197                 {
198                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
199                                 return Double.NaN;
200                         }
201                         return (val1 < val2)? val1: val2;
202                 }
203
204                 public static float Min (float val1, float val2)
205                 {
206                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
207                                 return Single.NaN;
208                         }
209                         return (val1 < val2)? val1: val2;
210                 }
211
212                 public static int Min (int val1, int val2)
213                 {
214                         return (val1 < val2)? val1: val2;
215                 }
216
217                 public static long Min (long val1, long val2)
218                 {
219                         return (val1 < val2)? val1: val2;
220                 }
221
222                 [CLSCompliant (false)]
223                 public static sbyte Min (sbyte val1, sbyte val2)
224                 {
225                         return (val1 < val2)? val1: val2;
226                 }
227
228                 public static short Min (short val1, short val2)
229                 {
230                         return (val1 < val2)? val1: val2;
231                 }
232
233                 [CLSCompliant (false)]
234                 public static uint Min (uint val1, uint val2)
235                 {
236                         return (val1 < val2)? val1: val2;
237                 }
238
239                 [CLSCompliant (false)]
240                 public static ulong Min (ulong val1, ulong val2)
241                 {
242                         return (val1 < val2)? val1: val2;
243                 }
244
245                 [CLSCompliant (false)]
246                 public static ushort Min (ushort val1, ushort val2)
247                 {
248                         return (val1 < val2)? val1: val2;
249                 }
250
251                 public static decimal Round (decimal d)
252                 {
253                         // Just call Decimal.Round(d, 0); when it rounds well.
254                         decimal int_part = Decimal.Floor(d);
255                         decimal dec_part = d - int_part;
256                         if (((dec_part == 0.5M) &&
257                                 ((2.0M * ((int_part / 2.0M) -
258                                 Decimal.Floor(int_part / 2.0M))) != 0.0M)) ||
259                                 (dec_part > 0.5M)) {
260                                 int_part++;
261                         }
262                         return int_part;
263                 }
264
265                 public static decimal Round (decimal d, int decimals)
266                 {
267                         if (decimals < 0 || decimals > 28)
268                                 throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
269
270                         // Just call Decimal.Round(d, decimals); when it
271                         // rounds good.
272                         decimal p = (decimal) Math.Pow(10, decimals);
273                         decimal int_part = Decimal.Floor(d);
274                         decimal dec_part = d - int_part;
275                         dec_part *= 10000000000000000000000000000M;
276                         dec_part = Decimal.Floor(dec_part);
277                         dec_part /= (10000000000000000000000000000M / p);
278                         dec_part = Math.Round(dec_part);
279                         dec_part /= p;
280                         return int_part + dec_part;
281                 }
282
283                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
284                 public extern static double Round (double d);
285
286                 public static double Round (double value, int digits)
287                 {
288                         if (digits < 0 || digits > 15)
289                                 throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
290
291                         return Round2(value, digits);
292                 }
293
294                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
295                 private extern static double Round2 (double value, int digits);
296
297                 public static int Sign (decimal value)
298                 {
299                         if (value > 0) return 1;
300                         return (value == 0)? 0: -1;
301                 }
302
303                 public static int Sign (double value)
304                 {
305                         if (Double.IsNaN (value))
306                                 throw new ArithmeticException ("NAN");
307                         if (value > 0) return 1;
308                         return (value == 0)? 0: -1;
309                 }
310
311                 public static int Sign (float value)
312                 {
313                         if (Single.IsNaN (value))
314                                 throw new ArithmeticException ("NAN");
315                         if (value > 0) return 1;
316                         return (value == 0)? 0: -1;
317                 }
318
319                 public static int Sign (int value)
320                 {
321                         if (value > 0) return 1;
322                         return (value == 0)? 0: -1;
323                 }
324
325                 public static int Sign (long value)
326                 {
327                         if (value > 0) return 1;
328                         return (value == 0)? 0: -1;
329                 }
330
331                 [CLSCompliant (false)]
332                 public static int Sign (sbyte value)
333                 {
334                         if (value > 0) return 1;
335                         return (value == 0)? 0: -1;
336                 }
337
338                 public static int Sign (short value)
339                 {
340                         if (value > 0) return 1;
341                         return (value == 0)? 0: -1;
342                 }
343
344                 // internal calls
345                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
346                 public extern static double Sin (double x);
347
348                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
349                 public extern static double Cos (double x);
350
351                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
352                 public extern static double Tan (double x);
353
354                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
355                 public extern static double Sinh (double x);
356
357                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
358                 public extern static double Cosh (double x);
359
360                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
361                 public extern static double Tanh (double x);
362
363                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
364                 public extern static double Acos (double x);
365                 
366                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
367                 public extern static double Asin (double x);
368
369                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
370                 public extern static double Atan (double x);
371
372                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
373                 public extern static double Atan2 (double y, double x);
374
375                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
376                 public extern static double Exp (double x);
377
378                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
379                 public extern static double Log (double x);
380
381                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
382                 public extern static double Log10 (double x);
383
384                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
385                 public extern static double Pow (double x, double y);
386
387                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
388                 public extern static double Sqrt (double x);
389         }
390 }