Eval функция в C, что приводит к отрицательному - PullRequest
0 голосов
/ 07 ноября 2019

Я использую Java 11, Eclipse IDE. Я разрабатываю программу, которая требует некоторых вычислений, я пишу эту программу на Java, поэтому я пытался найти что-то похожее на функцию с именем "eval ()", которая оценивает уравнение. Итак, я реализовал эту функцию в C и превратил ее в файл «.dll» и использовал ее в java.

Моя главная проблема заключается в том, когда я передаю уравнение в функцию eval, и оно возвращает двойное число, котороеявляется отрицательным и очень большим, как: я передал его "1.0 + 0.5 ^ 2", и он привел "-9.255963134931783E61", невозможно получить такой результат!

ПРИМЕЧАНИЕ: он всегдавернул правильный результат, но при последнем фрагменте выполнения он вернул вышеописанное! Почему? Как? Я использую ту же функцию eval.

Я покажу вам только важные части, а остальные оставлю, что не важно:

Все коды:

eval.c:

int evaluate(char* line, double* val);
static int do_op(void);
static int do_paren(void);
static void push_op(char op);
static void push_arg(double arg);
static STATUS pop_arg(double* arg);
static STATUS pop_op(int* op);
static char* getexp(char* str);
static char* getop(char* str);
static char* getop(char* str);
JNIEXPORT jdouble JNICALL Java_application_Main_eval
(JNIEnv* env, jobject object, jstring str) {
    const char* strs = env->GetStringUTFChars(str, false);
    char* equation = const_cast<char*>(strs);
    double result;
    evaluate(equation, &result);
    printf("the result is : %f", result);
    jdouble* returnResult = new jdouble(result);
    return *returnResult;
}

Собственный метод eval в java:

static {
    System.load(System.getProperty("user.dir")+"\\eval.dll");
}
public native double eval(String equation);

метод java, который привел к чему-то странному в конце:

String evaluateEquation(String e) {
        // we will truncate the brackets into pieces and eval every piece, 
        // and then return it without brackets by replacing it inside the equation!
        StringBuilder equation = new StringBuilder(e);
        int count = countBrackets(equation);
        int[] pos;
        String part;
        String result;
        // TODO : fix here : 
        BigDecimal tempResult = new BigDecimal(0);
        while (count!=0) { // every one loop, it will truncate, evaluate, replace the new value!
            pos = lastBrackets(equation.toString());
            part = equation.substring(pos[0], pos[1]+1);
            System.out.println("evaluating this part : "+part);
            tempResult = new BigDecimal(new Main().eval(part));
            System.out.println(tempResult.toString());
            result = truncateDecimals(tempResult);
            equation.replace(pos[0], pos[1]+1, result);
            System.out.println(equation.toString());
            count--;
        }
        System.out.println(equation.substring(0, equation.length()));
        part = equation.substring(0, equation.length()-1);
        finalResult = new BigDecimal(new Main().eval(part));
        System.out.println("FinalResult is : "+truncateDecimals(finalResult));
        return truncateDecimals(finalResult);
    }

Если вы прочиталиВ программе «eval.c» вы заметите, что она принимает «char *» и «double &». Я позаботился об этих конверсиях и думаю, что они связаны с этой ошибкой. Метод всегда возвращает правильный результат, за исключением одного места, которое находится в конце метода «defineEquation».

Насколько я знаю, любое число, хранящееся в памяти компьютера, становится отрицательным ТОЛЬКО при измененииэто к отрицательному ИЛИ это распространяется на его максимальное количество для хранения. если число превысит свой предел, оно превратится в отрицательное. Однако я кое-что заметил, что отрицательное число повторяется снова и снова, каждый раз, когда я вызываю функцию eval в конце функции «defineEquation», я получаю один и тот же результат: «-9.255963134931783E61». Если у вас есть предположения, объяснения или что-нибудь. Пожалуйста, не стесняйтесь говорить. Я никогда не буду опускать голоса тех, кто пытается мне помочь.

ПРИМЕЧАНИЕ: это оригинальный код C, который я использовал для создания файла dll: http://stjarnhimlen.se/snippets/eval.c

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Число -9.255963134931783E61 имеет внутреннее представление 0xCCCCCCCCCCCCCCCC, что настоятельно свидетельствует о том, что это неинициализированное значение.

Поскольку вы не проверяете возвращаемое значение из evaluate, это говорит о том, что оновозвращает условие ошибки, потому что в этом случае evaluate не устанавливает значение, на которое указывает его второй аргумент.

0 голосов
/ 09 ноября 2019

Я заметил, что в коде чего-то не хватает. Я пересмотрел его и вспомнил, что файл dll загружается только один раз при запуске программы, поэтому все переменные удаляются или очищаются. Это привело к тому, что возвращаемое значение было нечетным и повторялось непрерывно после заполнения используемых массивов. Итак, я создал функцию для очистки:

void clear() {
    for (int i = 0; i!=256 ; i++) {
        op_stack[i] = NULL;
        arg_stack[i] = NULL;
        token[i] = NULL;
    }
    op_sptr = 0;
    arg_sptr = 0;
    parens = 0;
    state = 0;
}
...