Merge pull request #5714 from alexischr/update_bockbuild
[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 #if __MOBILE__
27 class MathTests
28 #else
29 class Tests
30 #endif
31 {
32
33 #if !__MOBILE__
34         public static int Main (string[] args) {
35                 return TestDriver.RunTests (typeof (Tests), args);
36         }
37 #endif
38         
39         public static int test_0_sin_precision () {
40                 double d1 = Math.Sin (1);
41                 double d2 = Math.Sin (1) - d1;
42                 return (d2 == 0) ? 0 : 1;
43         }
44
45         public static int test_0_cos_precision () {
46                 double d1 = Math.Cos (1);
47                 double d2 = Math.Cos (1) - d1;
48                 return (d2 == 0) ? 0 : 1;
49         }
50
51         public static int test_0_tan_precision () {
52                 double d1 = Math.Tan (1);
53                 double d2 = Math.Tan (1) - d1;
54                 return (d2 == 0) ? 0 : 1;
55         }
56
57         public static int test_0_atan_precision () {
58                 double d1 = Math.Atan (double.NegativeInfinity);
59                 double d2 = Math.Atan (double.NegativeInfinity) - d1;
60                 return (d2 == 0) ? 0 : 1;
61         }
62
63         public static int test_0_sqrt_precision () {
64                 double d1 = Math.Sqrt (2);
65                 double d2 = Math.Sqrt (2) - d1;
66                 return (d2 == 0) ? 0 : 1;
67         }
68
69         public static int test_2_sqrt () {
70                 return (int) Math.Sqrt (4);
71         }
72         public static int test_0_sqrt_precision_and_not_spill () {
73                 double expected = 0;
74                 double[] operands = new double[3];
75                 double[] temporaries = new double[3];
76                 for (int i = 0; i < 3; i++) {
77                         operands [i] = (i+1) * (i+1) * (i+1);
78                         if (i == 0) {
79                                 expected = operands [0];
80                         } else {
81                                 temporaries [i] =  operands [i] / expected;
82                                 temporaries [i] = Math.Sqrt (temporaries [i]);
83                                 expected = temporaries [i];
84                         }
85                         
86                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
87                 }
88                 expected = temporaries [2];
89                 
90                 double result = Math.Sqrt (operands [2] / Math.Sqrt (operands [1] / operands [0]));
91                 
92                 //Console.Write( "result: {0,20:G}\n", result );
93                 
94                 return (result == expected) ? 0 : 1;
95         }
96         
97         public static int test_0_sqrt_precision_and_spill () {
98                 double expected = 0;
99                 double[] operands = new double[9];
100                 double[] temporaries = new double[9];
101                 for (int i = 0; i < 9; i++) {
102                         operands [i] = (i+1) * (i+1) * (i+1);
103                         if (i == 0) {
104                                 expected = operands [0];
105                         } else {
106                                 temporaries [i] =  operands [i] / expected;
107                                 temporaries [i] = Math.Sqrt (temporaries [i]);
108                                 expected = temporaries [i];
109                         }
110                         
111                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
112                 }
113                 expected = temporaries [8];
114                 
115                 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]))))))));
116                 
117                 //Console.Write( "result: {0,20:G}\n", result );
118                 
119                 return (result == expected) ? 0 : 1;
120         }
121         
122         public static int test_0_div_precision_and_spill () {
123                 double expected = 0;
124                 double[] operands = new double[9];
125                 double[] temporaries = new double[9];
126                 for (int i = 0; i < 9; i++) {
127                         operands [i] = (i+1) * (i+1);
128                         if (i == 0) {
129                                 expected = operands [0];
130                         } else {
131                                 temporaries [i] =  operands [i] / expected;
132                                 expected = temporaries [i];
133                         }
134                         
135                         //Console.Write( "{0}: {1}\n", i, temporaries [i] );
136                 }
137                 expected = temporaries [8];
138                 
139                 double result = (operands [8] / (operands [7] / (operands [6] / (operands [5] / (operands [4] / (operands [3] / (operands [2] / (operands [1] / operands [0]))))))));
140                 
141                 //Console.Write( "result: {0,20:G}\n", result );
142                 
143                 return (result == expected) ? 0 : 1;
144         }
145         
146         public static int test_0_sqrt_nan () {
147                 return Double.IsNaN (Math.Sqrt (Double.NaN)) ? 0 : 1;
148         }
149         
150         public static int test_0_sin_nan () {
151                 return Double.IsNaN (Math.Sin (Double.NaN)) ? 0 : 1;
152         }
153         
154         public static int test_0_cos_nan () {
155                 return Double.IsNaN (Math.Cos (Double.NaN)) ? 0 : 1;
156         }
157         
158         public static int test_0_tan_nan () {
159                 return Double.IsNaN (Math.Tan (Double.NaN)) ? 0 : 1;
160         }
161         
162         public static int test_0_atan_nan () {
163                 return Double.IsNaN (Math.Atan (Double.NaN)) ? 0 : 1;
164         }
165
166         public static int test_0_min () {
167                 if (Math.Min (5, 6) != 5)
168                         return 1;
169                 if (Math.Min (6, 5) != 5)
170                         return 2;
171                 if (Math.Min (-100, -101) != -101)
172                         return 3;
173                 if (Math.Min ((long)5, (long)6) != 5)
174                         return 4;
175                 if (Math.Min ((long)6, (long)5) != 5)
176                         return 5;
177                 if (Math.Min ((long)-100, (long)-101) != -101)
178                         return 6;
179                 return 0;
180         }
181
182         public static int test_0_max () {
183                 if (Math.Max (5, 6) != 6)
184                         return 1;
185                 if (Math.Max (6, 5) != 6)
186                         return 2;
187                 if (Math.Max (-100, -101) != -100)
188                         return 3;
189                 if (Math.Max ((long)5, (long)6) != 6)
190                         return 4;
191                 if (Math.Max ((long)6, (long)5) != 6)
192                         return 5;
193                 if (Math.Max ((long)-100, (long)-101) != -100)
194                         return 6;
195                 return 0;
196         }
197
198         public static int test_0_min_un () {
199                 uint a = (uint)int.MaxValue + 10;
200
201                 for (uint b = 7; b <= 10; ++b) {
202                         if (Math.Min (a, b) != b)
203                                 return (int)b;
204                         if (Math.Min (b, a) != b)
205                                 return (int)b;
206                 }
207
208                 if (Math.Min ((ulong)5, (ulong)6) != 5)
209                         return 4;
210                 if (Math.Min ((ulong)6, (ulong)5) != 5)
211                         return 5;
212
213                 ulong la = (ulong)long.MaxValue + 10;
214
215                 for (ulong b = 7; b <= 10; ++b) {
216                         if (Math.Min (la, b) != b)
217                                 return (int)b;
218                         if (Math.Min (b, la) != b)
219                                 return (int)b;
220                 }
221
222                 return 0;
223         }
224
225         public static int test_0_max_un () {
226                 uint a = (uint)int.MaxValue + 10;
227
228                 for (uint b = 7; b <= 10; ++b) {
229                         if (Math.Max (a, b) != a)
230                                 return (int)b;
231                         if (Math.Max (b, a) != a)
232                                 return (int)b;
233                 }
234
235                 if (Math.Max ((ulong)5, (ulong)6) != 6)
236                         return 4;
237                 if (Math.Max ((ulong)6, (ulong)5) != 6)
238                         return 5;
239
240                 ulong la = (ulong)long.MaxValue + 10;
241
242                 for (ulong b = 7; b <= 10; ++b) {
243                         if (Math.Max (la, b) != la)
244                                 return (int)b;
245                         if (Math.Max (b, la) != la)
246                                 return (int)b;
247                 }
248
249                 return 0;
250         }
251
252         public static int test_0_abs () {
253                 double d = -5.0;
254
255                 if (Math.Abs (d) != 5.0)
256                         return 1;
257                 return 0;
258         }
259
260         public static int test_0_float_abs () {
261                 float f = -1.0f;
262
263                 if (Math.Abs (f) != 1.0f)
264                         return 1;
265                 return 0;
266         }
267
268         public static int test_0_round () {
269                 if (Math.Round (5.0) != 5.0)
270                         return 1;
271
272                 if (Math.Round (5.000000000000001) != 5.0)
273                         return 2;
274
275                 if (Math.Round (5.499999999999999) != 5.0)
276                         return 3;
277
278                 if (Math.Round (5.5) != 6.0)
279                         return 4;
280
281                 if (Math.Round (5.999999999999999) != 6.0)
282                         return 5;
283
284                 if (Math.Round (Double.Epsilon) != 0)
285                         return 6;
286
287                 if (!Double.IsNaN (Math.Round (Double.NaN)))
288                         return 7;
289
290                 if (!Double.IsPositiveInfinity (Math.Round (Double.PositiveInfinity)))
291                         return 8;
292
293                 if (!Double.IsNegativeInfinity (Math.Round (Double.NegativeInfinity)))
294                         return 9;
295
296                 if (Math.Round (Double.MinValue) != Double.MinValue)
297                         return 10;
298
299                 if (Math.Round (Double.MaxValue) != Double.MaxValue)
300                         return 11;
301
302                 return 0;
303         }
304 }