我需要從我的Blackberry Java應用程序計算arc tan值。不幸的是,黑莓4.2 api沒有Math.atan()函數。天知道爲什麼,但那是你的黑莓API。黑莓JDE的4.6版有它,但不是4.2。在Blackberry 4.2上調用atan函數JDE
有誰知道計算atan的解決方法嗎?
我需要從我的Blackberry Java應用程序計算arc tan值。不幸的是,黑莓4.2 api沒有Math.atan()函數。天知道爲什麼,但那是你的黑莓API。黑莓JDE的4.6版有它,但不是4.2。在Blackberry 4.2上調用atan函數JDE
有誰知道計算atan的解決方法嗎?
當所有其他都失敗時,通過估計arctan
函數的無限級數的結果,可能可以獲得相當不錯的值。
該Wikipedia page on inverse trigonometic functions有一個反三角函數的infinite series部分,包括arctan
。爲了獲得一個估計,人們將執行無限序列,直到獲得所需的精度。
至於爲什麼不包括arctan
函數的原因,可能是因爲黑莓中的處理器功能不是很強大,並且需要大量的處理器資源來執行計算。
此外,看着黑莓JDE 4.2 API文檔,似乎有一個定點數學庫叫Fixed32
它提供了兩種arctan。它們使用32位整數執行計算,因此它們可能比執行浮點算法具有一些性能優勢。
從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;
}
}
這裏是我使用(沒有保證,它是非常快的)功能:使用泰勒級數(截至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;
}
首先執行標準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收斂非常緩慢。
我有同樣的問題...丟失的數學函數可以在下面的包中找到:
出於純粹的好奇,爲什麼你需要ATAN()? – Calyth 2009-09-21 16:57:07
@Dave該函數不存在的原因是BlackBerry Java從J2ME開始,而不是從J2SE開始,這正是您期望在移動領域中所期望的。 J2ME仍然沒有Math.atan()的實現。 – Fostah 2009-09-21 17:02:45