Java C中的eval函数导致负
我正在使用Java11,EclipseIDE。 我正在设计一个需要一些计算的程序,我正在用java编写这个程序,所以我试图找到一个类似于eval的函数,它计算一个等式。所以,我用C实现了这个函数,并将它转换成一个.dll文件,然后在java中使用它 我的主要问题是,当我把这个方程传递到求值函数中,它返回一个双精度,它是负数,非常大,比如:我把它传递了1.0+0.5^2,结果是-9.255963134931783E61,不可能得到这样的结果 注意:它总是返回正确的结果,但在最后一次执行时,它返回了上面的结果!为什么?怎样我使用的是相同的eval函数 我将只向您展示重要部分,其余部分则不重要: 所有代码: 评估c:Java C中的eval函数导致负,java,c,math,double,eval,Java,C,Math,Double,Eval,我正在使用Java11,EclipseIDE。 我正在设计一个需要一些计算的程序,我正在用java编写这个程序,所以我试图找到一个类似于eval的函数,它计算一个等式。所以,我用C实现了这个函数,并将它转换成一个.dll文件,然后在java中使用它 我的主要问题是,当我把这个方程传递到求值函数中,它返回一个双精度,它是负数,非常大,比如:我把它传递了1.0+0.5^2,结果是-9.255963134931783E61,不可能得到这样的结果 注意:它总是返回正确的结果,但在最后一次执行时,它返回了
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方法:
字符串求值表达式字符串e{
//我们将把括号切成几段,然后计算每一段,
//然后通过在方程式中替换它来返回它,不带括号!
StringBuilder公式=新StringBuildere;
int count=countbracketsequalation;
int[]pos;
弦部;
字符串结果;
//TODO:在此处修复:
BigDecimal tempResult=新的BigDecimal0;
当count!=0{//每一个循环时,它将截断、计算、替换新值!
pos=最后一个括号Sequalation.toString;
部分=方程式。子字符串pos[0],pos[1]+1;
System.out.println评估此部分:+part;
tempResult=new BigDecimalnew Main.evalpart;
System.out.printlntempResult.toString;
结果=截断CIMALSTEMPRESULT;
方程.replacepos[0],pos[1]+1,结果;
System.out.printlnequation.toString;
计数-;
}
System.out.printlnequation.substring0,等式.length;
部分=方程式.substring0,方程式.length-1;
finalResult=new BigDecimalnew Main.evalpart;
System.out.printlnFinalResult为:+truncateDecimalsfinalResult;
返回截断的CIMALFinalResult;
}
如果您读过eval.c程序,您会注意到它需要一个char*和一个double&。我已经处理了这些转换,我认为它们与这个bug有关。该方法始终返回正确的结果,但evaluateEquation方法末尾的一个位置除外
据我所知,存储在计算机内存中的任何数字只有在我们将其更改为负数或扩展到要存储的最大数字时才会变为负数。如果这个数字突破了它的极限,它将变成负数。
然而,我注意到,每次我在evaluateEquation函数末尾调用eval函数时,负数会被一次又一次地重复,得到相同的结果,即:-9.255963134931783E61。
如果你有任何假设、解释或任何东西。请随便说。我决不会投票反对任何试图帮助我的人
注意:这是我用来创建dll文件的原始C代码:数字-9.255963134931783E61具有内部表示0xCCCC,这强烈表明它是未初始化的值
由于没有检查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;
}
在转换为BigDecimal和调用TruncatedCIMALS之前,试着打印new Main.evalpart的值,看看最后两个步骤是否有问题。C代码中的printf打印的是什么数字?@DawoodsaysRestatemonica,我确信part变量没有问题,方程也没有问题,我检查了所有东西,只有eval方法的输出是错误的,太奇怪了,我想问题是来自引用?也许,也许StringBuilder正在返回一个字符串引用,其中默认添加了我不想要或不需要的内容?我真的不知道,也不确定。@ErwinBolwidt,它打印了与我从新的Main.evalequation方法中收到的相同的数字错误号。在这种情况下,因为它在C中已经有错误,这不是Java问题。问题在于你的C求值函数。您可以删除所有与Java相关的代码、信息和标记!从你的问题,张贴一个良好的C代码,并再次询问。