web-dev-qa-db-ja.com

2つのNSNumberオブジェクトを追加する方法は?

これは簡単なはずですが、どのようにして2つのNSNumberを合計できますか?のようなものです:

[one floatValue] + [two floatValue]

またはより良い方法がありますか?

77
mamcx

本当に良い方法はありませんが、回避できるのであれば、これを行うべきではありません。 NSNumberはスカラー番号のラッパーとして存在するため、それらをコレクションに格納し、他のNSObjectsとともに多態的に渡すことができます。実際の数学で数値を保存するために実際には使用されません。それらに対して数学を行う場合、スカラーだけで演算を実行するよりもはるかに遅いため、おそらく便利なメソッドはありません。

例えば:

NSNumber *sum = [NSNumber numberWithFloat:([one floatValue] + [two floatValue])];

メッセージのディスパッチで最低21命令で処理されますが、1命令相当の計算を行うために、メソッドがボックスを解除し、値(おそらく数百)を再ボックス化するために必要なコードが多くなります。

したがって、dictに数値を格納する必要がある場合はNSNumberを使用し、数値または文字列である可能性のある何かを関数に渡す必要がある場合はNSNumberを使用しますが、スカラーC型の数学スティック。

142
Louis Gerbarg

NSDecimalNumberNSNumber のサブクラス)には、探しているすべてのグッズがあります。

– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:

...

計算パフォーマンスに関心がある場合は、C++配列std :: vectorなどに変換します。

今ではもうC-Arrayを使用しません。間違ったインデックスまたはポインターを使用してクラッシュするのは簡単です。そして、すべての新しい[]とdelete []をペアにするのは非常に面倒です。

48
Semmel

使用できます

NSNumber *sum = @([first integerValue] + [second integerValue]);

編集:ohhoで見られるように、この例は整数値を保持する2つのNSNumberインスタンスを追加するためのものです。浮動小数点値を保持する2つのNSNumberを加算する場合は、次を実行する必要があります。

NSNumber *sum = @([first floatValue] + [second floatValue]);
12
nemesis

現在の トップ投票の回答 は、診断が困難なバグと、floatの使用による精度の低下につながります。 NSNumber値で数値演算を行う場合は、最初にNSDecimalNumberに変換し、代わりにそれらのオブジェクトで演算を実行する必要があります。

ドキュメント から:

NSNumberの不変のサブクラスであるNSDecimalNumberは、10進数の算術演算を行うためのオブジェクト指向のラッパーを提供します。インスタンスは、仮数が最大38桁の10進整数であり、指数が-128〜127の整数である仮数x 10 ^ exponentとして表現できる任意の数値を表すことができます。

したがって、[NSNumber decimalValue]を使用してNSNumberインスタンスをNSDecimalNumbersに変換し、必要な演算を実行し、完了したらNSNumberに割り当て直す必要があります。

Objective-Cの場合:

NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithDecimal:one.decimalValue]
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithDecimal:two.decimalValue]
NSNumber *result = [a decimalNumberByAdding:b]

In Swift 3:

let a = NSDecimalNumber(decimal: one.decimalValue)
let b = NSDecimalNumber(decimal: two.decimalValue)
let result: NSNumber = a.adding(b)
4
Dan Loewenherz

NSxEpressionを使用しないのはなぜですか?

NSNumber *x = @(4.5), *y = @(-2);

NSExpression *ex = [NSExpression expressionWithFormat:@"(%@ + %@)", x, y];
NSNumber *result = [ex expressionValueWithObject:nil context:nil];

NSLog(@"%@",result); // will print out "2.5"

次のように、異なる引数で評価するために再利用できるNSExpressionを構築することもできます。

NSExpression *expr = [NSExpression expressionWithFormat: @"(X+Y)"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", y, @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);

たとえば、毎回異なる「Y」値を使用して、同じ解析式を評価するループを作成できます。

 for (float f=20; f<30; f+=2.0) {
    NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", @(f), @"Y", nil];
    NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
 }
0
Motti Shneor

Swiftでは、Bolt_Swiftライブラリを使用してこの機能を取得できます https://github.com/williamFalcon/Bolt_Swift

例:

  var num1 = NSNumber(integer: 20)
  var num2 = NSNumber(integer: 25)
  print(num1+num2) //prints 45
0
William Falcon