diff --git a/lib/built_ins.dart b/lib/built_ins.dart index b33fe51..1de4d4a 100644 --- a/lib/built_ins.dart +++ b/lib/built_ins.dart @@ -35,16 +35,20 @@ import 'abstract_operator.dart'; import 'abstract_unary_operator.dart'; import 'expression.dart'; -double _convertAngle(double angle,String currentAngleUnit,{ bool inverse = false}) { - switch(currentAngleUnit){ +double _convertAngle(double angle, String currentAngleUnit, + {bool inverse = false}) { + switch (currentAngleUnit) { case 'D': - return inverse?n.radianToDegree(angle):n.degreeToRadian(angle); + return inverse ? n.radianToDegree(angle) : n.degreeToRadian(angle); case 'G': - return inverse?n.radianToGrad(angle):n.degreeToRadian(n.gradToDegree(angle)); + return inverse + ? n.radianToGrad(angle) + : n.degreeToRadian(n.gradToDegree(angle)); default: return angle; } -} +} + void addBuiltIns(Expression e) { e.addOperator(OperatorImpl("+", Expression.operatorPrecedenceAdditive, true, fEval: (v1, v2) { @@ -70,29 +74,31 @@ void addBuiltIns(Expression e) { return (v1 / v2).toDecimal(scaleOnInfinitePrecision: 16); })); - e.addOperator(OperatorImpl( - "mod", Expression.operatorPrecedenceMultiplicative, true, fEval: (v1, v2) { + e.addOperator( + OperatorImpl("mod", Expression.operatorPrecedenceMultiplicative, true, + fEval: (v1, v2) { return v1 % v2; })); e.addOperator(OperatorImpl( "%", Expression.operatorPrecedenceMultiplicative, true, fEval: (v1, v2) { - return Decimal.parse((v1.toDouble()/100*v2.toDouble()).toString()); + return Decimal.parse((v1.toDouble() / 100 * v2.toDouble()).toString()); })); e.addOperator(OperatorImpl("logbase", 50, true, fEval: (v1, v2) { - if(v1==Decimal.zero||v2==Decimal.zero){ + if (v1 == Decimal.zero || v2 == Decimal.zero) { throw const ExpressionException('Exponentiation invalid'); } - if(v2==Decimal.one){ + if (v2 == Decimal.one) { throw const ExpressionException('Cannot divide by 0.'); } - return Decimal.parse((math.log(v1.toDouble())/math.log(v2.toDouble())).toString()); - })); - e.addOperator(OperatorImpl( - "yroot", 35, true, fEval: (v1, v2) { - return Decimal.parse((math.pow(v1.toDouble(),1/v2.toDouble())).toString()); - })); + return Decimal.parse( + (math.log(v1.toDouble()) / math.log(v2.toDouble())).toString()); + })); + e.addOperator(OperatorImpl("yroot", 35, true, fEval: (v1, v2) { + return Decimal.parse( + (math.pow(v1.toDouble(), 1 / v2.toDouble())).toString()); + })); e.addOperator( OperatorImpl("^", e.powerOperatorPrecedence, false, fEval: (v1, v2) { @@ -151,7 +157,8 @@ void addBuiltIns(Expression e) { })); e.addOperator(OperatorImpl( - ">", Expression.operatorPrecedenceComparison, false, fEval: (v1, v2) { + ">", Expression.operatorPrecedenceComparison, false, + booleanOperator: true, fEval: (v1, v2) { return v1.compareTo(v2) > 0 ? Decimal.one : Decimal.zero; })); @@ -248,8 +255,7 @@ void addBuiltIns(Expression e) { })); e.addOperator(OperatorSuffixImpl("!", 61, false, fEval: (v) { - if (v.toDouble() > - 50) { + if (v.toDouble() > 50) { throw new ExpressionException("Operand must be <= 50"); } @@ -292,345 +298,352 @@ void addBuiltIns(Expression e) { e.addFunc(FunctionImpl("DMS", 1, booleanFunction: false, fEval: (params) { num n = num.parse(params.first.toString()); - if(n.toInt()==n) return Decimal.parse(n.toString()); + if (n.toInt() == n) return Decimal.parse(n.toString()); int degrees = n.floor(); double remainingMinutes = (n - degrees) * 60; int minutes = remainingMinutes.floor(); double seconds = (remainingMinutes - minutes) * 60; - return Decimal.parse((degrees + (minutes / 100) + (seconds / 10000)).toString()); + return Decimal.parse( + (degrees + (minutes / 100) + (seconds / 10000)).toString()); })); // TRIGONOMETRY FUNCTIONS - final Map)> trigonometry = { + final Map)> trigonometry = { // Standard, degrees 'COSD': (List params) { - final double ans = n.cos(_convertAngle(params.first.toDouble(),'D')); + final double ans = n.cos(_convertAngle(params.first.toDouble(), 'D')); return Decimal.parse(ans.toString()); }, 'SIND': (List params) { - final double ans = n.sin(_convertAngle(params.first.toDouble(),'D')); + final double ans = n.sin(_convertAngle(params.first.toDouble(), 'D')); return Decimal.parse(ans.toString()); }, 'TAND': (List params) { - final double ans = n.tan(_convertAngle(params.first.toDouble(),'D')); + final double ans = n.tan(_convertAngle(params.first.toDouble(), 'D')); return Decimal.parse(ans.toString()); }, 'SECD': (List params) { - final double ans = 1 / n.cos(_convertAngle(params.first.toDouble(),'D')); + final double ans = 1 / n.cos(_convertAngle(params.first.toDouble(), 'D')); return Decimal.parse(ans.toString()); }, 'CSCD': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.sin(_convertAngle(val,'D')); + final double ans = 1 / n.sin(_convertAngle(val, 'D')); return Decimal.parse(ans.toString()); }, - 'COTD': (List args){ + 'COTD': (List args) { final double val = args.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.tan(_convertAngle(val,'D')); + final double ans = 1 / n.tan(_convertAngle(val, 'D')); return Decimal.parse(ans.toString()); }, // Inverse arc functions, degrees - 'ACOSD': (List params){ + 'ACOSD': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.acos(val),'D',inverse:true); + final double ans = _convertAngle(n.acos(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASIND': (List params){ + 'ASIND': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.asin(val),'D',inverse:true); + final double ans = _convertAngle(n.asin(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, - 'ATAND': (List params){ + 'ATAND': (List params) { final double val = params.first.toDouble(); - final double ans = _convertAngle(n.atan(val),'D',inverse:true); + final double ans = _convertAngle(n.atan(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASECD': (List params){ + 'ASECD': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.asec(val),'D',inverse:true); + final double ans = _convertAngle(n.asec(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACSCD': (List params){ + 'ACSCD': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.acsc(val),'D',inverse:true); + final double ans = _convertAngle(n.acsc(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACOTD': (List params){ + 'ACOTD': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = _convertAngle(n.acot(val),'D',inverse:true); + final double ans = _convertAngle(n.acot(val), 'D', inverse: true); return Decimal.parse(ans.toString()); }, // Standard, radians 'COSR': (List params) { final double val = params.first.toDouble(); - final double ans = n.cos(_convertAngle(val,'R')); + final double ans = n.cos(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, 'SINR': (List args) { final double val = args.first.toDouble(); - final double ans = n.sin(_convertAngle(val,'R')); + final double ans = n.sin(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, 'TANR': (List args) { final double val = args.first.toDouble(); - final double ans = n.tan(_convertAngle(val,'R')); + final double ans = n.tan(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, 'SECR': (List args) { final double val = args.first.toDouble(); - final double ans = 1 / n.cos(_convertAngle(val,'R')); + final double ans = 1 / n.cos(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, 'CSCR': (List args) { final double val = args.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.sin(_convertAngle(val,'R')); + final double ans = 1 / n.sin(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, - 'COTR': (List args){ + 'COTR': (List args) { final double val = args.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.tan(_convertAngle(val,'R')); + final double ans = 1 / n.tan(_convertAngle(val, 'R')); return Decimal.parse(ans.toString()); }, // Inverse arc functions, radians - 'ACOSR': (List params){ + 'ACOSR': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.acos(val),'R',inverse:true); + final double ans = _convertAngle(n.acos(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASINR': (List params){ + 'ASINR': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.asin(val),'R',inverse:true); + final double ans = _convertAngle(n.asin(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, - 'ATANR': (List params){ + 'ATANR': (List params) { final double val = params.first.toDouble(); - final double ans = _convertAngle(n.atan(val),'R',inverse:true); + final double ans = _convertAngle(n.atan(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASECR': (List params){ + 'ASECR': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.asec(val),'R',inverse:true); + final double ans = _convertAngle(n.asec(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACSCR': (List params){ + 'ACSCR': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.acsc(val),'R',inverse:true); + final double ans = _convertAngle(n.acsc(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACOTR': (List params){ + 'ACOTR': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = _convertAngle(n.acot(val),'R',inverse:true); + final double ans = _convertAngle(n.acot(val), 'R', inverse: true); return Decimal.parse(ans.toString()); }, // Standard, gradians 'COSG': (List params) { final double val = params.first.toDouble(); - final double ans = n.cos(_convertAngle(val,'G')); + final double ans = n.cos(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, 'SING': (List params) { final double val = params.first.toDouble(); - final double ans = n.sin(_convertAngle(val,'G')); + final double ans = n.sin(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, 'TANG': (List params) { final double val = params.first.toDouble(); - final double ans = n.tan(_convertAngle(val,'G')); + final double ans = n.tan(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, 'SECG': (List params) { final double val = params.first.toDouble(); - final double ans = 1 / n.cos(_convertAngle(val,'G')); + final double ans = 1 / n.cos(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, 'CSCG': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.sin(_convertAngle(val,'G')); + final double ans = 1 / n.sin(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, - 'COTG': (List params){ + 'COTG': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = 1 / n.tan(_convertAngle(val,'G')); + final double ans = 1 / n.tan(_convertAngle(val, 'G')); return Decimal.parse(ans.toString()); }, // Inverse arc functions, gradians - 'ACOSG': (List params){ + 'ACOSG': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.acos(val),'G',inverse:true); + final double ans = _convertAngle(n.acos(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASING': (List params){ + 'ASING': (List params) { final double val = params.first.toDouble(); - if(val<-1){ + if (val < -1) { throw const ExpressionException("Number must not be smaller than -1."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } - final double ans = _convertAngle(n.asin(val),'G',inverse:true); + final double ans = _convertAngle(n.asin(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, - 'ATANG': (List params){ + 'ATANG': (List params) { final double val = params.first.toDouble(); - final double ans = _convertAngle(n.atan(val),'G',inverse:true); + final double ans = _convertAngle(n.atan(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, - 'ASECG': (List params){ + 'ASECG': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.asec(val),'G',inverse:true); + final double ans = _convertAngle(n.asec(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACSCG': (List params){ + 'ACSCG': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val>0&&val<1){ - throw const ExpressionException("Number must be smaller than 0 and >=1"); + if (val > 0 && val < 1) { + throw const ExpressionException( + "Number must be smaller than 0 and >=1"); } - final double ans = _convertAngle(n.acsc(val),'G',inverse:true); + final double ans = _convertAngle(n.acsc(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, - 'ACOTG': (List params){ + 'ACOTG': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - final double ans = _convertAngle(n.acot(val),'G',inverse:true); + final double ans = _convertAngle(n.acot(val), 'G', inverse: true); return Decimal.parse(ans.toString()); }, // Hyperbolic - 'SINH': (List params){ + 'SINH': (List params) { final double val = params.first.toDouble(); return Decimal.parse(n.sinh(val).toString()); }, - 'COSH': (List params){ + 'COSH': (List params) { final double val = params.first.toDouble(); return Decimal.parse(n.cosh(val).toString()); }, - 'TANH': (List params){ + 'TANH': (List params) { final double val = params.first.toDouble(); return Decimal.parse(n.tanh(val).toString()); }, @@ -640,88 +653,89 @@ void addBuiltIns(Expression e) { return Decimal.parse(n.sech(val).toString()); }, - 'CSCH': (List params){ + 'CSCH': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } return Decimal.parse(n.csch(val).toString()); }, - 'COTH': (List params){ + 'COTH': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } return Decimal.parse(n.coth(val).toString()); }, // Inverse arc functions, hyperbolic - 'ASINH': (List params){ + 'ASINH': (List params) { final double val = params.first.toDouble(); return Decimal.parse(n.asinh(val).toString()); }, - 'ACOSH': (List params){ + 'ACOSH': (List params) { final double val = params.first.toDouble(); - if(val<1){ + if (val < 1) { throw const ExpressionException('Number must not be smaller than 1.'); } return Decimal.parse(n.acosh(val).toString()); }, - 'ATANH': (List params){ + 'ATANH': (List params) { final double val = params.first.toDouble(); - if(val==1){ + if (val == 1) { throw const ExpressionException("Number must not be 1."); } - if(val<0){ + if (val < 0) { throw const ExpressionException("Number must not be smaller than 0."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } return Decimal.parse(n.atanh(val).toString()); }, - 'ASECH': (List params){ + 'ASECH': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val<0){ + if (val < 0) { throw const ExpressionException("Number must not be smaller than 0."); } - if(val>1){ + if (val > 1) { throw const ExpressionException("Number must not be greater than 1."); } return Decimal.parse(n.asech(val).toString()); }, - 'ACSCH': (List params){ + 'ACSCH': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } return Decimal.parse(n.acsch(val).toString()); }, - 'ACOTH': (List params){ + 'ACOTH': (List params) { final double val = params.first.toDouble(); - if(val==0){ + if (val == 0) { throw const ExpressionException("Number must not be 0."); } - if(val==1){ + if (val == 1) { throw const ExpressionException("Number must not be 1."); } - if(val<1){ + if (val < 1) { throw const ExpressionException("Number must not be smaller than 1."); } return Decimal.parse(n.acoth(val).toString()); }, }; e.addFunc(FunctionImpl("ATAN2D", 2, fEval: (params) { - double ans = n.radianToDegree(math.atan2(params[0].toDouble(), params[1].toDouble())); + double ans = n + .radianToDegree(math.atan2(params[0].toDouble(), params[1].toDouble())); return Decimal.parse(ans.toString()); })); e.addFunc(FunctionImpl("ATAN2R", 2, fEval: (params) { @@ -729,20 +743,16 @@ void addBuiltIns(Expression e) { return Decimal.parse(ans.toString()); })); e.addFunc(FunctionImpl("ATAN2G", 2, fEval: (params) { - double ans = n.radianToGrad(math.atan2(params[0].toDouble(), params[1].toDouble())); + double ans = + n.radianToGrad(math.atan2(params[0].toDouble(), params[1].toDouble())); return Decimal.parse(ans.toString()); })); - for(String funcName in trigonometry.keys){ - e.addFunc( - FunctionImpl( - funcName, 1, - booleanFunction: false, - fEval: trigonometry[funcName]! - ) - ); + for (String funcName in trigonometry.keys) { + e.addFunc(FunctionImpl(funcName, 1, + booleanFunction: false, fEval: trigonometry[funcName]!)); } // Adding all the trigonometric functions - + // Conversions e.addFunc(FunctionImpl("RAD", 1, fEval: (params) { double convertedValue = n.degreeToRadian(params.first.toDouble()); @@ -815,15 +825,14 @@ void addBuiltIns(Expression e) { e.addFunc(FunctionImpl("SQRT", 1, fEval: (params) { return Decimal.parse(math.sqrt(params.first.toDouble()).toString()); })); - + e.addFunc(FunctionImpl("CUBEROOT", 1, fEval: (params) { final double n = params.first.toDouble(); - if(n<0) { + if (n < 0) { throw const ExpressionException('Number must not be smaller than 0.'); } - return Decimal.parse((math.pow(n,1/3)).toString()); - } - )); + return Decimal.parse((math.pow(n, 1 / 3)).toString()); + })); e.variables["theAnswerToLifeTheUniverseAndEverything"] = e.createLazyNumber(Decimal.fromInt(42)); diff --git a/pubspec.lock b/pubspec.lock index 5e92226..c122866 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: dart_internal - sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567" + sha256: "781e0d03812e5b52fdc3f71540b178245021be64d22cbc88da2aee6b45705183" url: "https://pub.dev" source: hosted - version: "0.2.9" + version: "0.2.13" dart_numerics: dependency: "direct main" description: @@ -402,4 +402,4 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.0.0 <3.3.0" + dart: ">=3.0.0 <3.7.0"