2009-09-21 60 views
2

我需要從我的Blackberry Java應用程序計算arc tan值。不幸的是,黑莓4.2 api沒有Math.atan()函數。天知道爲什麼,但那是你的黑莓API。黑莓JDE的4.6版有它,但不是4.2。在Blackberry 4.2上調用atan函數JDE

有誰知道計算atan的解決方法嗎?

+0

出於純粹的好奇,爲什麼你需要ATAN()? – Calyth 2009-09-21 16:57:07

+0

@Dave該函數不存在的原因是BlackBerry Java從J2ME開始,而不是從J2SE開始,這正是您期望在移動領域中所期望的。 J2ME仍然沒有Math.atan()的實現。 – Fostah 2009-09-21 17:02:45

回答

2

當所有其他都失敗時,通過估計arctan函數的無限級數的結果,可能可以獲得相當不錯的值。

Wikipedia page on inverse trigonometic functions有一個反三角函數的infinite series部分,包括arctan。爲了獲得一個估計,人們將執行無限序列,直到獲得所需的精度。

至於爲什麼不包括arctan函數的原因,可能是因爲黑莓中的處理器功能不是很強大,並且需要大量的處理器資源來執行計算。

此外,看着黑莓JDE 4.2 API文檔,似乎有一個定點數學庫叫Fixed32它提供了兩種arctan。它們使用32位整數執行計算,因此它們可能比執行浮點算法具有一些性能優勢。

3

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; 
    } 
} 
1

這裏是我使用(沒有保證,它是非常快的)功能:使用泰勒級數(截至http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Infinite_series描述

/** 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; 
}  
0

首先執行標準arctan(x)

在撥打arctan之前執行以下操作:

1)首先做這個檢查。

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

2)如果|x| > 1,計算arctan(1/x)最後從Pi/2

3)如果|x|靠近1減去結果,使用半角式 arctan(x) = 2*arctan(x/(1+sqrt(1+x*x)))計算反正切的半視角。也就是說,首先計算半角,然後將結果乘以2.否則,對於接近1的|x|,arctan收斂非常緩慢。