As I was building my first JavaFX project, I noticed that the calculator engine that I had built was a little off. With that being said, I went over my code for about an hour now, trying to figure out what is wrong and I couldn't find anything that connects to this strange bug in my program.
The calculator engine:
public static String BasicEval(String str, String function) {
int indexOfOperation = str.indexOf(function);
int downBoundary = indexOfOperation - 1;
int upBoundary = indexOfOperation + 1;
int closestUp = str.length(), closestDown = 0;
for (int index = 0; index < str.length(); index++) { // Searching for the closest white space (between vals.) to determine what are the two vals.
if (Math.abs(indexOfOperation - index) == 1) {
continue;
} else if ((str.charAt(index) == ' ') && ((indexOfOperation - index) > closestDown)) {
closestDown = index; //Finds the closest blank space in order to differentiate between elements.
} else if ((str.charAt(index) == ' ') && (Math.abs(indexOfOperation + index) < closestUp)) {
closestUp = index; //Finds the closest black space in order to differentiate between elements.
}
}
while (str.substring(upBoundary,closestUp).contains("X") || (str.substring(upBoundary,closestUp).contains("-") || (str.substring(upBoundary,closestUp).contains("+") || (str.substring(upBoundary,closestUp).contains("/") || (str.substring(upBoundary,closestUp).contains("^")))))) {
closestUp--;
}
double firstValue = Double.valueOf(str.substring((closestDown + 1), downBoundary));
double secondValue = Double.valueOf(str.substring(upBoundary + 1, (closestUp-1)));
double OperationResult;
switch (function) {
case "^" : OperationResult = Math.pow(firstValue,secondValue); break;
case "X" : OperationResult = (firstValue * secondValue); break;
case "/" : OperationResult = (firstValue / secondValue); break;
case "+" : OperationResult = (firstValue + secondValue); break;
case "-" : OperationResult = firstValue - secondValue; break;
default: OperationResult = -999.12349876; //ERROR
}
str = strSort(str,firstValue,secondValue,OperationResult);
return str;
}
A little bit about the engine: the engine itself supposes to evaluate math expressions inside strings, so for example an input would be: " 3 + 4 " and the answer would be: 7.0 as a double. The way I hoped to achive this was by deviding the str into 4 smaller sections by the spaces between the terms and operation sign. The problem is: the math gets all wierd as you use bigger numbers. The number -999.123... stands for an error in my program.
The engine works just fine for simple calculations that use low numbers, but as you start to use bigger numbers things get messy. Sometimes it also produces errors like: "empty string", which I don't understand why ..
For more info about the project or the engine please comment. -- Keep in mind that I'm looking for an answer that would apply to my algorithm, not to javaFX in general-- (though I'd love to learn new stuff) Thanks !!
Examples of how things aren't as they should be: enter image description here enter image description here
I'll post more pictures in the comments.
strSort Method
public static String strSort(String str, double firstValue, double secondValue, double result) {
//Method that sorts between which vals are ints and which ones are doubles. --> returns them in their current form.
int firstValueIndex = 0;
int secondValueIndex = 0;
if (!intOrDoubleTest(firstValue) && firstValue == secondValue){ // Special category : indexOf doesn't work since the two vals. are the same --> giving off the same index.
firstValueIndex = str.indexOf(Double.toString(firstValue));
secondValueIndex = str.indexOf(Double.toString(secondValue),firstValueIndex+1);
} else if (intOrDoubleTest(firstValue) && firstValue == secondValue) { // Special category : indexOf doesn't work since the two vals. are the same --> giving off the same index.
firstValueIndex = str.indexOf(Integer.toString(intValue(firstValue)));
secondValueIndex = str.indexOf(Integer.toString(intValue(secondValue)),firstValueIndex+1);
} else if (intOrDoubleTest(firstValue) && intOrDoubleTest(secondValue)) { // First, sorts out the two vals.
firstValueIndex = str.indexOf(Integer.toString(intValue(firstValue)));
secondValueIndex = str.indexOf(Integer.toString(intValue(secondValue)));
} else if (!intOrDoubleTest(firstValue) && intOrDoubleTest(secondValue)) {
firstValueIndex = str.indexOf(Double.toString(firstValue));
secondValueIndex = str.indexOf(Integer.toString(intValue(secondValue)));
} else if (intOrDoubleTest(firstValue) && !intOrDoubleTest(secondValue)) {
firstValueIndex = str.indexOf(Integer.toString(intValue(firstValue)));
secondValueIndex = str.indexOf(Double.toString(secondValue));
} else if (!intOrDoubleTest(firstValue) && !intOrDoubleTest(secondValue)) {
firstValueIndex = str.indexOf(Double.toString(firstValue));
secondValueIndex = str.indexOf(Double.toString(secondValue));
}
String strToReplace = str.substring(firstValueIndex, secondValueIndex); // Computing the range that need to be replaced.
if (intOrDoubleTest(result)) {
int intResult = intValue(result);
str = str.replace(strToReplace,Integer.toString(intResult));
} else if (!intOrDoubleTest(result)) {
str = str.replace(strToReplace,Double.toString(result));
}
return str;
}
public static boolean intOrDoubleTest(double value) {
return (value % 1 == 0); // True = val is Int, False = val is Double.
}