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