d2fa1ede9bc9317e245a730a233024d36f6bc81c
[mono.git] / mono / mini / basic-math.cs
1 using System;
2 using System.Reflection;
3
4 /*
5  * Regression tests for the mono JIT.
6  *
7  * Each test needs to be of the form:
8  *
9  * public static int test_<result>_<name> ();
10  *
11  * where <result> is an integer (the value that needs to be returned by
12  * the method to make it pass.
13  * <name> is a user-displayed name used to identify the test.
14  *
15  * The tests can be driven in two ways:
16  * *) running the program directly: Main() uses reflection to find and invoke
17  *      the test methods (this is useful mostly to check that the tests are correct)
18  * *) with the --regression switch of the jit (this is the preferred way since
19  *      all the tests will be run with optimizations on and off)
20  *
21  * The reflection logic could be moved to a .dll since we need at least another
22  * regression test file written in IL code to have better control on how
23  * the IL code looks.
24  */
25
26 class Tests {
27
28         public static int Main () {
29                 return TestDriver.RunTests (typeof (Tests));
30         }
31         
32         public static int test_0_sin_precision () {
33                 double d1 = Math.Sin (1);
34                 double d2 = Math.Sin (1) - d1;
35                 return (d2 == 0) ? 0 : 1;
36         }
37
38         public static int test_0_cos_precision () {
39                 double d1 = Math.Cos (1);
40                 double d2 = Math.Cos (1) - d1;
41                 return (d2 == 0) ? 0 : 1;
42         }
43
44         public static int test_0_tan_precision () {
45                 double d1 = Math.Tan (1);
46                 double d2 = Math.Tan (1) - d1;
47                 return (d2 == 0) ? 0 : 1;
48         }
49
50         public static int test_0_atan_precision () {
51                 double d1 = Math.Atan (double.NegativeInfinity);
52                 double d2 = Math.Atan (double.NegativeInfinity) - d1;
53                 return (d2 == 0) ? 0 : 1;
54         }
55
56         public static int test_0_sqrt_precision () {
57                 double d1 = Math.Sqrt (2);
58                 double d2 = Math.Sqrt (2) - d1;
59                 return (d2 == 0) ? 0 : 1;
60         }
61
62         public static int test_2_sqrt () {
63                 return (int) Math.Sqrt (4);
64         }
65         public static int test_0_sqrt_precision_and_not_spill () {
66                 double expected = 0;
67                 double[] operands = new double[3];
68                 double[] temporaries = new double[3];
69                 for (int i = 0; i < 3; i++) {
70                         operands [i] = (i+1) * (i+1) * (i+1);
71                         if (i == 0) {
72                                 expected = operands [0];
73                         } else {
74                                 temporaries [i] =  operands [i] / expected;
75                                 temporaries [i] = Math.Sqrt (temporaries [i]);
76                                 expected = temporaries [i];
77                         }
78                         
79                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
80                 }
81                 expected = temporaries [2];
82                 
83                 double result = Math.Sqrt (operands [2] / Math.Sqrt (operands [1] / operands [0]));
84                 
85                 //Console.Write( "result: {0,20:G}\n", result );
86                 
87                 return (result == expected) ? 0 : 1;
88         }
89         
90         public static int test_0_sqrt_precision_and_spill () {
91                 double expected = 0;
92                 double[] operands = new double[9];
93                 double[] temporaries = new double[9];
94                 for (int i = 0; i < 9; i++) {
95                         operands [i] = (i+1) * (i+1) * (i+1);
96                         if (i == 0) {
97                                 expected = operands [0];
98                         } else {
99                                 temporaries [i] =  operands [i] / expected;
100                                 temporaries [i] = Math.Sqrt (temporaries [i]);
101                                 expected = temporaries [i];
102                         }
103                         
104                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
105                 }
106                 expected = temporaries [8];
107                 
108                 double result = Math.Sqrt (operands [8] / Math.Sqrt (operands [7] / Math.Sqrt (operands [6] / Math.Sqrt (operands [5] / Math.Sqrt (operands [4] / Math.Sqrt (operands [3] / Math.Sqrt (operands [2] / Math.Sqrt (operands [1] / operands [0]))))))));
109                 
110                 //Console.Write( "result: {0,20:G}\n", result );
111                 
112                 return (result == expected) ? 0 : 1;
113         }
114         
115         public static int test_0_div_precision_and_spill () {
116                 double expected = 0;
117                 double[] operands = new double[9];
118                 double[] temporaries = new double[9];
119                 for (int i = 0; i < 9; i++) {
120                         operands [i] = (i+1) * (i+1);
121                         if (i == 0) {
122                                 expected = operands [0];
123                         } else {
124                                 temporaries [i] =  operands [i] / expected;
125                                 expected = temporaries [i];
126                         }
127                         
128                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
129                 }
130                 expected = temporaries [8];
131                 
132                 double result = (operands [8] / (operands [7] / (operands [6] / (operands [5] / (operands [4] / (operands [3] / (operands [2] / (operands [1] / operands [0]))))))));
133                 
134                 //Console.Write( "result: {0,20:G}\n", result );
135                 
136                 return (result == expected) ? 0 : 1;
137         }
138         
139         public static int test_0_sqrt_nan () {
140                 return Double.IsNaN (Math.Sqrt (Double.NaN)) ? 0 : 1;
141         }
142         
143         public static int test_0_sin_nan () {
144                 return Double.IsNaN (Math.Sin (Double.NaN)) ? 0 : 1;
145         }
146         
147         public static int test_0_cos_nan () {
148                 return Double.IsNaN (Math.Cos (Double.NaN)) ? 0 : 1;
149         }
150         
151         public static int test_0_tan_nan () {
152                 return Double.IsNaN (Math.Tan (Double.NaN)) ? 0 : 1;
153         }
154         
155         public static int test_0_atan_nan () {
156                 return Double.IsNaN (Math.Atan (Double.NaN)) ? 0 : 1;
157         }
158
159         public static int test_0_min () {
160                 if (Math.Min (5, 6) != 5)
161                         return 1;
162                 if (Math.Min (6, 5) != 5)
163                         return 2;
164                 if (Math.Min (-100, -101) != -101)
165                         return 3;
166                 if (Math.Min ((long)5, (long)6) != 5)
167                         return 4;
168                 if (Math.Min ((long)6, (long)5) != 5)
169                         return 5;
170                 if (Math.Min ((long)-100, (long)-101) != -101)
171                         return 6;
172                 return 0;
173         }
174
175         public static int test_0_max () {
176                 if (Math.Max (5, 6) != 6)
177                         return 1;
178                 if (Math.Max (6, 5) != 6)
179                         return 2;
180                 if (Math.Max (-100, -101) != -100)
181                         return 3;
182                 if (Math.Max ((long)5, (long)6) != 6)
183                         return 4;
184                 if (Math.Max ((long)6, (long)5) != 6)
185                         return 5;
186                 if (Math.Max ((long)-100, (long)-101) != -100)
187                         return 6;
188                 return 0;
189         }
190
191         public static int test_0_min_un () {
192                 uint a = (uint)int.MaxValue + 10;
193
194                 for (uint b = 7; b <= 10; ++b) {
195                         if (Math.Min (a, b) != b)
196                                 return (int)b;
197                         if (Math.Min (b, a) != b)
198                                 return (int)b;
199                 }
200
201                 if (Math.Min ((ulong)5, (ulong)6) != 5)
202                         return 4;
203                 if (Math.Min ((ulong)6, (ulong)5) != 5)
204                         return 5;
205
206                 ulong la = (ulong)long.MaxValue + 10;
207
208                 for (ulong b = 7; b <= 10; ++b) {
209                         if (Math.Min (la, b) != b)
210                                 return (int)b;
211                         if (Math.Min (b, la) != b)
212                                 return (int)b;
213                 }
214
215                 return 0;
216         }
217
218         public static int test_0_max_un () {
219                 uint a = (uint)int.MaxValue + 10;
220
221                 for (uint b = 7; b <= 10; ++b) {
222                         if (Math.Max (a, b) != a)
223                                 return (int)b;
224                         if (Math.Max (b, a) != a)
225                                 return (int)b;
226                 }
227
228                 if (Math.Max ((ulong)5, (ulong)6) != 6)
229                         return 4;
230                 if (Math.Max ((ulong)6, (ulong)5) != 6)
231                         return 5;
232
233                 ulong la = (ulong)long.MaxValue + 10;
234
235                 for (ulong b = 7; b <= 10; ++b) {
236                         if (Math.Max (la, b) != la)
237                                 return (int)b;
238                         if (Math.Max (b, la) != la)
239                                 return (int)b;
240                 }
241
242                 return 0;
243         }
244
245         public static int test_0_abs () {
246                 double d = -5.0;
247
248                 if (Math.Abs (d) != 5.0)
249                         return 1;
250                 return 0;
251         }
252
253         public static int test_0_round () {
254                 if (Math.Round (5.0) != 5.0)
255                         return 1;
256
257                 if (Math.Round (5.000000000000001) != 5.0)
258                         return 2;
259
260                 if (Math.Round (5.499999999999999) != 5.0)
261                         return 3;
262
263                 if (Math.Round (5.5) != 6.0)
264                         return 4;
265
266                 if (Math.Round (5.999999999999999) != 6.0)
267                         return 5;
268
269                 if (Math.Round (Double.Epsilon) != 0)
270                         return 6;
271
272                 if (!Double.IsNaN (Math.Round (Double.NaN)))
273                         return 7;
274
275                 if (!Double.IsPositiveInfinity (Math.Round (Double.PositiveInfinity)))
276                         return 8;
277
278                 if (!Double.IsNegativeInfinity (Math.Round (Double.NegativeInfinity)))
279                         return 9;
280
281                 if (Math.Round (Double.MinValue) != Double.MinValue)
282                         return 10;
283
284                 if (Math.Round (Double.MaxValue) != Double.MaxValue)
285                         return 11;
286
287                 return 0;
288         }
289 }