/**
   * Returns the double value of this operator node operating on its operands.
   *
   * @param parametersValue the value of parameters passed to compute a compiled function.
   * @return the value of this operator.
   */
  public double computeExpression(double[] parametersValue) {
    double number1 = firstOperand.computeExpression(parametersValue);
    double number2 = secondOperand.computeExpression(parametersValue);
    Object binaryOperatorKey = getKey();

    if (binaryOperatorKey.equals(Syntax.OPERATOR_ADD)) return number1 + number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_SUBSTRACT)) return number1 - number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_MULTIPLY)) return number1 * number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_DIVIDE)) return number1 / number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_POWER)) return Math.pow(number1, number2);
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_MODULO)) {
      double modulo = number1 - number2 * (int) (number1 / number2);
      // If dividend and divisor are not of the same sign, add divisor
      if (number1 < 0 && number2 > 0 || number1 > 0 && number2 < 0) modulo += number2;
      return modulo;
    } else if (binaryOperatorKey.equals(Syntax.OPERATOR_REMAINDER)) return number1 % number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_EQUAL))
      return number1 == number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_DIFFERENT))
      return number1 != number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_GREATER_OR_EQUAL))
      return number1 >= number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_LESS_OR_EQUAL))
      return number1 <= number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_GREATER))
      return number1 > number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_LESS))
      return number1 < number2 ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_LOGICAL_OR))
      return number1 != FALSE_DOUBLE || number2 != FALSE_DOUBLE ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_LOGICAL_AND))
      return number1 != FALSE_DOUBLE && number2 != FALSE_DOUBLE ? TRUE_DOUBLE : FALSE_DOUBLE;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_LOGICAL_XOR))
      return number1 != FALSE_DOUBLE && number2 == FALSE_DOUBLE
              || number1 == FALSE_DOUBLE && number2 != FALSE_DOUBLE
          ? TRUE_DOUBLE
          : FALSE_DOUBLE;
    else if (Math.floor(number1) != number1)
      throw new IllegalArgumentException("Operand " + number1 + " of bit operator not an integer");
    else if (Math.floor(number2) != number2)
      throw new IllegalArgumentException("Operand " + number2 + " of bit operator not an integer");
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_BITWISE_OR))
      return (long) number1 | (long) number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_BITWISE_XOR))
      return (long) number1 ^ (long) number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_BITWISE_AND))
      return (long) number1 & (long) number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_SHIFT_LEFT))
      return (long) number1 << (long) number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_SHIFT_RIGHT))
      return (long) number1 >> (long) number2;
    else if (binaryOperatorKey.equals(Syntax.OPERATOR_SHIFT_RIGHT_0))
      return (long) number1 >>> (long) number2;
    else
      // User binary operators must be implemented in an interpreter
      throw new IllegalArgumentException(
          "Binary operator key " + binaryOperatorKey + " not implemented");
  }
 /**
  * Returns the value returned by the <code>getBinaryOperatorValue ()</code> method of <code>
  * interpreter</code> with the key of this operator and the computed value of its operands as
  * parameters.
  *
  * @param interpreter runtime interpreter.
  * @param parametersValue the value of parameters passed to compute a compiled function.
  * @return the computed value of this operator. The type of the returned value depends on the
  *     implementation of the interpreter.
  * @see com.eteks.parser.Interpreter#getBinaryOperatorValue
  */
 public Object computeExpression(Interpreter interpreter, Object[] parametersValue) {
   Object operand1 = firstOperand.computeExpression(interpreter, parametersValue);
   Object operand2 = secondOperand.computeExpression(interpreter, parametersValue);
   return interpreter.getBinaryOperatorValue(getKey(), operand1, operand2);
 }