5
\$\begingroup\$

I have written a set of functions to compute basic mathematical operations for my own Java-based programming language. First I tokenize input from the source code file and store it in a String array. For the mathematics, I simply read through the array looking for an operator (+, -, /, *) and if I find one I call a operation function. The language needs to be able to automatically handle double/int mathematics without additional casting or indication so obviously this complicates the functions. However, my question is, are these functions really the simplest and most efficient way to do basic math operations?: (Note, I have 4 just like this, one for each basic operation, just copy/pasted the same code with minor changes. That feels repetitive. Isn't there a better way to do this also along with the shortening of each function?)

Example:

5.32 + 7 returns 12.32

My Number Parser:

NumReturn numberParser(int cIndex) { 
                 NumReturn nri;
                  NumReturn nrd;
                 try {
                         nri = new NumReturn(Integer.parseInt(Lexer.token[cIndex]), cIndex++, 'i');
                         System.out.println(nri.value + " ");
                         return nri;
                 } catch (NumberFormatException intExcep) {
                 }
                 try {
                         nrd = new NumReturn(Double.parseDouble((Lexer.token[cIndex])), cIndex++, 'd');
                         System.out.println(nrd.dvalue + " ");
                         return nrd;
                 } catch (NumberFormatException doubExcep) {
                         // doubExcep.printStackTrace();
                 }
                 return null;
         }`

My addition function: (Could this somehow be shortened or be made more efficient?)

NumReturn add(int x) {
                if (numberParser(x) != null) {
            NumReturn a1 = numberParser(x);
            if (Lexer.token[x + 1].equals("+")) {
                if (numberParser(x + 2) != null) {
                    NumReturn a2 = numberParser(x + 2);
                    if (a1.type == 'd' && a2.type == 'd') {
                        System.out.println(a1.dvalue + a2.dvalue);
                        return new NumReturn(a1.dvalue + a2.dvalue, a2.pointerLocation, 'd');
                    } else if (a1.type == 'i' && a2.type == 'd') {
                        a1.dvalue = (double) a1.value;
                        System.out.println(a1.dvalue + a2.dvalue);
                        return new NumReturn((double) a1.value + a2.dvalue, a2.pointerLocation, 'd');
                    }

                    else if (a1.type == 'd' && a2.type == 'i') {
                        a2.dvalue = (double) a2.value;
                        System.out.println(a1.dvalue + a2.dvalue);
                        return new NumReturn(a1.dvalue + (double) a2.value, a2.pointerLocation, 'd');
                    }

                    else {
                        System.out.println(a1.value + a2.value);
                        return new NumReturn(a1.value + a2.value, a2.pointerLocation, 'i');
                    }

                }

                else if (Lexer.token[x + 2].equals("+")) {
                    System.out.println(a1.value + 1);
                    System.out.println(a1.dvalue + 1);
                    if (a1.type == 'i')
                        return new NumReturn(a1.value++,a1.pointerLocation + 3, 'i');
                    else
                        return new NumReturn(a1.dvalue++,a1.pointerLocation + 3, 'd');

                }
            }    
        }
        return null;

    }

NumReturn Class Type:

 package jsmash; 
 public class NumReturn {
         int value;
         double dvalue;
         int pointerLocation;
         char type;
         NumReturn(int value, int pointerLocation, char type) {
                 this.value = value;
                 this.pointerLocation = pointerLocation;
                 this.type = type;
         }
         NumReturn(double dvalue, int pointerLocation, char type) {
                 this.dvalue = dvalue;
                 this.pointerLocation = pointerLocation;
                 this.type = type;
         }

 }
\$\endgroup\$
1
\$\begingroup\$

Are your "Returned Numbers" somehow different in their meaning (semantically) than other numbers?

By making your calculation methods return a different type than they accept, you rob yourself the possibility to chain their calls: a.add(b).add(c)

You may not use this right now, but it might come in handy later when you are calculating complex things.

Why do you care if both, the first or the second numbers are doubles? There is no difference except a potentially useless cast of a double to a double. Invert the logic: Detect only the int-int-case as this is the only case not returning a double. All other calculations should cast both operands to double and go on.

\$\endgroup\$
  • \$\begingroup\$ + 1. Ok I get what you are saying here. Good idea. I suppose I could accept my own NumReturn class as the parameter for the function. The issue is unless you have another suggestion for me, I need the NumReturn class. Otherwise I can't handle int + double addition. (And other operations with mixed types.) \$\endgroup\$ – Ashwin Gupta Jan 10 '16 at 21:11
  • \$\begingroup\$ I suppose I could try inverting the logic, let me think about that for a while I'll get back to you. \$\endgroup\$ – Ashwin Gupta Jan 10 '16 at 21:13
  • \$\begingroup\$ there is an issue with the inverse logic method you sugested, the NumReturn class contains both double and int. Without checking which type its using, I have no idea which one is relevant. So, I need to use the if statements anyway to check which thing to cast. Back to square one unfourtunently :(. \$\endgroup\$ – Ashwin Gupta Jan 11 '16 at 2:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.