Normalize line endings.
[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 using System.Runtime.ConstrainedExecution;
36
37 namespace System
38 {
39         public static class Math
40         {
41                 public const double E = 2.7182818284590452354;
42                 public const double PI = 3.14159265358979323846;
43
44                 public static decimal Abs (decimal value)
45                 {
46                         return (value < 0)? -value: value;
47                 }
48
49                 public static double Abs (double value)
50                 {
51                         return (value < 0)? -value: value;
52                 }
53
54                 public static float Abs (float value)
55                 {
56                         return (value < 0)? -value: value;
57                 }
58
59                 public static int Abs (int value)
60                 {
61                         if (value == Int32.MinValue)
62                                 throw new OverflowException (Locale.GetText ("Value is too small."));
63                         return (value < 0)? -value: value;
64                 }
65
66                 public static long Abs (long value)
67                 {
68                         if (value == Int64.MinValue)
69                                 throw new OverflowException (Locale.GetText ("Value is too small."));
70                         return (value < 0)? -value: value;
71                 }
72
73                 [CLSCompliant (false)]
74                 public static sbyte Abs (sbyte value)
75                 {
76                         if (value == SByte.MinValue)
77                                 throw new OverflowException (Locale.GetText ("Value is too small."));
78                         return (sbyte)((value < 0)? -value: value);
79                 }
80
81                 public static short Abs (short value)
82                 {
83                         if (value == Int16.MinValue)
84                                 throw new OverflowException (Locale.GetText ("Value is too small."));
85                         return (short)((value < 0)? -value: value);
86                 }
87
88                 public static decimal Ceiling (decimal d)
89                 {
90                         decimal result = Floor(d);
91                         if (result != d) {
92                                 result++;
93                         }
94                         return result;
95                 }
96
97                 public static double Ceiling (double a)
98                 {
99                         double result = Floor(a);
100                         if (result != a) {
101                                 result++;
102                         }
103                         return result;
104                 }
105
106                 // The following methods are defined in ECMA specs but they are
107                 // not implemented in MS.NET. However, they are in MS.NET 1.1
108
109                 public static long BigMul (int a, int b)
110                 {
111                         return ((long)a * (long)b);
112                 }
113
114                 public static int DivRem (int a, int b, out int result)
115                 {
116                         result = (a % b);
117                         return (int)(a / b);
118                 }
119
120                 public static long DivRem (long a, long b, out long result)
121                 {
122                         result = (a % b);
123                         return (long)(a / b);
124                 }
125
126                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
127                 public extern static double Floor (double d);
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                         /* Int64BitsToDouble is not endian-aware, but that is fine here */
138                         return (x > 0) ? 0: (BitConverter.Int64BitsToDouble (Int64.MinValue));
139                 }
140
141                 public static double Log (double a, double newBase)
142                 {
143                         double result = Log(a) / Log(newBase);
144                         return (result == -0)? 0: result;
145                 }
146
147                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
148                 public static byte Max (byte val1, byte val2)
149                 {
150                         return (val1 > val2)? val1: val2;
151                 }
152
153                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
154                 public static decimal Max (decimal val1, decimal val2)
155                 {
156                         return (val1 > val2)? val1: val2;
157                 }
158
159                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
160                 public static double Max (double val1, double val2)
161                 {
162                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
163                                 return Double.NaN;
164                         }
165                         return (val1 > val2)? val1: val2;
166                 }
167
168                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
169                 public static float Max (float val1, float val2)
170                 {
171                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
172                                 return Single.NaN;
173                         }
174                         return (val1 > val2)? val1: val2;
175                 }
176
177                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
178                 public static int Max (int val1, int val2)
179                 {
180                         return (val1 > val2)? val1: val2;
181                 }
182
183                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
184                 public static long Max (long val1, long val2)
185                 {
186                         return (val1 > val2)? val1: val2;
187                 }
188
189                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
190                 [CLSCompliant (false)]
191                 public static sbyte Max (sbyte val1, sbyte val2)
192                 {
193                         return (val1 > val2)? val1: val2;
194                 }
195
196                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
197                 public static short Max (short val1, short val2)
198                 {
199                         return (val1 > val2)? val1: val2;
200                 }
201
202                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
203                 [CLSCompliant (false)]
204                 public static uint Max (uint val1, uint val2)
205                 {
206                         return (val1 > val2)? val1: val2;
207                 }
208
209                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
210                 [CLSCompliant (false)]
211                 public static ulong Max (ulong val1, ulong val2)
212                 {
213                         return (val1 > val2)? val1: val2;
214                 }
215
216                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
217                 [CLSCompliant (false)]
218                 public static ushort Max (ushort val1, ushort val2)
219                 {
220                         return (val1 > val2)? val1: val2;
221                 }
222
223                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
224                 public static byte Min (byte val1, byte val2)
225                 {
226                         return (val1 < val2)? val1: val2;
227                 }
228
229                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
230                 public static decimal Min (decimal val1, decimal val2)
231                 {
232                         return (val1 < val2)? val1: val2;
233                 }
234
235                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
236                 public static double Min (double val1, double val2)
237                 {
238                         if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
239                                 return Double.NaN;
240                         }
241                         return (val1 < val2)? val1: val2;
242                 }
243
244                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
245                 public static float Min (float val1, float val2)
246                 {
247                         if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
248                                 return Single.NaN;
249                         }
250                         return (val1 < val2)? val1: val2;
251                 }
252
253                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
254                 public static int Min (int val1, int val2)
255                 {
256                         return (val1 < val2)? val1: val2;
257                 }
258
259                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
260                 public static long Min (long val1, long val2)
261                 {
262                         return (val1 < val2)? val1: val2;
263                 }
264
265                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
266                 [CLSCompliant (false)]
267                 public static sbyte Min (sbyte val1, sbyte val2)
268                 {
269                         return (val1 < val2)? val1: val2;
270                 }
271
272                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
273                 public static short Min (short val1, short val2)
274                 {
275                         return (val1 < val2)? val1: val2;
276                 }
277
278                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
279                 [CLSCompliant (false)]
280                 public static uint Min (uint val1, uint val2)
281                 {
282                         return (val1 < val2)? val1: val2;
283                 }
284
285                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
286                 [CLSCompliant (false)]
287                 public static ulong Min (ulong val1, ulong val2)
288                 {
289                         return (val1 < val2)? val1: val2;
290                 }
291
292                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
293                 [CLSCompliant (false)]
294                 public static ushort Min (ushort val1, ushort val2)
295                 {
296                         return (val1 < val2)? val1: val2;
297                 }
298
299                 public static decimal Round (decimal d)
300                 {
301                         // Just call Decimal.Round(d, 0); when it rounds well.
302                         decimal int_part = Decimal.Floor(d);
303                         decimal dec_part = d - int_part;
304                         if (((dec_part == 0.5M) &&
305                                 ((2.0M * ((int_part / 2.0M) -
306                                 Decimal.Floor(int_part / 2.0M))) != 0.0M)) ||
307                                 (dec_part > 0.5M)) {
308                                 int_part++;
309                         }
310                         return int_part;
311                 }
312
313                 public static decimal Round (decimal d, int decimals)
314                 {
315                         return Decimal.Round (d, decimals);
316                 }
317
318                 public static decimal Round (decimal d, MidpointRounding mode)
319                 {
320                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
321                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
322
323                         if (mode == MidpointRounding.ToEven)
324                                 return Round (d);
325                         else
326                                 return RoundAwayFromZero (d);
327                 }
328
329                 static decimal RoundAwayFromZero (decimal d)
330                 {
331                         decimal int_part = Decimal.Floor(d);
332                         decimal dec_part = d - int_part;
333                         if (int_part >= 0 && dec_part >= 0.5M)
334                                 int_part++;
335                         else if (int_part < 0 && dec_part > 0.5M)
336                                 int_part++;
337                         return int_part;
338                 }
339
340                 public static decimal Round (decimal d, int decimals, MidpointRounding mode)
341                 {
342                         return Decimal.Round (d, decimals, mode);
343                 }
344
345                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
346                 public extern static double Round (double a);
347
348                 public static double Round (double value, int digits)
349                 {
350                         if (digits < 0 || digits > 15)
351                                 throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
352
353                         return Round2(value, digits, false);
354                 }
355
356                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
357                 private extern static double Round2 (double value, int digits, bool away_from_zero);
358
359
360                 public static double Round (double value, MidpointRounding mode)
361                 {
362                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
363                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
364
365                         if (mode == MidpointRounding.ToEven)
366                                 return Round (value);
367                         if (value > 0)
368                                 return Floor (value + 0.5);
369                         else
370                                 return Ceiling (value - 0.5);
371                 }
372
373                 public static double Round (double value, int digits, MidpointRounding mode)
374                 {
375                         if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
376                                 throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
377
378                         if (mode == MidpointRounding.ToEven)
379                                 return Round (value, digits);
380                         else
381                                 return Round2 (value, digits, true);
382                 }
383                 
384                 public static double Truncate (double d)
385                 {
386                         if (d > 0D)
387                                 return Floor (d);
388                         else if (d < 0D)
389                                 return Ceiling (d);
390                         else
391                                 return d;
392                 }
393
394                 public static decimal Truncate (decimal d)
395                 {
396                         return Decimal.Truncate (d);
397                 }
398
399                 public static decimal Floor (Decimal d)
400                 {
401                         return Decimal.Floor (d);
402                 }
403
404                 public static int Sign (decimal value)
405                 {
406                         if (value > 0) return 1;
407                         return (value == 0)? 0: -1;
408                 }
409
410                 public static int Sign (double value)
411                 {
412                         if (Double.IsNaN (value))
413                                 throw new ArithmeticException ("NAN");
414                         if (value > 0) return 1;
415                         return (value == 0)? 0: -1;
416                 }
417
418                 public static int Sign (float value)
419                 {
420                         if (Single.IsNaN (value))
421                                 throw new ArithmeticException ("NAN");
422                         if (value > 0) return 1;
423                         return (value == 0)? 0: -1;
424                 }
425
426                 public static int Sign (int value)
427                 {
428                         if (value > 0) return 1;
429                         return (value == 0)? 0: -1;
430                 }
431
432                 public static int Sign (long value)
433                 {
434                         if (value > 0) return 1;
435                         return (value == 0)? 0: -1;
436                 }
437
438                 [CLSCompliant (false)]
439                 public static int Sign (sbyte value)
440                 {
441                         if (value > 0) return 1;
442                         return (value == 0)? 0: -1;
443                 }
444
445                 public static int Sign (short value)
446                 {
447                         if (value > 0) return 1;
448                         return (value == 0)? 0: -1;
449                 }
450
451                 // internal calls
452                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
453                 public extern static double Sin (double a);
454
455                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
456                 public extern static double Cos (double d);
457
458                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
459                 public extern static double Tan (double a);
460
461                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
462                 public extern static double Sinh (double value);
463
464                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
465                 public extern static double Cosh (double value);
466
467                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
468                 public extern static double Tanh (double value);
469
470                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
471                 public extern static double Acos (double d);
472                 
473                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
474                 public extern static double Asin (double d);
475
476                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
477                 public extern static double Atan (double d);
478
479                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
480                 public extern static double Atan2 (double y, double x);
481
482                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
483                 public extern static double Exp (double d);
484
485                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
486                 public extern static double Log (double d);
487
488                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
489                 public extern static double Log10 (double d);
490
491                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
492                 public extern static double Pow (double x, double y);
493
494                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
495                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
496                 public extern static double Sqrt (double d);
497         }
498 }