Android - Проблема в результатах тригонометрических c функций на этом методе вычисления математического выражения - PullRequest
1 голос
/ 20 июня 2020

{ ссылка }

В этом посте метод вычисления математического выражения предоставлен @ Bruce.

Я также вставляю здесь код:

public static double eval(final String str) {
return new Object() {
    int pos = -1, ch;

    void nextChar() {
        ch = (++pos < str.length()) ? str.charAt(pos) : -1;
    }

    boolean eat(int charToEat) {
        while (ch == ' ') nextChar();
        if (ch == charToEat) {
            nextChar();
            return true;
        }
        return false;
    }

    double parse() {
        nextChar();
        double x = parseExpression();
        if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
        return x;
    }

    // Grammar:
    // expression = term | expression `+` term | expression `-` term
    // term = factor | term `*` factor | term `/` factor
    // factor = `+` factor | `-` factor | `(` expression `)`
    //        | number | functionName factor | factor `^` factor

    double parseExpression() {
        double x = parseTerm();
        for (;;) {
            if      (eat('+')) x += parseTerm(); // addition
            else if (eat('-')) x -= parseTerm(); // subtraction
            else return x;
        }
    }

    double parseTerm() {
        double x = parseFactor();
        for (;;) {
            if      (eat('*')) x *= parseFactor(); // multiplication
            else if (eat('/')) x /= parseFactor(); // division
            else return x;
        }
    }

    double parseFactor() {
        if (eat('+')) return parseFactor(); // unary plus
        if (eat('-')) return -parseFactor(); // unary minus

        double x;
        int startPos = this.pos;
        if (eat('(')) { // parentheses
            x = parseExpression();
            eat(')');
        } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
            while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
            x = Double.parseDouble(str.substring(startPos, this.pos));
        } else if (ch >= 'a' && ch <= 'z') { // functions
            while (ch >= 'a' && ch <= 'z') nextChar();
            String func = str.substring(startPos, this.pos);
            x = parseFactor();
            if (func.equals("sqrt")) x = Math.sqrt(x);
            else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
            else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
            else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
            else throw new RuntimeException("Unknown function: " + func);
        } else {
            throw new RuntimeException("Unexpected: " + (char)ch);
        }

        if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation

        return x;
    }
}.parse();
}

Здесь, когда я, например, пытаюсь оценить sin (30), он дает результат как 0,49999999999994. Также проблема с другими функциями тригонометрии c. Например, результат tan (45) будет 0,99999999999. В чем проблема?

Еще одна проблема, в Java математической библиотеке есть функция atan (), но не функция acot ().

Любая помощь будет принята с благодарностью ..

Ответы [ 2 ]

0 голосов
/ 21 июня 2020

Нет проблем с вашим кодом. Работает нормально. Точные результаты тригонометрии c не могут быть рассчитаны, поэтому вы получите близкий результат. А теперь перейдем ко второму вопросу. В библиотеке присутствуют функции, относящиеся к sin , cos и tan . Coses , se c и cot можно рассчитать, используя обратную формулу. Например, cot -1 (x) можно рассчитать как tan -1 (1 / x). Может, поэтому и не удосужились создать для этого отдельный метод.

0 голосов
/ 21 июня 2020

Вы получаете эти результаты, потому что все тригонометрические c функции в Java ожидают параметры в радианах. Вы можете преобразовать углы в радианы по формуле:

double angle = ...;
double radians = angle * Math.PI / 180;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...