我需要从我的 Blackberry Java 应用程序计算 arc tan 值。不幸的是,blackberry 4.2 api 没有 Math.atan() 函数。Blackberry JDE 的 4.6 版有它,但 4.2 版没有。
有谁知道计算atan的解决方法?
我需要从我的 Blackberry Java 应用程序计算 arc tan 值。不幸的是,blackberry 4.2 api 没有 Math.atan() 函数。Blackberry JDE 的 4.6 版有它,但 4.2 版没有。
有谁知道计算atan的解决方法?
来自Stephen Zimmerman 的 J2ME 中的 Arctan:
// 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;
}
}
当所有其他方法都失败时,人们可能会通过估计arctan
函数的无限系列的结果来获得一个不错的值。
关于反三角函数的Wikipedia 页面有一个关于无穷系列反三角函数的部分,包括arctan
. 为了获得估计,人们将执行无限级数,直到获得所需的精度。
至于为什么arctan
不包含该功能,可能是因为黑莓中的处理器不是很强大,并且会占用大量的处理器资源来执行计算。
此外,查看 Blackberry JDE 4.2 API 文档,似乎有一个名为的定点数学库Fixed32
,它提供了两种风格的 arctan。它们使用 32 位整数执行计算,因此与执行浮点运算相比,它们可能提供一些性能优势。
我遇到了同样的问题...缺少的数学函数可以在以下包中找到:
这是我使用的功能(不保证它非常快):
/** 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)
使用泰勒级数实现标准(如http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Infinite_series所述)
在调用 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。否则,对于|x|
接近 1,arctan 收敛非常缓慢。