I am using java 11, Eclipse IDE. I am designing a program that needs some calculations, I am writing that program in java, so I was trying to find something similar to a function called "eval()", which evaluates an equation. So, I implemented that function in C and turned it into a ".dll" file and used it inside java.
My main problem is when I pass the equation into the eval function, and it returns a double which is negative and very huge, like : I passed it "1.0+0.5^2", and it resulted "-9.255963134931783E61", it is impossible to get to a result like that!
NOTE : it has always returned the right result, but at the last piece of execution, it has returned the above! Why? How? I am using the same eval function.
I will only show you the important parts and leave the rest, which is not important :
All codes :
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;
}
The native eval method in java :
static {
System.load(System.getProperty("user.dir")+"\\eval.dll");
}
public native double eval(String equation);
the java method that resulted something odd at the end :
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);
}
If you have read the "eval.c" program, you will notice that it takes a "char*" and a "double&". I have taken care of these conversions and I think they have a relation with this bug. The method always returns the right result, except at one place, which is at the end of the "evaluateEquation" method.
Based on my knowledge, any number stored inside the computer memory gets to negative ONLY when we change it to a negative OR it extends on its maximum number to store. if the number breaks its limit, it will turn into a negative. However, I noticed something, the number that is negative is being repeated again and again every time I call the eval function in the end of the "evaluateEquation" function I get the same result, which is : "-9.255963134931783E61". If you have any assumptions, explanation or anything. Please, feel free to talk. I will never down-vote anyone who is trying to help me.
NOTE : this is the original C code that I used to make the dll file : http://stjarnhimlen.se/snippets/eval.c
I have noticed that the code is missing something. I revised it, and I remembered that a dll file is only loaded once when the program starts, so all the variables are being deleted or cleaned up. That caused the returned value to be odd and repeated continuously after the used arrays are full. So, I created a function to clear :
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;
}