繁体   English   中英

eval function 在 C 导致负

[英]eval function in C resulting in negative

我正在使用 java 11、Eclipse IDE。 我正在设计一个需要一些计算的程序,我正在 java 中编写该程序,所以我试图找到类似于 function 的东西,称为“eval()”,它评估一个方程。 因此,我在 C 中实现了 function 并将其转换为“.dll”文件并在 java 中使用它。

我的主要问题是当我将方程传递给 eval function 时,它返回一个负数且非常大的双精度数,例如:我传递了它“1.0+0.5^2”,结果是“-9.255963134931783E61”,它是不可能得到这样的结果!

注意:它总是返回正确的结果,但在最后一次执行时,它返回了上面的结果? 为什么? 如何。 我正在使用相同的 eval 函数。

我只给你看重要的部分,留下不重要的rest:

所有代码:

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;
}

java 中的原生 eval 方法:

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&”。 我已经处理了这些转换,我认为它们与这个错误有关。 该方法总是返回正确的结果,除了在“evaluateEquation”方法末尾的一个地方。

据我所知,存储在计算机 memory 中的任何数字只有在我们将其更改为负数或它扩展到其要存储的最大数量时才会变为负数。 如果数字超过其限制,它将变成负数。 但是,我注意到了一些事情,每次我在“evaluateEquation”function 末尾调用 eval function 时,都会一次又一次地重复负数,我得到相同的结果,即:“-9.2539631.34931” 如果您有任何假设,解释或任何事情。 请随意谈谈。 我永远不会拒绝任何试图帮助我的人。

NOTE: this is the original C code that I used to make the dll file: http://stjarnhimlen.se/snippets/eval.c

数字-9.255963134931783E61具有内部表示0xCCCCCCCCCCCCCCCC ,这强烈表明它是一个未初始化的值。

由于您不检查evaluate的返回值,这表明它正在返回错误条件,因为在这种情况下, evaluate不会设置其第二个参数指向的值。

我注意到代码缺少一些东西。 我修改了一下,我记得一个dll文件只在程序启动时加载一次,所以所有的变量都在被删除或清理。 导致使用的 arrays 满后返回值为奇数并不断重复。 所以,我创建了一个 function 来清除:

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM