入力NSExpression
はCの場合とよく似ています。整数(小数点/コンマなし)のように見えるリテラルは整数として扱われるため、整数除算を使用します。(整数除算では、1/2はゼロです。0.5が必要な場合は、浮動小数点除算が必要です。)これは、式が解析および評価されるときに発生するため、結果のタイプまたは出力のフォーマットを変更しようとしても、効果-これらのことは、解析と評価の後に発生します。
が完全に制御されている場合calculationString
は、浮動小数点除算が必要な場所で浮動小数点リテラルを使用することを簡単に確認できます。(つまり、1.0/2
の代わりに使用し1/2
ます。)そうでない場合は、変更するように変更する必要があります。ここではNSExpression
、文字列を変更するよりも、解析を分解してオペランドを変更する方がよいでしょう。
「分解」ビットのフォローアップ編集:高次構造を持つことがわかっているコンテンツでの文字列の変更は、一般的に問題があります。そして、を使用するとNSExpression
、文字列を分解するパーサー(単純な正規表現よりも賢い)がすでにあります。これが実際のところNSExpression
です。
したがって、ユーザー提供の文字列を使用している場合は、文字列を変更して式を変更しようとしないでください。それNSExpression
を解析してから、結果のオブジェクトのプロパティを使用して、構成要素の式に分解します。文字列が単純に「1/2」の場合、式には2つの配列とarguments
関数"divide:by:"
があります。引数の1つが明示的に浮動小数点値である同等の関数に置き換えることができます。
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
}
}
}