티스토리 뷰

my Programing/J2ME

MathFP Class

Gandawon 2009. 9. 15. 12:25
   
public abstract class MathFP {
  public static final int MAX_VALUE = 0x7fffffff;
  public static final int MIN_VALUE = 0x80000001;
  public static final int PI = 12868;
  public static final int PI_DEMI = 6444;
  public static final int E = 11134;
  public static final int ZERO = 0;
  public static final int UN = 4096;
  public static final int DEUX = 8192;
  public static int toFP(int i) {
    return i << 12;
  }
  public static int toFP(int i, int f) {
    if (i == 0) {
      return (f << 12) / 1000;
    }
    else if (i > 0) {
      return (i << 12) + (f << 12) / 1000;
    }
    else {
      return - ( ( ( -i) << 12) + (f << 12) / 1000);
    }
  }
  public static int toFP(boolean s, int i, int f) {
    if (i < 0) {
      i = -i;
    }
    if (f < 0) {
      f = -f;
    }
    if (s) {
      return (i << 12) + (f << 12) / 1000;
    }
    else {
      return - ( (i << 12) + (f << 12) / 1000);
    }
  }
  public static int trunc(int i) {
    if (i >= 0) {
      return i >> 12;
    }
    else {
      return (i >> 12) + 1;
    }
  }
  public static int floor(int i) {
    return i >> 12;
  }
  public static int ceil(int i) {
    return (i >> 12) + 1;
  }
  public static int fract(int i) {
    if (i < 0) {
      i = -i;
    }
    return ( ( ( (i + 1) & 0x0fff) * 1000) >> 12);
  }

  public static int round(int i) {
    return round(i, 0);
  }
  public static int round(int i, int d) {
    boolean flag = false;
    if (i < 0) {
      flag = true;
      i = -i;
    }
    if (d == 0) {
      i = i + 2049;
    }
    else if (d == 1) {
      i = i + 206;
    }
    else if (d == 2) {
      i = i + 21;
    }
    else if (d == 3) {
      i = i + 2;
    }
    int k = i & 0xfff; // fractional part
    i = i & 0xfffff000; // integer part  
    // fract part
    int a;
    int m = 10;
    for (int l = 0; l < d; l++) {
      k = k * 10;
      a = k & 0xf000;
      i = i + a / m;
      m = m * 10;
      k = k & 0xfff;
    }
    if (flag) {
      return -i;
    }
    else {
      return i;
    }
  }
  public static char[] toString(int i) {
    boolean flag = false;
    if (i < 0) {
      flag = true;
      i = -i;
    }
    i = i + 2; // rounding to 1/1000 (1/1024 in fact)
    int j = i >> 12; // integer part
    int k = ( (i & 0xfff) * 10000) >> 12; // fractional part
    // int part
    int a;
    char[] t = new char[6];
    byte l = 0;
    do {
      a = j;
      j = j / 10;
      t[l] = (char) (a - j * 10 + 48);
      l++;
    }
    while (j > 0);
    // definitive alloc
    char[] r;
    byte m;
    if (flag) {
      r = new char[l + 5];
      r[0] = '-';
      m = 1;
    }
    else {
      r = new char[l + 4];
      m = 0;
    }
    // copy int part
    do {
      l--;
      r[m] = t[l];
      m++;
    }
    while (l > 0);
    // decimal point
    r[m] = 'o'; // because . not mapped on RCX ??
    // fract part    
    m += 3;
    k = k / 10; // drop last digit
    for (l = 0; l < 3; l++) {
      a = k;
      k = k / 10;
      r[m] = (char) (a - k * 10 + 48);
      m--;
    }
    return r;
  }
  public static int min(int i, int j) {
    return j >= i ? i : j;
  }
  public static int max(int i, int j) {
    return i >= j ? i : j;
  }
  public static int abs(int i) {
    if (i < 0) {
      return -i;
    }
    else {
      return i;
    }
  }
  public static int add(int i, int j) {
    return i + j;
  }
  public static int sub(int i, int j) {
    return i - j;
  }
  public static int mul(int i, int j) {
    boolean flag = false;
    if ( (i & 0xfff) == 0) {
      return (i >> 12) * j;
    }
    if ( (j & 0xfff) == 0) {
      return i * (j >> 12);
    }
    if (i < 0 && j > 0 || i > 0 && j < 0) {
      flag = true;
    }
    if (i < 0) {
      i = -i;
    }
    if (j < 0) {
      j = -j;
    }
    int i0 = ( (i >> 16) * (j >> 16));
    if (i0 < 0) {
      throw new ArithmeticException();
    }
    int i1 = (i >> 16) * (j & 0xffff) + (j >> 16) * (i & 0xffff); // overflow impossible ici
    if (i1 < 0) {
      throw new ArithmeticException();
    }
    int i2 = ( (i & 0xffff) * (j & 0xffff));
    int l = (i0 << 20) + (i1 << 4) + ( ( (i2 >> 11) + 1) >> 1);
    if (l < 0) {
      throw new ArithmeticException();
    }
    else {
      return flag ? -l : l;
    }
  }
  public static int div(int i, int j) {
    boolean flag = false;
    if (j == 4096) {
      return i;
    }
    if ( (j & 0xfff) == 0) {
      return i / (j >> 12);
    }
    if (i < 0) {
      i = -i;
      flag = true;
    }
    if (j < 0) {
      j = -j;
      if (flag) {
        flag = false;
      }
      else {
        flag = true;
      }
    }
    byte byte0 = 0;
    if (i > 0x64fff) {
      byte0 = 3;
    }
    if (i > 0x3e8fff) {
      byte0 = 4;
    }
    if (i > 0x7dffff) {
      byte0 = 6;
    }
    if (i > 0x1f4ffff) {
      byte0 = 8;
    }
    if (i > 0x7dfffff) {
      byte0 = 10;
    }
    if (byte0 > 0) {
      int k = 2 << byte0 - 1;
      i += k;
      j += k;
    }
    int l = (i << 12 - byte0) / (j >> byte0);
    return flag ? -l : l;
  }
  public static int sqrt(int a) {
    if (a < 0) {
      throw new ArithmeticException();
    }
    if (a == 0) {
      return 0;
    }
    int k;
    if ( (a & 0xf0000000) != 0) {
      k = 0x00200000; // for range 65535..524288
    }
    else if ( (a & 0x0ff00000) != 0) {
      k = 0x000B0000; // for range 256..65535
    }
    else if ( (a & 0x000ff000) != 0) {
      k = 0x0000B000; // for range 0..255
    }
    else if ( (a & 0x00000ff0) != 0) {
      k = 0x00000B00; // for negatives   
    }
    else {
      k = 0x000000B0; // for small negatives
    }
    for (int i = 0; i < 6; i++) { // 6 iterations should be OK
      k = (k + div(a, k)) >> 1;
    }
    if (k < 0) {
      return ZERO;
    }
    return k;
  }
  private static int FP180 = 737280;
  public static int toDeg(int a) {
    return div(mul(a, FP180), PI);
  }
  public static int toRad(int a) {
    return div(mul(a, PI), FP180);
  }
  public static int sin(int a) {
    int j = 0;
    for (; a < 0; a = a + 25736) {
      ; // normalize
    }
    if (a > 25736) {
      a = a % 25736;
    }
    int k = (a * 10) / 714; // compute index
    if (a != 0 && a != 6434 && a != 12868 && a != 19302 && a != 25736) {
      j = (a * 100) / 714 - k * 10;
    }
    if (k <= 90) {
      return sin_lookup(k, j);
    }
    if (k <= 180) {
      return sin_lookup(180 - k, j);
    }
    if (k <= 270) {
      return -sin_lookup(k - 180, j);
    }
    else {
      return -sin_lookup(360 - k, j);
    }
  }
  private static int sin_lookup(int i, int j) {
    if (j > 0 && j < 10 && i < 0) {
      return STAB[i] + ( (STAB[i + 1] - STAB[i]) / 10) * j;
    }
    else {
      return STAB[i];
    }
  }
  private static final int STAB[] = {
      0, 71, 142, 214, 285, 357, 428, 499, 570, 641,
      711, 781, 851, 921, 990, 1060, 1128, 1197, 1265, 1333,
      1400, 1468, 1534, 1600, 1665, 1730, 1795, 1859, 1922, 1985,
      2048, 2109, 2170, 2230, 2290, 2349, 2407, 2464, 2521, 2577,
      2632, 2686, 2740, 2793, 2845, 2896, 2946, 2995, 3043, 3091,
      3137, 3183, 3227, 3271, 3313, 3355, 3395, 3434, 3473, 3510,
      3547, 3582, 3616, 3649, 3681, 3712, 3741, 3770, 3797, 3823,
      3849, 3872, 3895, 3917, 3937, 3956, 3974, 3991, 4006, 4020,
      4033, 4045, 4056, 4065, 4073, 4080, 4086, 4090, 4093, 4095,
      4096
  };
  public static int cos(int a) {
    return sin(a + 6435);
  }
  public static int tan(int a) {
    int j = div(sin(a), cos(a));
    return j;
  }
  public static int cot(int a) {
    return div(UN, tan(a));
  }
  public static int asin(int e) {
    boolean flag = false;
    if (e < 0) {
      e = -e;
      flag = true;
    }
    if (e > UN) {
      throw new ArithmeticException();
    }
    int i = 0;
    int j = 90;
    int m;
    int d;
    while (i != (j - 1)) {
      m = (i + j) >> 1;
      d = e - STAB[m];
      if (d < 0) {
        j = m;
      }
      else {
        i = m;
      }
    }
    int a = i << 12;
    a = a + div(e - STAB[i], STAB[i + 1] - STAB[i]); // a is in degree
    a = toRad(a);
    if (flag) {
      return -a;
    }
    else {
      return a;
    }
  }
  public static int acos(int e) {
    return 36840 - asin(e);
  }
  public static int atan(int e) {
    boolean flag = false;
    if (e < 0) {
      e = -e;
      flag = true;
    }
    int i = 0;
    int j = 90;
    int m;
    int d;
    while (i != (j - 1)) {
      m = (i + j) >> 1;
      if (m == 90) {
        d = MAX_VALUE;
      }
      else {
        d = e - div(STAB[m], STAB[90 - m]);
      }
      if (d < 0) {
        j = m;
      }
      else {
        i = m;
      }
    }
    // linear interpolation between i and i+1
    int a = i << 12;
    int c0, c1;
    if (i == 90) {
      c0 = MAX_VALUE;
    }
    else {
      c0 = div(STAB[i], STAB[90 - i]);
    }
    if (i == 89) {
      c1 = MAX_VALUE;
    }
    else {
      c1 = div(STAB[i + 1], STAB[89 - i]);
    }
    a = a + div(e - c0, c1 - c0);
    a = toRad(a);
    if (flag) {
      return -a;
    }
    else {
      return a;
    }
  }
  public static int acot(int e) {
    return atan(div(UN, e));
  }
  public static int atan2(int x, int y) {
    int res = ZERO;
    if (x == 0) {
      if (y > 0) {
        return PI_DEMI;
      }
      else {
        return -PI_DEMI;
      }
    }
    res = atan(y / x);
    if (x < 0) {
      if (y == 0) {
        return PI;
      }
      else {
        if (y > 0) {
          return res + PI;
        }
        else {
          return res - PI;
        }
      }
    }
    return res;
  }
  public static int log(int a) {
    if (a <= 0) {
      throw new ArithmeticException();
    }
    int j = 0;
    boolean flag = false;
    int l;
    for (l = 0; a > 8192; l++) {
      a = a >> 1;
    }
    int i1 = l * 2839;
    int j1 = 0;
    a = a - UN;
    for (int k1 = 1; k1 < 11; k1++) {
      int k;
      if (j == 0) {
        k = a;
      }
      else {
        k = mul(j, a);
      }
      if (k == 0) {
        break;
      }
      j1 += ( (k1 % 2 != 0 ? 1 : -1) * k) / k1;
      j = k;
    }
    return i1 + j1;
  }
  private static int ETAB[] = {
      4096, 11134, 30266, 0x1415e, 0x36992, 0x9469c, 0x1936dc, 0x448a21,
      0xba4f54, 0x1fa7158, 0x560a774, 0xe9e2244, 0x27bc2ca9, 0x6c02d646
  };

  public static int exp(int a) {
    int j = abs(a) >> 12;
    if (j > 13) {
      throw new ArithmeticException();
    }
    int k = ETAB[j];
    int l = abs(a) & 0xfff;
    if (l > 0) {
      int i1 = 0;
      int j1 = 4096;
      int k1 = 1;
      for (int l1 = 0; l1 < 6; l1++) {
        i1 += j1 / k1;
        j1 = mul(j1, l);
        k1 *= l1 + 1;
      }
      k = mul(k, i1);
    }
    if (a < 0) {
      return div(UN, k);
    }
    else {
      return k;
    }
  }
  public static int pow(int a, int b) {
    // j est-il bien FP-float ?
    boolean flag = false;
    int k = 1;
    if (b < 0) {
      flag = true;
      b = -b;
    }
    if (abs(a) < 4096 && b > 12288) {
      k = exp(mul(log(a), b));
    }
    else {
      k = powInt(a, b >> 12);
      if ( (b & 0xfff) != 0) {
        k = mul(k, exp(mul(log(a), b & 0xfff)));
      }
    }
    if (flag) {
      return div(4096, k);
    }
    else {
      return k;
    }
  }
  public static int powInt(int a, int b) {
    if (a == 0) {
      if (b == 0) {
        throw new ArithmeticException();
      }
      else {
        return ZERO;
      }
    }
    else {
      if (b == 0) {
        return UN;
      }
    }
    int d = ( (b > 0) ? b : -b);
    int c = UN;
    int e = a;
    if (b > 0) {
      while (d != 0) {
        if ( (d & 1) != 0) {
          c = mul(c, e);
        }
        e = mul(e, e);
        d = d >> 1;
      }
    }
    else {
      if ( (d & 1) != 0) {
        c = div(c, e);
      }
      e = mul(e, e);
      d = d >> 1;
    }
    return c;
  }
}

'my Programing > J2ME' 카테고리의 다른 글

WMA 2.0과 Push Registry  (0) 2007.11.14
How to get IMEI in Java ME  (0) 2007.11.14
Java ME FAQ From Forum Nokia Wiki  (0) 2007.11.14
Supported Encodings  (0) 2007.10.29
댓글