colonleado's

关于游戏也关于技术 im Co
数据加载中……
J2me定点数数学类
这是我在开发中经常用到的类,为了模拟小数点运算以及实现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, 0x2b7e151L0x763992eL0x1415e5bfL,
 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}


posted on 2010-08-21 16:22 colonleado 阅读(1328) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: