df0fccd0e35ed2e6dc57dece2c5e790d60376483
[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 // Copyright (C) 2004 Novell (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Runtime.CompilerServices;
35
36 #if NET_2_0
37 using System.Runtime.ConstrainedExecution;
38 #endif
39
40 namespace System
41 {
42         public sealed class Math
43         {
44                 public const double E = 2.7182818284590452354;
45                 public const double PI = 3.14159265358979323846;
46
47                 private Math ()
48                 {
49                 }
50
51                 public static decimal Abs (decimal value)
52                 {
53                         return (value < 0)? -value: value;
54                 }
55
56                 public static double Abs (double value)
57                 {
58                         return (value < 0)? -value: value;
59                 }
60
61                 public static float Abs (float value)
62                 {
63                         return (value < 0)? -value: value;
64                 }
65
66                 public static int Abs (int value)
67                 {
68                         if (value == Int32.MinValue)
69                                 throw new OverflowException (Locale.GetText ("Value is too small."));
70                         return (value < 0)? -value: value;
71                 }
72
73                 public static long Abs (long value)
74                 {
75                         if (value == Int64.MinValue)
76                                 throw new OverflowException (Locale.GetText ("Value is too small."));
77                         return (value < 0)? -value: value;
78                 }
79
80                 [CLSCompliant (false)]
81                 public static sbyte Abs (sbyte value)
82                 {
83                         if (value == SByte.MinValue)
84                                 throw new OverflowException (Locale.GetText ("Value is too small."));
85                         return (sbyte)((value < 0)? -value: value);
86                 }
87
88                 public static short Abs (short value)
89                 {
90                         if (value == Int16.MinValue)
91                                 throw new OverflowException (Locale.GetText ("Value is too small."));
92                         return (short)((value < 0)? -value: value);
93                 }
94
95                 public static double Ceiling (double a)
96                 {
97                         double result = Floor(a);
98                         if (result != a) {
99                                 result++;
100                         }
101                         return result;
102                 }
103
104                 // The following methods are defined in ECMA specs but they are
105                 // not implemented in MS.NET. However, they are in MS.NET 1.1
106
107 #if (!NET_1_0)
108                 public static long BigMul (int a, int b)
109                 {
110                         return ((long)a * (long)b);
111                 }
112
113                 public static int DivRem (int a, int b, out int result)
114                 {
115                         result = (a % b);
116                         return (int)(a / b);
117                 }
118
119                 public static long DivRem (long a, long b, out long result)
120                 {
121                         result = (a % b);
122                         return (long)(a / b);
123                 }
124 #endif
125
126                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
127                 public extern static double Floor (double value);
128
129                 public static double IEEERemainder (double x, double y)
130                 {
131                         double r;
132                         if (y == 0)
133                                 return Double.NaN;
134                         r = x - (y * Math.Round(x/y));
135                         if (r != 0)
136                                 return r;
137                         return (x > 0) ? 0: (BitConverter.Int64BitsToDouble (Int64.MinValue));
138                 }
139
140                 public static double Log (double a, double newBase)
141                 {
142                         double result = Log(a) / Log(newBase);
143                         return (result == -0)? 0: result;
144                 }
145
146 #if NET_2_0
147                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
148 #endif
149                 public static byte Max (byte val1, byte val2)
150                 {
151                         return (val1 > val2)? val1: val2;
152                 }
153
154 #if NET_2_0
155                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
156 #endif
157                 public static decimal Max (decimal val1, decimal val2)
158                 {
159                         return (val1 > val2)? val1: val2;
160                 }
161
162 #if NET_2_0
163                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
164 #endif
165                 public static double Max (double val1, double val2)
166                 {
167                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
168                                 return Double.NaN;
169                         }
170                         return (val1 > val2)? val1: val2;
171                 }
172
173 #if NET_2_0
174                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
175 #endif
176                 public static float Max (float val1, float val2)
177                 {
178                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
179                                 return Single.NaN;
180                         }
181                         return (val1 > val2)? val1: val2;
182                 }
183
184 #if NET_2_0
185                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
186 #endif
187                 public static int Max (int val1, int val2)
188                 {
189                         return (val1 > val2)? val1: val2;
190                 }
191
192 #if NET_2_0
193                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
194 #endif
195                 public static long Max (long val1, long val2)
196                 {
197                         return (val1 > val2)? val1: val2;
198                 }
199
200 #if NET_2_0
201                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
202 #endif
203                 [CLSCompliant (false)]
204                 public static sbyte Max (sbyte val1, sbyte val2)
205                 {
206                         return (val1 > val2)? val1: val2;
207                 }
208
209 #if NET_2_0
210                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
211 #endif
212                 public static short Max (short val1, short val2)
213                 {
214                         return (val1 > val2)? val1: val2;
215                 }
216
217 #if NET_2_0
218                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
219 #endif
220                 [CLSCompliant (false)]
221                 public static uint Max (uint val1, uint val2)
222                 {
223                         return (val1 > val2)? val1: val2;
224                 }
225
226 #if NET_2_0
227                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
228 #endif
229                 [CLSCompliant (false)]
230                 public static ulong Max (ulong val1, ulong val2)
231                 {
232                         return (val1 > val2)? val1: val2;
233                 }
234
235 #if NET_2_0
236                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
237 #endif
238                 [CLSCompliant (false)]
239                 public static ushort Max (ushort val1, ushort val2)
240                 {
241                         return (val1 > val2)? val1: val2;
242                 }
243
244 #if NET_2_0
245                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
246 #endif
247                 public static byte Min (byte val1, byte val2)
248                 {
249                         return (val1 < val2)? val1: val2;
250                 }
251
252 #if NET_2_0
253                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
254 #endif
255                 public static decimal Min (decimal val1, decimal val2)
256                 {
257                         return (val1 < val2)? val1: val2;
258                 }
259
260 #if NET_2_0
261                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
262 #endif
263                 public static double Min (double val1, double val2)
264                 {
265                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
266                                 return Double.NaN;
267                         }
268                         return (val1 < val2)? val1: val2;
269                 }
270
271 #if NET_2_0
272                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
273 #endif
274                 public static float Min (float val1, float val2)
275                 {
276                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
277                                 return Single.NaN;
278                         }
279                         return (val1 < val2)? val1: val2;
280                 }
281
282 #if NET_2_0
283                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
284 #endif
285                 public static int Min (int val1, int val2)
286                 {
287                         return (val1 < val2)? val1: val2;
288                 }
289
290 #if NET_2_0
291                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
292 #endif
293                 public static long Min (long val1, long val2)
294                 {
295                         return (val1 < val2)? val1: val2;
296                 }
297
298 #if NET_2_0
299                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
300 #endif
301                 [CLSCompliant (false)]
302                 public static sbyte Min (sbyte val1, sbyte val2)
303                 {
304                         return (val1 < val2)? val1: val2;
305                 }
306
307 #if NET_2_0
308                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
309 #endif
310                 public static short Min (short val1, short val2)
311                 {
312                         return (val1 < val2)? val1: val2;
313                 }
314
315 #if NET_2_0
316                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
317 #endif
318                 [CLSCompliant (false)]
319                 public static uint Min (uint val1, uint val2)
320                 {
321                         return (val1 < val2)? val1: val2;
322                 }
323
324 #if NET_2_0
325                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
326 #endif
327                 [CLSCompliant (false)]
328                 public static ulong Min (ulong val1, ulong val2)
329                 {
330                         return (val1 < val2)? val1: val2;
331                 }
332
333 #if NET_2_0
334                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
335 #endif
336                 [CLSCompliant (false)]
337                 public static ushort Min (ushort val1, ushort val2)
338                 {
339                         return (val1 < val2)? val1: val2;
340                 }
341
342                 public static decimal Round (decimal d)
343                 {
344                         // Just call Decimal.Round(d, 0); when it rounds well.
345                         decimal int_part = Decimal.Floor(d);
346                         decimal dec_part = d - int_part;
347                         if (((dec_part == 0.5M) &&
348                                 ((2.0M * ((int_part / 2.0M) -
349                                 Decimal.Floor(int_part / 2.0M))) != 0.0M)) ||
350                                 (dec_part > 0.5M)) {
351                                 int_part++;
352                         }
353                         return int_part;
354                 }
355
356                 public static decimal Round (decimal d, int decimals)
357                 {
358                         return Decimal.Round (d, decimals);
359                 }
360
361 #if NET_2_0
362                 [MonoTODO]
363                 public static decimal Round (decimal d, MidpointRounding mode)
364                 {
365                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
366                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
367
368                         if (mode == MidpointRounding.ToEven)
369                                 return Round (d);
370                         throw new NotImplementedException ();
371                 }
372
373                 [MonoTODO]
374                 public static decimal Round (decimal d, int decimals, MidpointRounding mode)
375                 {
376                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
377                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
378
379                         if (mode == MidpointRounding.ToEven)
380                                 return Round (d, decimals);
381                         throw new NotImplementedException ();
382                 }
383 #endif
384
385                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
386                 public extern static double Round (double d);
387
388                 public static double Round (double value, int digits)
389                 {
390                         if (digits < 0 || digits > 15)
391                                 throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
392
393                         return Round2(value, digits);
394                 }
395
396                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
397                 private extern static double Round2 (double value, int digits);
398
399
400 #if NET_2_0
401                 public static double Round (double value, MidpointRounding mode)
402                 {
403                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
404                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
405
406                         if (mode == MidpointRounding.ToEven)
407                                 return Round (value);
408                         if (value > 0)
409                                 return Floor (value + 0.5);
410                         else
411                                 return Ceiling (value - 0.5);
412                 }
413
414                 [MonoTODO]
415                 public static double Round (double value, int digits, MidpointRounding mode)
416                 {
417                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
418                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
419
420                         if (mode == MidpointRounding.ToEven)
421                                 return Round (value, digits);
422                         throw new NotImplementedException ();
423                 }
424
425                 public static double Truncate (double d)
426                 {
427                         if (d > 0D)
428                                 return Floor (d);
429                         else if (d < 0D)
430                                 return Ceiling (d);
431                         else
432                                 return d;
433                 }
434
435                 public static decimal Truncate (decimal d)
436                 {
437                         return Decimal.Truncate (d);
438                 }
439 #endif
440
441                 public static int Sign (decimal value)
442                 {
443                         if (value > 0) return 1;
444                         return (value == 0)? 0: -1;
445                 }
446
447                 public static int Sign (double value)
448                 {
449                         if (Double.IsNaN (value))
450                                 throw new ArithmeticException ("NAN");
451                         if (value > 0) return 1;
452                         return (value == 0)? 0: -1;
453                 }
454
455                 public static int Sign (float value)
456                 {
457                         if (Single.IsNaN (value))
458                                 throw new ArithmeticException ("NAN");
459                         if (value > 0) return 1;
460                         return (value == 0)? 0: -1;
461                 }
462
463                 public static int Sign (int value)
464                 {
465                         if (value > 0) return 1;
466                         return (value == 0)? 0: -1;
467                 }
468
469                 public static int Sign (long value)
470                 {
471                         if (value > 0) return 1;
472                         return (value == 0)? 0: -1;
473                 }
474
475                 [CLSCompliant (false)]
476                 public static int Sign (sbyte value)
477                 {
478                         if (value > 0) return 1;
479                         return (value == 0)? 0: -1;
480                 }
481
482                 public static int Sign (short value)
483                 {
484                         if (value > 0) return 1;
485                         return (value == 0)? 0: -1;
486                 }
487
488                 // internal calls
489                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
490                 public extern static double Sin (double x);
491
492                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
493                 public extern static double Cos (double x);
494
495                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
496                 public extern static double Tan (double x);
497
498                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
499                 public extern static double Sinh (double x);
500
501                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
502                 public extern static double Cosh (double x);
503
504                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
505                 public extern static double Tanh (double x);
506
507                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
508                 public extern static double Acos (double x);
509                 
510                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
511                 public extern static double Asin (double x);
512
513                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
514                 public extern static double Atan (double x);
515
516                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
517                 public extern static double Atan2 (double y, double x);
518
519                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
520                 public extern static double Exp (double x);
521
522                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
523                 public extern static double Log (double x);
524
525                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
526                 public extern static double Log10 (double x);
527
528                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
529                 public extern static double Pow (double x, double y);
530
531                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
532 #if NET_2_0
533                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
534 #endif
535                 public extern static double Sqrt (double x);
536         }
537 }