这是我在开发中经常用到的类,为了模拟小数点运算以及实现j2me的Math没有提供的数学运算。
1/** *//**
2 * 定点数数学类
3 * 模拟浮点数运算以及一些Math类没有的数学运算
4 *
5 * @author Colonleado
6 *
7 */
8public abstract class CMathFP {
9
10 private static int _fbits = 24;
11
12 private static int _digits = 8;
13
14 public static long _one;
15
16 private static long _fmask = 0xffffffL;
17
18 private static long _dmul = 0x5f5e100L;
19
20 private static long _flt = 0L;
21
22 private static long _pi;
23
24 private static long e[];
25
26 public static long PI;
27
28 public static long E;
29
30 public static final long MAX_VALUE = 0x7fffffffffffffffL;
31
32 public static final long MIN_VALUE = 0x8000000000000001L;
33
34 public CMathFP() {
35 }
36
37 static {
38 _one = 0x1000000L;
39 _pi = 0x3243f6aL;
40 e = (new long[] { _one, 0x2b7e151L, 0x763992eL, 0x1415e5bfL,
41 0x3699205cL });
42 PI = _pi;
43 E = e[1];
44 }
45
46 public static int setPrecision(int i) {
47 if (i > 24 || i < 0)
48 return _digits;
49 _fbits = i;
50 _one = 1L << i;
51 _flt = 24 - i;
52 _digits = 0;
53 _dmul = 1L;
54 _fmask = _one - 1L;
55 PI = _pi >> (int) _flt;
56 E = e[1] >> (int) _flt;
57 for (long l = _one; l != 0L;) {
58 l /= 10L;
59 _digits++;
60 _dmul *= 10L;
61 }
62
63 return _digits;
64 }
65
66 public static int getPrecision() {
67 return _fbits;
68 }
69
70
71 public static long toLong(long l) {
72 l = round(l, 0);
73 return l >> _fbits;
74 }
75
76
77 public static long toFP(long l) {
78 return l << _fbits;
79 }
80
81 public static long convert(long l, int i) {
82 long l1 = l >= 0L ? 1L : -1L;
83 if (abs(i) < 25L)
84 if (_fbits < i)
85 l = l + l1 * (1L << (i - _fbits >> 1)) >> i - _fbits;
86 else
87 l <<= _fbits - i;
88 return l;
89 }
90
91
92 public static long toFP(String s) {
93 int i = 0;
94 if (s.charAt(0) == '-')
95 i = 1;
96 String s1 = "-1";
97 int j = s.indexOf('.');
98 if (j >= 0) {
99 for (s1 = s.substring(j + 1, s.length()); s1.length() < _digits; s1 = s1
100 + "0")
101 ;
102 if (s1.length() > _digits)
103 s1 = s1.substring(0, _digits);
104 } else {
105 j = s.length();
106 }
107 long l = 0L;
108 if (i != j)
109 l = Long.parseLong(s.substring(i, j));
110 long l1 = Long.parseLong(s1) + 1L;
111 long l2 = (l << _fbits) + (l1 << _fbits) / _dmul;
112 if (i == 1)
113 l2 = -l2;
114 return l2;
115 }
116
117
118 public static String toString(long l) {
119 boolean flag = false;
120 if (l < 0L) {
121 flag = true;
122 l = -l;
123 }
124 long l1 = l >> _fbits;
125 long l2 = _dmul * (l & _fmask) >> _fbits;
126 String s;
127 for (s = Long.toString(l2); s.length() < _digits; s = "0" + s)
128 ;
129 return (flag ? "-" : "") + Long.toString(l1) + "." + s;
130 }
131
132
133 public static String toString(long l, int i) {
134 if (i > _digits)
135 i = _digits;
136 String s = toString(round(l, i));
137 return s.substring(0, (s.length() - _digits) + i);
138 }
139
140 public static long max(long l, long l1) {
141 return l >= l1 ? l : l1;
142 }
143
144
145 public static long min(long l, long l1) {
146 return l1 >= l ? l : l1;
147 }
148
149
150 public static long round(long l, int i) {
151 long l1 = 10L;
152 for (int j = 0; j < i; j++)
153 l1 *= 10L;
154
155 l1 = div(toFP(5L), toFP(l1));
156 if (l < 0L)
157 l1 = -l1;
158 return l + l1;
159 }
160
161
162 public static long mul(long l, long l1) {
163 boolean flag = false;
164 int i = _fbits;
165 long l2 = _fmask;
166 if ((l & l2) == 0L)
167 return (l >> i) * l1;
168 if ((l1 & l2) == 0L)
169 return l * (l1 >> i);
170 if (l < 0L && l1 > 0L || l > 0L && l1 < 0L)
171 flag = true;
172 if (l < 0L)
173 l = -l;
174 if (l1 < 0L)
175 l1 = -l1;
176 for (; max(l, l1) >= 1L << 63 - i; i--) {
177 l >>= 1;
178 l1 >>= 1;
179 l2 >>= 1;
180 }
181
182 long l3 = (l >> i) * (l1 >> i) << i;
183 long l4 = (l & l2) * (l1 & l2) >> i;
184 l4 += (l & ~l2) * (l1 & l2) >> i;
185 l3 = l3 + l4 + ((l & l2) * (l1 & ~l2) >> i) << _fbits - i;
186 if (l3 < 0L)
187 throw new ArithmeticException("Overflow");
188 else
189 return flag ? -l3 : l3;
190 }
191
192 public static long div(long l, long l1) {
193 boolean flag = false;
194 int i = _fbits;
195 if (l1 == _one)
196 return l;
197 if ((l1 & _fmask) == 0L)
198 return l / (l1 >> i);
199 if (l < 0L && l1 > 0L || l > 0L && l1 < 0L)
200 flag = true;
201 if (l < 0L)
202 l = -l;
203 if (l1 < 0L)
204 l1 = -l1;
205 for (; max(l, l1) >= 1L << 63 - i; i--) {
206 l >>= 1;
207 l1 >>= 1;
208 }
209
210 long l2 = (l << i) / l1 << _fbits - i;
211 return flag ? -l2 : l2;
212 }
213
214 public static long add(long l, long l1) {
215 return l + l1;
216 }
217
218
219 public static long sub(long l, long l1) {
220 return l - l1;
221 }
222
223 public static long abs(long l) {
224 if (l < 0L)
225 return -l;
226 else
227 return l;
228 }
229
230
231 public static int abs(int l) {
232 if (l < 0L)
233 return -l;
234 else
235 return l;
236 }
237
238
239 public static long sqrt(long l, int i) {
240 if (l < 0L)
241 throw new ArithmeticException("Bad Input");
242 if (l == 0L)
243 return 0L;
244 long l1 = l + _one >> 1;
245 for (int j = 0; j < i; j++)
246 l1 = l1 + div(l, l1) >> 1;
247
248 if (l1 < 0L)
249 throw new ArithmeticException("Overflow");
250 else
251 return l1;
252 }
253
254
255 public static long sqrt(long l) {
256 return sqrt(l, 24);
257 }
258
259
260 public static long sin(long l) {
261 long l1 = mul(l, div(toFP(180L), PI));
262 l1 %= toFP(360L);
263 if (l1 < 0L)
264 l1 = toFP(360L) + l1;
265 long l2 = l1;
266 if (l1 >= toFP(90L) && l1 < toFP(270L))
267 l2 = toFP(180L) - l1;
268 else if (l1 >= toFP(270L) && l1 < toFP(360L))
269 l2 = -(toFP(360L) - l1);
270 long l3 = l2 / 90L;
271 long l4 = mul(l3, l3);
272 long l5 = mul(mul(mul(mul(0xfffffffffffee21aL >> (int) _flt, l4)
273 + (0x14594dL >> (int) _flt), l4)
274 - (0xa55b13L >> (int) _flt), l4)
275 + (long) (0x1921f9c >> (int) _flt), l3);
276 return l5;
277 }
278
279
280 public static long asin(long l) {
281 if (abs(l) > _one) {
282 throw new ArithmeticException("Bad Input");
283 } else {
284 boolean flag = l < 0L;
285 l = abs(l);
286 long l1 = mul(mul(mul(mul(0x236cf >> (int) _flt, l)
287 - (long) (0x92748 >> (int) _flt), l)
288 + (long) (0x15acb4 >> (int) _flt), l)
289 - (long) (0x36d0dd >> (int) _flt), l)
290 + (long) (0x1921f27 >> (int) _flt);
291 long l2 = PI / 2L - mul(sqrt(_one - l), l1);
292 return flag ? -l2 : l2;
293 }
294 }
295
296
297 public static long cos(long l) {
298 return sin(PI / 2L - l);
299 }
300
301
302 public static long acos(long l) {
303 return PI / 2L - asin(l);
304 }
305
306
307 public static long tan(long l) {
308 return div(sin(l), cos(l));
309 }
310
311
312 public static long cot(long l) {
313 return div(cos(l), sin(l));
314 }
315
316
317 public static long atan(long l) {
318 return asin(div(l, sqrt(_one + mul(l, l))));
319 }
320
321 public static long exp(long l) {
322 if (l == 0L)
323 return _one;
324 boolean flag = l < 0L;
325 l = abs(l);
326 int i = (int) (l >> _fbits);
327 long l1 = _one;
328 for (int j = 0; j < i / 4; j++)
329 l1 = mul(l1, e[4] >> (int) _flt);
330
331 if (i % 4 > 0)
332 l1 = mul(l1, e[i % 4] >> (int) _flt);
333 l &= _fmask;
334 if (l > 0L) {
335 long l2 = _one;
336 long l3 = 0L;
337 long l4 = 1L;
338 for (int k = 0; k < 16; k++) {
339 l3 += l2 / l4;
340 l2 = mul(l2, l);
341 l4 *= k + 1;
342 if (l4 > l2 || l2 <= 0L || l4 <= 0L)
343 break;
344 }
345
346 l1 = mul(l1, l3);
347 }
348 if (flag)
349 l1 = div(_one, l1);
350 return l1;
351 }
352
353
354 public static long log(long l) {
355 if (l <= 0L)
356 throw new ArithmeticException("Bad Input");
357 long l1 = 0L;
358// long l2 = 0L;
359 int i;
360 for (i = 0; l >= _one << 1; i++)
361 l >>= 1;
362
363 long l4 = (long) i * (long) (0xb17218 >> (int) _flt);
364 long l5 = 0L;
365 if (l < _one)
366 return -log(div(_one, l));
367 l -= _one;
368 for (int j = 1; j < 20; j++) {
369 long l3;
370 if (l1 == 0L)
371 l3 = l;
372 else
373 l3 = mul(l1, l);
374 if (l3 == 0L)
375 break;
376 l5 += ((j % 2 != 0 ? 1L : -1L) * l3) / (long) j;
377 l1 = l3;
378 }
379
380 return l4 + l5;
381 }
382
383
384 public static long pow(long l, long l1) {
385 boolean flag = l1 < 0L;
386 long l2 = _one;
387 l1 = abs(l1);
388 for (int i = (int) l1 >> _fbits; i-- > 0;)
389 l2 = mul(l2, l);
390
391 if (l2 < 0L)
392 throw new ArithmeticException("Overflow");
393 if (l != 0L)
394 l2 = mul(l2, exp(mul(log(l), l1 & _fmask)));
395 else
396 l2 = 0L;
397 if (flag)
398 return div(_one, l2);
399 else
400 return l2;
401 }
402
403 public static long asin2(long x, long y, long j) {
404 if (j <= 0L) {
405 j = sqrt(add(mul(x, x), mul(y, y)));
406 }
407 if (x > j)
408 throw new ArithmeticException("Bad Input");
409 long m = abs(div(x, j));
410 long n = mul(mul(mul(mul(0x236cf >> (int) _flt, m)
411 - (long) (0x92748 >> (int) _flt), m)
412 + (long) (0x15acb4 >> (int) _flt), m)
413 - (long) (0x36d0dd >> (int) _flt), m)
414 + (long) (0x1921f27 >> (int) _flt);
415 long k = PI / 2 - mul(sqrt(_one - m), n);
416 return getRadian(k, x, y);
417 }
418
419 public static long acos2(long x, long y, long j) {
420 if (j <= 0L) {
421 j = sqrt(add(mul(x, x), mul(y, y)));
422 }
423 if (x > j)
424 throw new ArithmeticException("Bad Input");
425 long m = abs(div(y, j));
426 long k = PI / 2 - asin(m);
427 return getRadian(k, x, y);
428 }
429
430 /**//*
431 * public static long atan2( long l, long l1 ) { long l2 = 0L; if ( l1 > 0L
432 * ) l2 = atan( div( l, l1 ) ); else if ( l1 < 0L ) { l2 = ( l1 >= 0L ? PI :
433 * -PI ) - atan( abs( div( l, l1 ) ) ); } else { if ( l1 == 0L && l == 0L )
434 * throw new ArithmeticException( "Bad Input" ); l2 = ( l >= 0L ? PI : -PI )
435 * / 2L; } return l2; }
436 */
437
438
439 public static long atan2(long y, long x) {
440 if (x == 0L)
441 throw new ArithmeticException("Bad Input");
442 if (y == 0L) {
443 if (x < 0L)
444 return PI;
445 return 0L;
446 }
447 long k = atan(abs(div(y, x)));
448 return getRadian(k, y, x);
449 }
450
451
452 public static long getRadian(long k, long x, long y) {
453 if (x < 0L && y > 0L) {
454 return PI * 2 - k;
455 } else if (x < 0L && y < 0L) {
456 return PI + k;
457 } else if (x > 0L && y < 0L) {
458 return PI - k;
459 }
460 return k;
461 }
462}