OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 class MathTest { | |
6 static void testConstants() { | |
7 // Source for mathematical constants is Wolfram Alpha. | |
8 Expect.equals(2.7182818284590452353602874713526624977572470936999595749669, | |
9 Math.E); | |
10 Expect.equals(2.3025850929940456840179914546843642076011014886287729760333, | |
11 Math.LN10); | |
12 Expect.equals(0.6931471805599453094172321214581765680755001343602552541206, | |
13 Math.LN2); | |
14 Expect.equals(1.4426950408889634073599246810018921374266459541529859341354, | |
15 Math.LOG2E); | |
16 Expect.equals(0.4342944819032518276511289189166050822943970058036665661144, | |
17 Math.LOG10E); | |
18 Expect.equals(3.1415926535897932384626433832795028841971693993751058209749, | |
19 Math.PI); | |
20 Expect.equals(0.7071067811865475244008443621048490392848359376884740365883, | |
21 Math.SQRT1_2); | |
22 Expect.equals(1.4142135623730950488016887242096980785696718753769480731766, | |
23 Math.SQRT2); | |
24 } | |
25 | |
26 static checkClose(double a, double b, EPSILON) { | |
27 Expect.equals(true, a - EPSILON <= b); | |
28 Expect.equals(true, b <= a + EPSILON); | |
29 } | |
30 | |
31 static void testSin() { | |
32 // Given the imprecision of PI we can't expect better results than this. | |
33 final double EPSILON = 1e-15; | |
34 checkClose(0.0, Math.sin(0.0), EPSILON); | |
35 checkClose(0.0, Math.sin(Math.PI), EPSILON); | |
36 checkClose(0.0, Math.sin(2.0 * Math.PI), EPSILON); | |
37 checkClose(1.0, Math.sin(Math.PI / 2.0), EPSILON); | |
38 checkClose(-1.0, Math.sin(Math.PI * (3.0 / 2.0)), EPSILON); | |
39 } | |
40 | |
41 static void testCos() { | |
42 // Given the imprecision of PI we can't expect better results than this. | |
43 final double EPSILON = 1e-15; | |
44 checkClose(1.0, Math.cos(0.0), EPSILON); | |
45 checkClose(-1.0, Math.cos(Math.PI), EPSILON); | |
46 checkClose(1.0, Math.cos(2.0 * Math.PI), EPSILON); | |
47 checkClose(0.0, Math.cos(Math.PI / 2.0), EPSILON); | |
48 checkClose(0.0, Math.cos(Math.PI * (3.0 / 2.0)), EPSILON); | |
49 } | |
50 | |
51 static void testTan() { | |
52 // Given the imprecision of PI we can't expect better results than this. | |
53 final double EPSILON = 1e-15; | |
54 checkClose(0.0, Math.tan(0.0), EPSILON); | |
55 checkClose(0.0, Math.tan(Math.PI), EPSILON); | |
56 checkClose(0.0, Math.tan(2.0 * Math.PI), EPSILON); | |
57 checkClose(1.0, Math.tan(Math.PI / 4.0), EPSILON); | |
58 } | |
59 | |
60 static void testAsin() { | |
61 // Given the imprecision of PI we can't expect better results than this. | |
62 final double EPSILON = 1e-15; | |
63 checkClose(0.0, Math.asin(0.0), EPSILON); | |
64 checkClose(Math.PI / 2.0, Math.asin(1.0), EPSILON); | |
65 checkClose(-Math.PI / 2.0, Math.asin(-1.0), EPSILON); | |
66 } | |
67 | |
68 | |
69 static void testAcos() { | |
70 // Given the imprecision of PI we can't expect better results than this. | |
71 final double EPSILON = 1e-15; | |
72 checkClose(0.0, Math.acos(1.0), EPSILON); | |
73 checkClose(Math.PI, Math.acos(-1.0), EPSILON); | |
74 checkClose(Math.PI / 2.0, Math.acos(0.0), EPSILON); | |
75 } | |
76 | |
77 static void testAtan() { | |
78 // Given the imprecision of PI we can't expect better results than this. | |
79 final double EPSILON = 1e-15; | |
80 checkClose(0.0, Math.atan(0.0), EPSILON); | |
81 checkClose(Math.PI / 4.0, Math.atan(1.0), EPSILON); | |
82 checkClose(-Math.PI / 4.0, Math.atan(-1.0), EPSILON); | |
83 } | |
84 | |
85 static void testAtan2() { | |
86 // Given the imprecision of PI we can't expect better results than this. | |
87 final double EPSILON = 1e-15; | |
88 checkClose(0.0, Math.atan2(0.0, 5.0), EPSILON); | |
89 checkClose(Math.PI / 4.0, Math.atan2(2.0, 2.0), EPSILON); | |
90 checkClose(3 * Math.PI / 4.0, Math.atan2(0.5, -0.5), EPSILON); | |
91 checkClose(-3 * Math.PI / 4.0, Math.atan2(-2.5, -2.5), EPSILON); | |
92 } | |
93 | |
94 static checkVeryClose(double a, double b) { | |
95 // We find a ulp (unit in the last place) by shifting the original number | |
96 // to the right. This only works if we are not too close to infinity or if | |
97 // we work with denormals. | |
98 // We special case or 0.0, but not for infinity. | |
99 if (a == 0.0) { | |
100 final minimalDouble = 4.9406564584124654e-324; | |
101 Expect.equals(true, b.abs() <= minimalDouble); | |
102 return; | |
103 } | |
104 if (b == 0.0) { | |
105 // No need to look if they are close. Otherwise the check for 'a' above | |
106 // whould have triggered. | |
107 Expect.equals(a, b); | |
108 } | |
109 final double shiftRightBy52 = 2.220446049250313080847263336181640625e-16; | |
110 final double shiftedA = (a * shiftRightBy52).abs(); | |
111 // Compared to 'a', 'shiftedA' is now ~1-2 ulp. | |
112 | |
113 final double limitLow = a - shiftedA; | |
114 final double limitHigh = a + shiftedA; | |
115 Expect.equals(false, a == limitLow); | |
116 Expect.equals(false, a == limitHigh); | |
117 Expect.equals(true, limitLow <= b); | |
118 Expect.equals(true, b <= limitHigh); | |
119 } | |
120 | |
121 static void testSqrt() { | |
122 checkVeryClose(2.0, Math.sqrt(4.0)); | |
123 checkVeryClose(Math.SQRT2, Math.sqrt(2.0)); | |
124 checkVeryClose(Math.SQRT1_2, Math.sqrt(0.5)); | |
125 checkVeryClose(1e50, Math.sqrt(1e100)); | |
126 checkVeryClose(1.1111111061110855443054405046358901279277111935183977e56, | |
127 Math.sqrt(12345678901234e99)); | |
128 } | |
129 | |
130 static void testExp() { | |
131 checkVeryClose(Math.E, Math.exp(1.0)); | |
132 final EPSILON = 1e-15; | |
133 checkClose(10.0, Math.exp(Math.LN10), EPSILON); | |
134 checkClose(2.0, Math.exp(Math.LN2), EPSILON); | |
135 } | |
136 | |
137 static void testLog() { | |
138 // Even though E is imprecise, it is good enough to get really close to 1. | |
139 // We still provide an epsilon. | |
140 checkClose(1.0, Math.log(Math.E), 1e-16); | |
141 checkVeryClose(Math.LN10, Math.log(10.0)); | |
142 checkVeryClose(Math.LN2, Math.log(2.0)); | |
143 } | |
144 | |
145 static void testPow() { | |
146 checkVeryClose(16.0, Math.pow(4.0, 2.0)); | |
147 checkVeryClose(Math.SQRT2, Math.pow(2.0, 0.5)); | |
148 checkVeryClose(Math.SQRT1_2, Math.pow(0.5, 0.5)); | |
149 } | |
150 | |
151 static bool parseIntThrowsBadNumberFormatException(str) { | |
152 try { | |
153 Math.parseInt(str); | |
154 return false; | |
155 } catch (BadNumberFormatException e) { | |
156 return true; | |
157 } | |
158 } | |
159 | |
160 static void testParseInt() { | |
161 Expect.equals(499, Math.parseInt("499")); | |
162 Expect.equals(499, Math.parseInt("+499")); | |
163 Expect.equals(-499, Math.parseInt("-499")); | |
164 Expect.equals(499, Math.parseInt(" 499 ")); | |
165 Expect.equals(499, Math.parseInt(" +499 ")); | |
166 Expect.equals(-499, Math.parseInt(" -499 ")); | |
167 Expect.equals(0, Math.parseInt("0")); | |
168 Expect.equals(0, Math.parseInt("+0")); | |
169 Expect.equals(0, Math.parseInt("-0")); | |
170 Expect.equals(0, Math.parseInt(" 0 ")); | |
171 Expect.equals(0, Math.parseInt(" +0 ")); | |
172 Expect.equals(0, Math.parseInt(" -0 ")); | |
173 Expect.equals(0x1234567890, Math.parseInt("0x1234567890")); | |
174 Expect.equals(0x1234567890, Math.parseInt("+0x1234567890")); | |
175 Expect.equals(-0x1234567890, Math.parseInt("-0x1234567890")); | |
176 Expect.equals(0x1234567890, Math.parseInt(" 0x1234567890 ")); | |
177 Expect.equals(0x1234567890, Math.parseInt(" +0x1234567890 ")); | |
178 Expect.equals(-0x1234567890, Math.parseInt(" -0x1234567890 ")); | |
179 Expect.equals(256, Math.parseInt("0x100")); | |
180 Expect.equals(256, Math.parseInt("+0x100")); | |
181 Expect.equals(-256, Math.parseInt("-0x100")); | |
182 Expect.equals(256, Math.parseInt(" 0x100 ")); | |
183 Expect.equals(256, Math.parseInt(" +0x100 ")); | |
184 Expect.equals(-256, Math.parseInt(" -0x100 ")); | |
185 Expect.equals(0xabcdef, Math.parseInt("0xabcdef")); | |
186 Expect.equals(0xABCDEF, Math.parseInt("0xABCDEF")); | |
187 Expect.equals(0xabcdef, Math.parseInt("0xabCDEf")); | |
188 Expect.equals(-0xabcdef, Math.parseInt("-0xabcdef")); | |
189 Expect.equals(-0xABCDEF, Math.parseInt("-0xABCDEF")); | |
190 Expect.equals(0xabcdef, Math.parseInt(" 0xabcdef ")); | |
191 Expect.equals(0xABCDEF, Math.parseInt(" 0xABCDEF ")); | |
192 Expect.equals(-0xabcdef, Math.parseInt(" -0xabcdef ")); | |
193 Expect.equals(-0xABCDEF, Math.parseInt(" -0xABCDEF ")); | |
194 Expect.equals(0xabcdef, Math.parseInt("0x00000abcdef")); | |
195 Expect.equals(0xABCDEF, Math.parseInt("0x00000ABCDEF")); | |
196 Expect.equals(-0xabcdef, Math.parseInt("-0x00000abcdef")); | |
197 Expect.equals(-0xABCDEF, Math.parseInt("-0x00000ABCDEF")); | |
198 Expect.equals(0xabcdef, Math.parseInt(" 0x00000abcdef ")); | |
199 Expect.equals(0xABCDEF, Math.parseInt(" 0x00000ABCDEF ")); | |
200 Expect.equals(-0xabcdef, Math.parseInt(" -0x00000abcdef ")); | |
201 Expect.equals(-0xABCDEF, Math.parseInt(" -0x00000ABCDEF ")); | |
202 Expect.equals(10, Math.parseInt("010")); | |
203 Expect.equals(-10, Math.parseInt("-010")); | |
204 Expect.equals(10, Math.parseInt(" 010 ")); | |
205 Expect.equals(-10, Math.parseInt(" -010 ")); | |
206 Expect.equals(9, Math.parseInt("09")); | |
207 Expect.equals(9, Math.parseInt(" 09 ")); | |
208 Expect.equals(-9, Math.parseInt("-09")); | |
209 Expect.equals(true, parseIntThrowsBadNumberFormatException("1b")); | |
210 Expect.equals(true, parseIntThrowsBadNumberFormatException(" 1b ")); | |
211 Expect.equals(true, parseIntThrowsBadNumberFormatException(" 1 b ")); | |
212 Expect.equals(true, parseIntThrowsBadNumberFormatException("1e2")); | |
213 Expect.equals(true, parseIntThrowsBadNumberFormatException(" 1e2 ")); | |
214 Expect.equals(true, parseIntThrowsBadNumberFormatException("00x12")); | |
215 Expect.equals(true, parseIntThrowsBadNumberFormatException(" 00x12 ")); | |
216 Expect.equals(true, parseIntThrowsBadNumberFormatException("-1b")); | |
217 Expect.equals(true, parseIntThrowsBadNumberFormatException(" -1b ")); | |
218 Expect.equals(true, parseIntThrowsBadNumberFormatException(" -1 b ")); | |
219 Expect.equals(true, parseIntThrowsBadNumberFormatException("-1e2")); | |
220 Expect.equals(true, parseIntThrowsBadNumberFormatException(" -1e2 ")); | |
221 Expect.equals(true, parseIntThrowsBadNumberFormatException("-00x12")); | |
222 Expect.equals(true, parseIntThrowsBadNumberFormatException(" -00x12 ")); | |
223 Expect.equals(true, parseIntThrowsBadNumberFormatException(" -00x12 ")); | |
224 Expect.equals(true, parseIntThrowsBadNumberFormatException("0x0x12")); | |
225 Expect.equals(true, parseIntThrowsBadNumberFormatException("0.1")); | |
226 Expect.equals(true, parseIntThrowsBadNumberFormatException("0x3.1")); | |
227 Expect.equals(true, parseIntThrowsBadNumberFormatException("5.")); | |
228 Expect.equals(true, parseIntThrowsBadNumberFormatException("+-5")); | |
229 Expect.equals(true, parseIntThrowsBadNumberFormatException("-+5")); | |
230 Expect.equals(true, parseIntThrowsBadNumberFormatException("--5")); | |
231 Expect.equals(true, parseIntThrowsBadNumberFormatException("++5")); | |
232 Expect.equals(true, parseIntThrowsBadNumberFormatException("+ 5")); | |
233 Expect.equals(true, parseIntThrowsBadNumberFormatException("- 5")); | |
234 Expect.equals(true, parseIntThrowsBadNumberFormatException("")); | |
235 Expect.equals(true, parseIntThrowsBadNumberFormatException(" ")); | |
236 } | |
237 | |
238 static testMain() { | |
239 testConstants(); | |
240 testSin(); | |
241 testCos(); | |
242 testTan(); | |
243 testAsin(); | |
244 testAcos(); | |
245 testAtan(); | |
246 testAtan2(); | |
247 testSqrt(); | |
248 testLog(); | |
249 testExp(); | |
250 testPow(); | |
251 testParseInt(); | |
252 } | |
253 } | |
254 | |
255 main() { | |
256 MathTest.testMain(); | |
257 } | |
OLD | NEW |