这是我在开发中经常用到的类,为了模拟小数点运算以及实现j2me的Math没有提供的数学运算。
1
/** *//**
2
* 定点数数学类
3
* 模拟浮点数运算以及一些Math类没有的数学运算
4
*
5
* @author Colonleado
6
*
7
*/
8
public 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
}