/// <summary> /// Calculate the square root of a float /// </summary> /// <param name="expr"> The float</param> /// <returns> The sqrt of the input float</returns> private static Variable sqrtFunction(Expression expr) { Variable v = expr.evaluate(); if (v is Integer) { int raw_int = v.getValue(); // ReSharper disable once RedundantCast float raw_float = (float)raw_int; v = new FloatVar(raw_float); } Debugging.assert(v is FloatVar); double real = (double)v.getValue(); float real_sqrt = (float)Math.Sqrt(real); return(new FloatVar(real_sqrt)); }
/// <summary> /// Applies an arithmetical or logical operation on two <see cref="Variable"/>s /// <para/>result = (variable1) op (variable2) /// </summary> /// <param name="v1"> var 1</param> /// <param name="v2"> var 2</param> /// <param name="op"> operator (e.g. '+', '-', '&')</param> /// <returns> result <see cref="Variable"/></returns> /// <exception cref="AquilaExceptions.InvalidTypeError"> Invalid type with this operator</exception> /// <exception cref="AquilaExceptions.SyntaxExceptions.SyntaxError"> Unknown operator char</exception> private static Variable applyOperator(Variable v1, Variable v2, char op) { int comparison; Debugging.print("applyOperator: ", v1.ToString(), " ", op, " ", v2.ToString(), " (", v1.getTypeString(), " ", op, " ", v2.getTypeString(), ")"); // Debugging.assert(v1.hasSameParent(v2)); // operations between same classes/subclasses if (!v1.hasSameParent(v2)) { if (v2.isConst()) { if (v2 is Integer) { Debugging.print("Converting int to float because of const status: ", v1.ToString()); Debugging.assert(v1 is FloatVar, new AquilaExceptions.InvalidTypeError($"The type \"{v1.getTypeString()}\" was not expected. \"{v1.getTypeString()}\" expected")); // if this is not a float, operation is not permitted ! v2 = new FloatVar((float)v2.getValue()); } } else { throw new AquilaExceptions.InvalidTypeError($"The type \"{v1.getTypeString()}\" was not expected"); } } switch (op) { // arithmetic case '+': if (v1 is NumericalValue) { return(((NumericalValue)v1).addition((NumericalValue)v2)); } else { throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\""); } case '-': if (v1 is NumericalValue) { return(((NumericalValue)v1).subtraction((NumericalValue)v2)); } else { throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\""); } case '/': if (v1 is NumericalValue) { return(((NumericalValue)v1).division((NumericalValue)v2)); } else { throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\""); } case '*': if (v1 is NumericalValue) { return(((NumericalValue)v1).mult((NumericalValue)v2)); } else { throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\""); } case '%': if (v1 is Integer) { return(((Integer)v1).modulo((Integer)v2)); } else { throw new AquilaExceptions.InvalidTypeError($"Invalid type \"{v1.getTypeString()}\" with operator \"{op}\""); } // logic case '<': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison == -1)); case '>': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison == 1)); case '{': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison != 1)); case '}': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison != -1)); case '~': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison == 0)); case ':': Debugging.assert(v1 is Integer || v1 is FloatVar); comparison = v1 is Integer ? ((Integer)v1).compare(v2 as Integer) : ((FloatVar)v1).compare(v2 as FloatVar); return(new BooleanVar(comparison != 0)); case '|': Debugging.assert(v1 is BooleanVar); return(((BooleanVar)v1).or((BooleanVar)v2)); case '^': Debugging.assert(v1 is BooleanVar); return(((BooleanVar)v1).xor((BooleanVar)v2)); case '&': Debugging.assert(v1 is BooleanVar); return(((BooleanVar)v1).and((BooleanVar)v2)); default: throw new AquilaExceptions.SyntaxExceptions.SyntaxError("Unknown operand " + op); } }