You might be better off using a third-party expression parser / evaluator, such as DDMathParser . NSExpression quite limited and does not have the ability to force point evaluation.
If you want (or should) stick with NSExpression : Here is a possible solution (recursively) to replace all the value constants in the expression with their floating point value:
extension NSExpression { func toFloatingPoint() -> NSExpression { switch expressionType { case .constantValue: if let value = constantValue as? NSNumber { return NSExpression(forConstantValue: NSNumber(value: value.doubleValue)) } case .function: let newArgs = arguments.map { $0.map { $0.toFloatingPoint() } } return NSExpression(forFunction: operand, selectorName: function, arguments: newArgs) case .conditional: return NSExpression(forConditional: predicate, trueExpression: self.true.toFloatingPoint(), falseExpression: self.false.toFloatingPoint()) case .unionSet: return NSExpression(forUnionSet: left.toFloatingPoint(), with: right.toFloatingPoint()) case .intersectSet: return NSExpression(forIntersectSet: left.toFloatingPoint(), with: right.toFloatingPoint()) case .minusSet: return NSExpression(forMinusSet: left.toFloatingPoint(), with: right.toFloatingPoint()) case .subquery: if let subQuery = collection as? NSExpression { return NSExpression(forSubquery: subQuery.toFloatingPoint(), usingIteratorVariable: variable, predicate: predicate) } case .aggregate: if let subExpressions = collection as? [NSExpression] { return NSExpression(forAggregate: subExpressions.map { $0.toFloatingPoint() }) } case .anyKey: fatalError("anyKey not yet implemented") case .block: fatalError("block not yet implemented") case .evaluatedObject, .variable, .keyPath: break
Example:
let expression = NSExpression(format: "10/6+3/4") if let result = expression.toFloatingPoint().expressionValue(with: nil, context: nil) as? Double { print("result:", result)
This works with "simple" expressions using arithmetic operators and functions and some "advanced" types of expressions (unions, intersections, ...). Other conversions can be added if necessary.
source share