【问题标题】:Calling atan function on Blackberry 4.2 JDE在 Blackberry 4.2 JDE 上调用 atan 函数
【发布时间】:2009-09-21 15:59:32
【问题描述】:

我需要从我的 Blackberry Java 应用程序中计算反正切值。不幸的是,blackberry 4.2 api 没有 Math.atan() 函数。 Blackberry JDE 的 4.6 版有它,但没有 4.2。

有人知道计算 atan 的解决方法吗?

【问题讨论】:

  • 纯粹出于好奇,为什么需要 atan()?
  • @Dave 该函数不存在的原因是 BlackBerry Java 是从 J2ME 开始的,而不是从 J2SE 开始的,这正是您在移动领域所期望的。 J2ME 仍然没有 Math.atan() 的实现。

标签: math blackberry java-me rim-4.2


【解决方案1】:

来自Arctan in J2ME by Stephen Zimmerman

// calculation functions
public class Calculation {

    // Because J2ME has no floating point numbers,
    // some sort of fixed point math is required.
    // My implementation is simply to shift 10 places.
    // for example, 1024 (>> 10) = 1
    // and 512 (>> 10) = 0.5


public static final int[] AtanTable = { 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12,
            13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 
            30, 30,31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 40, 41, 
            42, 43, 43, 44, 45 };

    // / returns angle 0->359 in degrees
    public static int atan(int Y, int X) {
        boolean swap = false;

        int top = Math.abs(Y);
        int bottom = Math.abs(X);
        if (top > bottom) {
            int btemp = bottom;
            bottom = top;
            top = btemp;
            swap = true;
        } else if (bottom == 0)
            return -300;

        // this should keep index inbounds [0, 45]
        int index = (top * 45) / bottom;
        int angle = AtanTable[index];

        if (swap)
            angle = 90 - angle;

        // X & Y += 180
        // X & !Y = ...90
        // !X & Y = ... 270
        if ((X < 0) && (Y < 0))
            angle += 180;
        else if (Y < 0) {
            angle = 90 - angle;
            angle += 270;
        } else if (X < 0) {
            angle = 90 - angle;
            angle += 90;
        }

        if (angle == 360)
            angle = 0;

        return angle;
    }
}

【讨论】:

    【解决方案2】:

    当所有其他方法都失败时,可以通过估计arctan 函数的无限系列的结果来获得一个不错的值。

    Wikipedia page on inverse trigonometic functions 有一节介绍反三角函数的infinite series,包括arctan。为了得到一个估计值,可以进行无穷级数,直到获得所需的精度。

    至于没有包含arctan函数,可能是因为黑莓中的处理器不是很强大,需要大量的处理器资源来执行计算。

    此外,查看 Blackberry JDE 4.2 API 文档,似乎有一个名为 Fixed32 的定点数学库,它提供了两种类型的 arctan。它们使用 32 位整数执行计算,因此与执行浮点运算相比,它们可能提供一些性能优势。

    【讨论】:

      【解决方案3】:

      这是我使用的函数(不保证它非常快):

      /** Square root from 3 */
      final static public double SQRT3 = 1.732050807568877294;
      
      static public double atan(double x)
      {
          boolean signChange=false;
          boolean Invert=false;
          int sp=0;
          double x2, a;
          // check up the sign change
          if(x<0.)
          {
              x=-x;
              signChange=true;
          }
          // check up the invertation
          if(x>1.)
          {
              x=1/x;
              Invert=true;
          }
          // process shrinking the domain until x<PI/12
          while(x>Math.PI/12)
          {
              sp++;
              a=x+SQRT3;
              a=1/a;
              x=x*SQRT3;
              x=x-1;
              x=x*a;
          }
          // calculation core
          x2=x*x;
          a=x2+1.4087812;
          a=0.55913709/a;
          a=a+0.60310579;
          a=a-(x2*0.05160454);
          a=a*x;
          // process until sp=0
          while(sp>0)
          {
              a=a+Math.PI/6;
              sp--;
          }
          // invertation took place
          if(Invert) a=Math.PI/2-a;
          // sign change took place
          if(signChange) a=-a;
          //
          return a;
      }    
      

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题...缺少的数学函数可以在以下包中找到:

        net.rim.device.api.util.MathUtilities

        【讨论】:

          【解决方案5】:

          首先使用泰勒级数实现标准arctan(x)(如http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Infinite_series 所述)

          在调用 arctan 之前执行以下操作:

          1) 首先进行此项检查。

            if (x == 0) {
              return 0;        
            }
          

          2) 如果|x| &gt; 1,计算arctan(1/x),最后从Pi/2中减去结果

          3) 如果|x| 接近1,则使用半角公式计算半角的反正切值 arctan(x) = 2*arctan(x/(1+sqrt(1+x*x)))。即先计算半角,然后将结果乘以 2。否则,对于接近 1 的|x|,arctan 收敛非常慢。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多