我想计算一个字符串,我正在这样做:

NSExpression *expression = [NSExpression expressionWithFormat:calculationString];
float result = [[expression expressionValueWithObject:nil context:nil] floatValue];
NSLog(@"%f", result);


问题是,当calculationstring为1/2时,结果为0。我试图将double和NSNumber以及float更改为%f和%@,但我始终只得到0。我必须更改什么?

同样重要的是,我在欧洲,所以我用逗号而不是点表示该值,但这并不重要,因为我正在用%f进行记录,并将其显示为点。仅供参考

最佳答案

NSExpression中键入与在C中非常相似:看起来像整数(没有小数点/逗号)的文字被视为整数,因此使用整数除法。 (在整数除法下,1/2为零。如果需要0.5,则需要浮点除法。)这种情况是在解析和计算表达式时发生的,因此尝试更改结果的类型或输出的格式没有任何意义。效果-这些事情发生在解析和评估之后。

如果calculationString完全在您的控制之下,则很容易确保在要进行浮点除法的任何地方使用浮点文字。 (也就是说,使用1.0/2而不是1/2。)否则,您需要对其进行更改,以使其能够正常工作-在这里,最好分解已解析的NSExpression并更改操作数,而不是对操作数进行调整串。



在“分解”位上进行后续编辑:已知内容具有高阶结构的内容中的字符串通常为problematic。使用NSExpression,您已经有了一个解析器(比简单的正则表达式更聪明)来为您分解字符串-实际上,这就是NSExpression的全部含义。

因此,如果您使用的是用户提供的字符串,请不要尝试通过更改字符串来更改表达式。让NSExpression对其进行解析,然后使用所得对象的属性将其分成其组成表达式。如果您的字符串只是“ 1/2”,则您的表达式包含两个arguments和一个函数"divide:by:"的数组-您可以将其替换为等效函数,其中一个参数明确为浮点值:

extension NSExpression {
    var floatifiedForDivisionIfNeeded: NSExpression {
        if function == "divide:by:", let args = arguments, let last = args.last,
          let firstValue = args.first?.constantValue as? NSNumber {
            let newFirst = NSExpression(forConstantValue: firstValue.doubleValue)
            return NSExpression(forFunction: function, arguments: [newFirst, last])
        } else {
            return self
        }
    }
}

关于objective-c - NSExpression 1/2,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14346056/

10-12 14:49