C中的评估函数导致结果为负

我正在使用Java 11,eclipse IDE。 我正在设计一个需要一些计算的程序,我正在用Java编写该程序,因此我试图找到类似于一个名为“ eval()”的函数,该函数可以计算方程式。因此,我用C实现了该功能,并将其转换为“ .dll”文件,并在Java中使用了它。

我的主要问题是,当我将方程式传递给eval函数时,它返回一个负数且非常大的double,例如:我传递了“ 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;
}

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”方法末尾的一个地方。

根据我的了解,只有当我们将其更改为负数时,计算机内存中存储的任何数字才会变为负数,或者扩展到要存储的最大数。如果数字超出限制,它将变为负数。 但是,我发现,每次我在“ evaluateEquation”函数末尾调用eval函数时,都会一次又一次重复负数,我得到的结果是:“-9.255963134931783E61”。 如果您有任何假设,解释或其他任何内容。请随便聊。我永远不会拒绝任何试图帮助我的人。

注意:这是我用来制作dll文件的原始C代码:http://stjarnhimlen.se/snippets/eval.c

Kelvin520 回答:C中的评估函数导致结果为负

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

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

,

我注意到代码缺少某些内容。我对其进行了修改,并记得该程序启动时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;
}
本文链接:https://www.f2er.com/3147296.html

大家都在问