Вызов функции atan в Blackberry 4.2 JDE

Мне нужно вычислить значение дуги в моем приложении Blackberry Java. К сожалению, API Blackberry 4.2 не имеет функции Math.atan(). Версия 4.6 Blackberry JDE имеет его, но не 4.2.

Кто-нибудь знает обходной путь для расчета atan?

5 ответов

От Арктана в J2ME Стивена Циммермана:

// 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 функция.

На странице Википедии об обратных тригонометрических функциях есть раздел, посвященный бесконечному ряду обратных тригонометрических функций, включая arctan, Чтобы получить оценку, нужно проводить бесконечные ряды, пока не будет достигнута желаемая точность.

Что касается причины, почему arctan функция не включена, вероятно, потому, что процессор в Blackberry не очень мощный, и потребует много ресурсов процессора для выполнения вычислений.

Кроме того, если посмотреть документацию по API Blackberry JDE 4.2, то, похоже, есть математическая библиотека с фиксированной точкой, которая называется Fixed32 который предлагает два вкуса арктана. Они выполняют вычисления с 32-разрядными целыми числами, поэтому они, вероятно, предлагают некоторые преимущества в производительности по сравнению с выполнением арифметики с плавающей точкой.

У меня была такая же проблема... недостающие математические функции можно найти в следующем пакете:

net.rim.device.api.util.MathUtilities

Вот функция, которую я использую (нет гарантий, что она очень быстрая):

/** 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)

Выполните следующее перед вызовом 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, арктан сходится очень медленно.

Другие вопросы по тегам